# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     name: python3
# ---

# + [markdown] colab_type="text" id="hRTa3Ee15WsJ"
# # Classifying an Image as Meme or Not Using Transfer Learning

# + [markdown] colab_type="text" id="2X4KyhORdSeO"
# We will try to classify meme vs normal images by using transfer learning from a pre-trained network. This will allows us to get higher accuracies than we saw by training our network from scratch.

# + colab_type="code" id="iBMcobPHdD8O" colab={}
from __future__ import absolute_import, division, print_function, unicode_literals

import os

import tensorflow as tf
from tensorflow import keras
print("TensorFlow version is ", tf.__version__)

import numpy as np

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

tf.enable_eager_execution()

# + [markdown] colab_type="text" id="v77rlkCKW0IJ"
# ## Dataset File Upload 

# + id="nptk8-Ji93kf" colab_type="code" colab={}
from google.colab import files
files.upload()

# + id="drMZitRtFMP9" colab_type="code" colab={}
zip_file = tf.keras.utils.get_file(origin="http://files.dgtlschl.com/MemeOrNot.zip",
                                   fname="MemeOrNot.zip")
zip_file

# + id="ry6AlzvXAnQR" colab_type="code" colab={}
import zipfile
with zipfile.ZipFile(zip_file, 'r') as zip_ref:
    zip_ref.extractall("/content/")

# + id="VUDIrktwA60_" colab_type="code" colab={}
base_dir="/content/MemeOrNot/"

# + [markdown] colab_type="text" id="9_6h-c5EXN91"
# ### Prepare training and validation meme or not dataset
# Create the training and validation directories for meme datasets and not meme datasets.

# + colab_type="code" id="RWcldM4TXLen" colab={}
train_dir = os.path.join(base_dir, 'train')
validation_dir = os.path.join(base_dir, 'validation')

# Directory with our training meme pictures
train_meme_dir = os.path.join(train_dir, 'meme')
print ('Total training meme images:', len(os.listdir(train_meme_dir)))

# Directory with our training not meme pictures
train_normal_dir = os.path.join(train_dir, 'normal')
print ('Total training normal images:', len(os.listdir(train_normal_dir)))

# Directory with our validation meme pictures
validation_meme_dir = os.path.join(validation_dir, 'meme')
print ('Total validation meme images:', len(os.listdir(validation_meme_dir)))

# Directory with our validation normal pictures
validation_normal_dir = os.path.join(validation_dir, 'normal')
print ('Total validation normal images:', len(os.listdir(validation_normal_dir)))

# + [markdown] colab_type="text" id="wvidPx6jeFzf"
# ### Create Image Data Generator with Image Augmentation
#
# We will use ImageDataGenerator to rescale the images.
#
# To create the train generator, specify where the train dataset directory, image size, batch size and binary classification mode.
#
# The validation generator is created the same way.

# + colab_type="code" id="y3PM6GVHcC31" colab={}
image_size = 160 # All images will be resized to 160x160
batch_size = 32

# Rescale all images by 1./255 and apply image augmentation
train_datagen = keras.preprocessing.image.ImageDataGenerator(
                rescale=1./255)

validation_datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1./255)

# Flow training images in batches of 20 using train_datagen generator
train_generator = train_datagen.flow_from_directory(
                train_dir,  # Source directory for the training images
                target_size=(image_size, image_size),
                batch_size=batch_size,
                # Since we use binary_crossentropy loss, we need binary labels
                class_mode='binary')

# Flow validation images in batches of 20 using test_datagen generator
validation_generator = validation_datagen.flow_from_directory(
                validation_dir, # Source directory for the validation images
                target_size=(image_size, image_size),
                batch_size=batch_size,
                class_mode='binary')

# + [markdown] colab_type="text" id="OkH-kazQecHB"
# ## Using the **MobileNet V2** base model from the pre-trained convnets
#

# + colab_type="code" id="19IQ2gqneqmS" colab={}
IMG_SHAPE = (image_size, image_size, 3)

# Create the base model from the pre-trained model MobileNet V2
base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
                                               include_top=False,
                                               weights='imagenet')

# + colab_type="code" id="OTCJH4bphOeo" colab={}
base_model.trainable = False

# + colab_type="code" id="KpbzSmPkDa-N" colab={}
# Let's take a look at the base model architecture
base_model.summary()

# + colab_type="code" id="eApvroIyn1K0" colab={}
model = tf.keras.Sequential([
  base_model,
  keras.layers.GlobalAveragePooling2D(),
  keras.layers.Dense(1, activation='sigmoid')
])

# + [markdown] colab_type="text" id="g0ylJXE_kRLi"
# ### Compile the model
#
# You must compile the model before training it.

# + colab_type="code" id="RpR8HdyMhukJ" colab={}
model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=0.0001),
              loss='binary_crossentropy',
              metrics=['accuracy'])

# + colab_type="code" id="I8ARiyMFsgbH" colab={}
model.summary()

