<jupyter_start><jupyter_text>Below is code with a link to a happy or sad dataset which contains 80 images, 40 happy and 40 sad. Create a convolutional neural network that trains to 100% accuracy on these images,  which cancels training upon hitting training accuracy of >.999Hint -- it will work best with 3 convolutional layers.<jupyter_code>import tensorflow as tf
import os
import zipfile


DESIRED_ACCURACY = 0.999

!wget --no-check-certificate \
    "https://storage.googleapis.com/laurencemoroney-blog.appspot.com/happy-or-sad.zip" \
    -O "/tmp/happy-or-sad.zip"

zip_ref = zipfile.ZipFile("/tmp/happy-or-sad.zip", 'r')
zip_ref.extractall("/tmp/h-or-s")
zip_ref.close()

class myCallback(tf.keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs={}):
    if (logs.get('accuracy') > 0.999):
        print("\nReached 99.9% accuracy so cacelling training!\n")
        self.model.stop_training = True

my_callback = myCallback()
# This Code Block should Define and Compile the Model
model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(150, 150, 3)),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2, 2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(512, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

from tensorflow.keras.optimizers import RMSprop

model.compile(loss='binary_crossentropy', 
              optimizer=RMSprop(learning_rate=0.0001),
              metrics=['accuracy'])
model.summary()
# This code block should create an instance of an ImageDataGenerator called train_datagen 
# And a train_generator by calling train_datagen.flow_from_directory

from tensorflow.keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale=1/255.)

train_generator = train_datagen.flow_from_directory(
        '/tmp/h-or-s/',
        target_size=(150,150),
        batch_size=8,
        class_mode='binary')   # classes=['sad', 'happy']

# Expected output: 'Found 80 images belonging to 2 classes'
# This code block should call model.fit and train for
# a number of epochs. 
history = model.fit(
        train_generator,
        steps_per_epoch=5,
        epochs=15,
        verbose=1,
        callbacks=[my_callback])
    
# Expected output: "Reached 99.9% accuracy so cancelling training!""<jupyter_output>Epoch 1/15
5/5 [==============================] - 0s 19ms/step - loss: 0.7900 - accuracy: 0.5750
Epoch 2/15
5/5 [==============================] - 0s 20ms/step - loss: 0.4969 - accuracy: 0.8750
Epoch 3/15
5/5 [==============================] - 0s 20ms/step - loss: 0.4238 - accuracy: 0.8250
Epoch 4/15
5/5 [==============================] - 0s 18ms/step - loss: 0.3179 - accuracy: 0.9250
Epoch 5/15
5/5 [==============================] - 0s 18ms/step - loss: 0.2564 - accuracy: 0.9000
Epoch 6/15
5/5 [==============================] - 0s 18ms/step - loss: 0.2382 - accuracy: 0.9500
Epoch 7/15
5/5 [==============================] - 0s 18ms/step - loss: 0.2993 - accuracy: 0.8500
Epoch 8/15
5/5 [==============================] - 0s 19ms/step - loss: 0.1719 - accuracy: 0.9500
Epoch 9/15
5/5 [==============================] - 0s 18ms/step - loss: 0.1208 - accuracy: 0.9750
Epoch 10/15
5/5 [==============================] - 0s 19ms/step - loss: 0.1305 - accuracy: 0.9750
Epoch 11/15
4/5 [============[...]
{'fraction_non_alphanumeric': 0.2129524886877828, 'fraction_numerical': 0.07692307692307693, 'mean_word_length': 3.838577291381669, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 6, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '484410', 'license': 'MIT', 'n_tokens_mistral': 1397, 'n_tokens_neox': 1199, 'n_words': 292, 'path': 'Course 1/Week 4/Exercise 4-Question.ipynb', 'repo_name': 'rickiepark/tensorflow-in-practice', 'size': '3536'}