In [2]:
import keras
from keras.preprocessing.image import load_img, img_to_array, array_to_img, ImageDataGenerator
from keras.models import Sequential, Model
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense, GlobalAveragePooling2D
from keras.applications import ResNet50
In [6]:
import matplotlib.pyplot as plt
%matplotlib inline

Load the data

In [25]:
img = load_img("food-binary/Dosa/img103.jpeg")
In [39]:
x = img_to_array(img)
plt.imshow(x/255.)
Out[39]:
<matplotlib.image.AxesImage at 0x7fec340f9518>
In [27]:
img_generator = ImageDataGenerator( 
    validation_split=0.2, 
    rescale=1./255,
    featurewise_std_normalization=True,
    vertical_flip=True, 
    zoom_range=0.4, 
    featurewise_center=True, 
    horizontal_flip=True, 
    rotation_range=90.                                 
                    
)
In [28]:
# ?img_generator.flow_from_directory
In [29]:
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)

Data Augmentation

In [30]:
# x
In [34]:
!mkdir preview
In [40]:
x2 = x.reshape((1, ) + x.shape)
In [41]:
i = 0
for batch in img_generator.flow(x2, batch_size = 1, save_to_dir="preview", 
                                save_prefix="cat", save_format="jpeg"):
    i += 1
    if i > 20:
        break
/opt/conda/lib/python3.6/site-packages/keras_preprocessing/image.py:959: UserWarning: This ImageDataGenerator specifies `featurewise_center`, but it hasn't been fit on any training data. Fit it first by calling `.fit(numpy_data)`.
  warnings.warn('This ImageDataGenerator specifies '
/opt/conda/lib/python3.6/site-packages/keras_preprocessing/image.py:967: UserWarning: This ImageDataGenerator specifies `featurewise_std_normalization`, but it hasn't been fit on any training data. Fit it first by calling `.fit(numpy_data)`.
  warnings.warn('This ImageDataGenerator specifies '

Transfer Learning with Image Augmentation

In [42]:
train_generator = get_batches("food-binary/", "training")
val_generator = get_batches("food-binary/", "validation")
Found 264 images belonging to 2 classes.
Found 65 images belonging to 2 classes.
In [43]:
base_model = ResNet50(include_top=False, input_shape=(228, 228, 3))
In [45]:
batch_size = 28
In [46]:
x = base_model.output
In [47]:
x.shape
Out[47]:
TensorShape([Dimension(None), Dimension(7), Dimension(7), Dimension(2048)])
In [48]:
x = GlobalAveragePooling2D()(x)
In [49]:
x.shape
Out[49]:
TensorShape([Dimension(None), Dimension(2048)])
In [50]:
x = Dense(128, activation ="relu")(x)
predictions = Dense(2, activation="softmax")(x)
In [51]:
m = Model(inputs = base_model.input, outputs= predictions)
In [53]:
# m.summary()
In [54]:
m.compile(loss="categorical_crossentropy", optimizer="sgd", metrics=["accuracy"])
In [57]:
m.fit_generator( train_generator, 
                steps_per_epoch=2000 // batch_size,
                epochs = 10,
                validation_data = val_generator, 
                validation_steps = 800 // batch_size)
Epoch 1/10
/opt/conda/lib/python3.6/site-packages/keras_preprocessing/image.py:959: UserWarning: This ImageDataGenerator specifies `featurewise_center`, but it hasn't been fit on any training data. Fit it first by calling `.fit(numpy_data)`.
  warnings.warn('This ImageDataGenerator specifies '
/opt/conda/lib/python3.6/site-packages/keras_preprocessing/image.py:967: UserWarning: This ImageDataGenerator specifies `featurewise_std_normalization`, but it hasn't been fit on any training data. Fit it first by calling `.fit(numpy_data)`.
  warnings.warn('This ImageDataGenerator specifies '
71/71 [==============================] - 28s 391ms/step - loss: 0.2330 - acc: 0.8979 - val_loss: 0.1691 - val_acc: 0.9310
Epoch 2/10
71/71 [==============================] - 28s 389ms/step - loss: 0.1829 - acc: 0.9190 - val_loss: 0.1389 - val_acc: 0.9409
Epoch 3/10
71/71 [==============================] - 27s 384ms/step - loss: 0.0853 - acc: 0.9683 - val_loss: 0.2183 - val_acc: 0.9212
Epoch 4/10
71/71 [==============================] - 27s 383ms/step - loss: 0.0999 - acc: 0.9595 - val_loss: 0.3194 - val_acc: 0.8571
Epoch 5/10
71/71 [==============================] - 27s 383ms/step - loss: 0.0887 - acc: 0.9630 - val_loss: 0.1415 - val_acc: 0.9360
Epoch 6/10
71/71 [==============================] - 27s 382ms/step - loss: 0.0486 - acc: 0.9806 - val_loss: 0.2416 - val_acc: 0.9261
Epoch 7/10
71/71 [==============================] - 28s 391ms/step - loss: 0.0572 - acc: 0.9842 - val_loss: 0.1764 - val_acc: 0.9360
Epoch 8/10
71/71 [==============================] - 27s 386ms/step - loss: 0.0693 - acc: 0.9789 - val_loss: 0.2092 - val_acc: 0.9261
Epoch 9/10
71/71 [==============================] - 28s 387ms/step - loss: 0.0907 - acc: 0.9754 - val_loss: 0.1281 - val_acc: 0.9458
Epoch 10/10
71/71 [==============================] - 27s 381ms/step - loss: 0.0880 - acc: 0.9665 - val_loss: 0.2056 - val_acc: 0.9310
Out[57]:
<keras.callbacks.History at 0x7febbab10438>