# + [markdown] colab_type="text" id="lxOcmVr0ydFZ"
# These 1.2K trainable parameters are divided among 2 TensorFlow `Variable` objects, the weights and biases of the two dense layers:

# + colab_type="code" id="krvBumovycVA" colab={}
len(model.trainable_variables)

# + [markdown] colab_type="text" id="RxvgOYTDSWTx"
# ### Train the model
#
# Training the model for 10 epochs
#

# + colab_type="code" id="Om4O3EESkab1" colab={}
epochs = 10
steps_per_epoch = train_generator.n // batch_size
validation_steps = validation_generator.n // batch_size

history = model.fit_generator(train_generator,
                              steps_per_epoch = steps_per_epoch,
                              epochs=epochs,
                              workers=4,
                              validation_data=validation_generator,
                              validation_steps=validation_steps)

# + colab_type="code" id="53OTCh3jnbwV" colab={}
acc = history.history['acc']
val_acc = history.history['val_acc']

loss = history.history['loss']
val_loss = history.history['val_loss']

plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.ylabel('Accuracy')
plt.ylim([min(plt.ylim()),1])
plt.title('Training and Validation Accuracy')

plt.subplot(2, 1, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.ylabel('Cross Entropy')
plt.ylim([0,max(plt.ylim())])
plt.title('Training and Validation Loss')
plt.show()

# + [markdown] colab_type="text" id="4TU4kv3yINQ-"
# # Saving the model
# We will now save the model for later use.
#

# + colab_type="code" id="0wozBQvmINQ_" colab={}
tf.keras.models.save_model(
    model,
    "/content/meme_or_not.h5",
    overwrite=True,
    include_optimizer=True,
    save_format="h5"
)

# + [markdown] colab_type="text" id="CqwV-CRdS6Nv"
# ## Fine tuning
#
#

# + colab_type="code" id="4nzcagVitLQm" colab={}
base_model.trainable = True

# + colab_type="code" id="-4HgVAacRs5v" colab={}
# Let's take a look to see how many layers are in the base model
print("Number of layers in the base model: ", len(base_model.layers))

# Fine tune from this layer onwards
fine_tune_at = 100

# Freeze all the layers before the `fine_tune_at` layer
for layer in base_model.layers[:fine_tune_at]:
  layer.trainable =  False

# + colab_type="code" id="NtUnaz0WUDva" colab={}

model.compile(optimizer = tf.keras.optimizers.RMSprop(lr=2e-5),
              loss='binary_crossentropy',
              metrics=['accuracy'])

# + colab_type="code" id="WwBWy7J2kZvA" colab={}
model.summary()

# + colab_type="code" id="bNXelbMQtonr" colab={}
len(model.trainable_variables)

# + [markdown] colab_type="text" id="4G5O4jd6TuAG"
# ### Continue Train the model

# + [markdown] colab_type="text" id="0foWUN-yDLo_"
# If you trained to convergence earlier, this will get you a few percent more accuracy.

# + colab_type="code" id="ECQLkAsFTlun" colab={}
history_fine = model.fit_generator(train_generator,
                                   steps_per_epoch = steps_per_epoch,
                                   epochs=epochs,
                                   workers=4,
                                   validation_data=validation_generator,
                                   validation_steps=validation_steps)

# + colab_type="code" id="PpA8PlpQKygw" colab={}
acc = history.history['acc']
val_acc = history.history['val_acc']

loss = history.history['loss']
val_loss = history.history['val_loss']

acc += history_fine.history['acc']
val_acc += history_fine.history['val_acc']

loss += history_fine.history['loss']
val_loss += history_fine.history['val_loss']

# + colab_type="code" id="chW103JUItdk" colab={}
plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.ylim([0.9, 1])
plt.plot([epochs-1,epochs-1], plt.ylim(), label='Start Fine Tuning')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(2, 1, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.ylim([0, 0.2])
plt.plot([epochs-1,epochs-1], plt.ylim(), label='Start Fine Tuning')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

# + [markdown] colab_type="text" id="_TZTwG7nhm0C"
# # Saving the model
# We will now save the model for later use.
#

# + id="VkxcDivCw5-W" colab_type="code" colab={}
tf.keras.models.save_model(
    model,
    "/content/meme_or_not-finetuned.h5",
    overwrite=True,
    include_optimizer=True,
    save_format="h5"
)

# + id="ogfO3e4cGbkp" colab_type="code" colab={}
pip install tensorflowjs

# + id="k02bXn7zJGBn" colab_type="code" colab={}
import tensorflowjs as tfjs
tf.enable_eager_execution()

# + id="TaiVFL-lHfbe" colab_type="code" colab={}
tfjs.converters.save_keras_model(model,"/content/tfjs/")

# + id="3VmY4sa6JB0g" colab_type="code" colab={}


StarcoderdataJupyterScriptsDedupFiltered