5 - Transfer Learning

How do you solve your own image classification problem with small labelled dataset

Let us use a self-collected small food picture dataset and see if we can classify them?

Load Library

In [1]:
import numpy as np
import keras

import matplotlib.pyplot as plt
Using TensorFlow backend.
In [2]:
%matplotlib inline

Get the Data

In [3]:
# !wget http://bit.do/dosa-nodosa -O dosa.zip
In [4]:
# !unzip dosa.zip
In [5]:
from keras.preprocessing.image import load_img, img_to_array, array_to_img, ImageDataGenerator
In [6]:
img = load_img('food-binary/Dosa/img39.jpeg')
In [7]:
img_array = img_to_array(img)
img_array.shape
Out[7]:
(194, 259, 3)
In [8]:
plt.imshow(img_array/255.);

Load the Data (From File System)

We need to load the data from the file system

In [9]:
img_generator = ImageDataGenerator(validation_split=0.2, rescale=1.0/255)
In [10]:
def get_batches(path, subset, gen=img_generator, shuffle=True, batch_size=8, class_mode="categorical"):
    return gen.flow_from_directory(path, target_size=(228,228), class_mode=class_mode,
                                  shuffle=shuffle, batch_size=batch_size, subset=subset)
In [11]:
train_generator = get_batches('food-binary/', 'training')
val_generator = get_batches('food-binary/', 'validation')
Found 260 images belonging to 2 classes.
Found 65 images belonging to 2 classes.
In [12]:
train_generator.class_indices
Out[12]:
{'Dosa': 0, 'NoDosa': 1}

Build a Transfer Learning Model

In [13]:
from keras.applications import ResNet50
from keras.models import Sequential, Model
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dense, Dropout, Flatten, GlobalAveragePooling2D
In [14]:
base_model = ResNet50(include_top=False, input_shape=(228,228,3))
In [15]:
#base_model.summary()
In [16]:
# Write the model in a functional way
x = base_model.output
x = GlobalAveragePooling2D()(x)                #
x = Dense(128, activation="relu") (x)          # 
predictions = Dense(2, activation="softmax") (x)

m = Model(inputs=base_model.input, outputs=predictions)
In [17]:
#m.summary()
In [18]:
m.compile(loss="categorical_crossentropy", optimizer="sgd", metrics=["accuracy"])
In [ ]:
m.fit_generator(
    train_generator,
    steps_per_epoch = 2000,
    epochs=1,
    validation_data = val_generator,
    validation_steps=800
)
Epoch 1/1