In [167]:
%matplotlib inline
import keras
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
import numpy as np
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from matplotlib import pyplot as plt
from keras.optimizers import SGD, RMSprop
from scipy.misc import imresize
from keras import backend as K
K.set_image_dim_ordering('th')
K.image_dim_ordering()


Out[167]:
'th'
Reducing the size of the data to test on a cpu

In [5]:
def reducex(X, y, reduce_classes=None, reduce_percent=.2):
#     import pdb; pdb.set_trace()
    idxs = []
    if reduce_classes:
        for c in reduce_classes:
            try:
                idxs += list(np.where(y == c)[0])
            except IndexError:
                continue
    np.random.seed(1000)
    new_size = int(np.round(len(idxs) * reduce_percent))
    np.random.shuffle(idxs)
    return (X[idxs[:int(len(idxs)*reduce_percent)]], y[idxs[:int(len(idxs)*reduce_percent)]] == 3)

batch_size = 16
Splitting the data into validation and train + One Hot Encoding the labels + data augumentation

In [181]:
(Xtrain, ytrain), (Xtest, ytest) = cifar10.load_data()

train_datagen = ImageDataGenerator(
            rotation_range=40,
            width_shift_range=0.2,
            height_shift_range=0.2,
            shear_range=0.2,
            zoom_range=0.2,
            horizontal_flip=True,
            fill_mode='nearest')

test_datagen = ImageDataGenerator(rescale=1./255)

Xtrain, ytrain = reducex(Xtrain, ytrain, reduce_classes=[3,5], reduce_percent=0.3)
Xtest, ytest = reducex(Xtest, ytest, reduce_classes=[3,5], reduce_percent=0.3)

yetrain = keras.utils.to_categorical(ytrain)
yetest = keras.utils.to_categorical(ytest)
Recizing the images into appropriate dimensions that VGG16 expects (48x48 - 224x224)

In [187]:
######## Resize cifar10 images to 3x48x48 #############
rsize = 48
temp = np.zeros((Xtrain.shape[0], 3, rsize, rsize))

for i, row in enumerate(Xtrain):
    temp[i] = imresize(row, size=(rsize,rsize)).transpose(2,1,0)

temp2 = np.zeros((Xtrain.shape[0], 3, rsize, rsize))
for i in Xtest:
    temp2[i] = imresize(row, size=(rsize,rsize)).transpose(2,1,0)

Xtrain = temp
Xtest = temp2


---------------------------------------------------------------------------
MemoryError                               Traceback (most recent call last)
<ipython-input-187-15063be704f4> in <module>()
      1 ######## Resize cifar10 images to 3x48x48 #############
      2 rsize = 224
----> 3 temp = np.zeros((Xtrain.shape[0], 3, rsize, rsize))
      4 
      5 for i, row in enumerate(Xtrain):

MemoryError: 
Plotting sample resized image and it's augumented copies

In [1]:
from keras.applications import VGG16

vmodel = VGG16(include_top=True, weights='imagenet')#, input_shape=(3,48,48))

vmodel.layers.pop()
for layr in vmodel.layers:
    layr.trainable = False
last = vmodel.output
# x = Flatten(last)
x = Dense(2, activation='sigmoid')(last)
vvmodel = keras.models.Model(vmodel.input, x)

# vmodel.add(Dense(2))
# vmodel.add(Activation('sigmoid'))
vvmodel.summary()

In [179]:
opt = RMSprop(lr=0.01)
vvmodel.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])

def fit_model(model, batches, val_batches, epochs=1):
    model.fit_generator(batches, steps_per_epoch=1500 // batch_size, epochs=epochs, 
                        validation_steps=700 // batch_size,
                        validation_data=val_batches)

vvmodel.fit(Xtrain[0:100], yetrain[0:100], verbose=True)

fit_model(vvmodel, train_generator, validation_generator, epochs=2)

# model.fit_generator(
#         train_generator,
#         steps_per_epoch=500 // batch_size,
#         epochs=15,
#         validation_data=validation_generator,
#         validation_steps=300 // batch_size)

In [62]:
# img = load_img('data/train/cats/cat.0.jpg')  # this is a PIL image
# x = img_to_array(img)  # this is a Numpy array with shape (3, 150, 150)
x = Xtrain[8]
x = x.reshape((1,) + x.shape)  # this is a Numpy array with shape (1, 3, 150, 150)
# the .flow() command below generates batches of randomly transformed images
# and saves the results to the `preview/` directory
i = 0
j = 0
xims = []
fig, axes = plt.subplots(2,2,figsize=(12,8))
for batch in datagen.flow(x, batch_size=1):
    axes[j][i].set_axis_off()
    axes[j][i].imshow(batch.reshape(x.shape[1:]).transpose(2,1,0), interpolation='nearest')
    if i >= 1:
        j += 1
        i = -1
    if j == 2:
        break
    i +=1 
    print j,i
    
# plt.imshow(Xtrain[0].reshape(32,32,3))
# fig, axes1 = plt.subplots(2,2,figsize=(12,8))
# for j in range(5):
#     for k in range(5):
#         i = np.random.choice(range(len(X)))
#         axes1[j][k].set_axis_off()
#         axes1[j][k].imshow(X[i:i+1][0], interpolation='nearest')
print ytrain[8]


0 1
1 0
1 1
[ True]

In [97]:
# train_generator = datagen.flow(Xtrain,yetrain,
#         batch_size=batch_size)  # since we use binary_crossentropy loss, we need binary labels

# # this is a similar generator, for validation data
# validation_generator = test_datagen.flow(Xtest, yetest,
#         batch_size=batch_size)
Barebones Convolutional model

In [98]:
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(3, 32, 32)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten()) # this converts our 3D feature maps to 1D feature vectors
model.add(Dense(32))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(2))
model.add(Activation('sigmoid'))
print(model.summary())


_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_4 (Conv2D)            (None, 32, 30, 30)        896       
_________________________________________________________________
activation_6 (Activation)    (None, 32, 30, 30)        0         
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 32, 15, 15)        0         
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 32, 13, 13)        9248      
_________________________________________________________________
activation_7 (Activation)    (None, 32, 13, 13)        0         
_________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 32, 6, 6)          0         
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 64, 4, 4)          18496     
_________________________________________________________________
activation_8 (Activation)    (None, 64, 4, 4)          0         
_________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 64, 2, 2)          0         
_________________________________________________________________
flatten_6 (Flatten)          (None, 256)               0         
_________________________________________________________________
dense_7 (Dense)              (None, 32)                8224      
_________________________________________________________________
activation_9 (Activation)    (None, 32)                0         
_________________________________________________________________
dropout_4 (Dropout)          (None, 32)                0         
_________________________________________________________________
dense_8 (Dense)              (None, 2)                 66        
_________________________________________________________________
activation_10 (Activation)   (None, 2)                 0         
=================================================================
Total params: 36,930.0
Trainable params: 36,930.0
Non-trainable params: 0.0
_________________________________________________________________
None

In [99]:
model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

In [100]:
batch_size = 64
model.fit_generator(
        train_generator,
        steps_per_epoch=500 // batch_size,
        epochs=15,
        validation_data=validation_generator,
        validation_steps=300 // batch_size)
import datetime
now = str(datetime.datetime.now())


Epoch 1/15
7/7 [==============================] - 2s - loss: 4.0395 - acc: 0.5257 - val_loss: 0.6932 - val_acc: 0.5117
Epoch 2/15
7/7 [==============================] - 1s - loss: 0.7200 - acc: 0.4900 - val_loss: 0.6930 - val_acc: 0.5000
Epoch 3/15
7/7 [==============================] - 1s - loss: 0.6975 - acc: 0.4944 - val_loss: 0.6933 - val_acc: 0.5000
Epoch 4/15
7/7 [==============================] - 1s - loss: 0.6943 - acc: 0.4989 - val_loss: 0.6929 - val_acc: 0.5000
Epoch 5/15
7/7 [==============================] - 1s - loss: 0.6959 - acc: 0.5033 - val_loss: 0.6931 - val_acc: 0.5000
Epoch 6/15
7/7 [==============================] - 1s - loss: 0.6933 - acc: 0.5045 - val_loss: 0.6934 - val_acc: 0.4745
Epoch 7/15
7/7 [==============================] - 2s - loss: 0.7386 - acc: 0.5206 - val_loss: 0.6929 - val_acc: 0.5234
Epoch 8/15
7/7 [==============================] - 1s - loss: 0.6934 - acc: 0.5212 - val_loss: 0.6929 - val_acc: 0.5185
Epoch 9/15
7/7 [==============================] - 1s - loss: 0.6928 - acc: 0.4743 - val_loss: 0.6932 - val_acc: 0.4961
Epoch 10/15
7/7 [==============================] - 1s - loss: 0.7018 - acc: 0.5112 - val_loss: 0.6933 - val_acc: 0.4883
Epoch 11/15
7/7 [==============================] - 1s - loss: 0.6928 - acc: 0.5290 - val_loss: 0.6930 - val_acc: 0.5093
Epoch 12/15
7/7 [==============================] - 1s - loss: 0.6937 - acc: 0.4621 - val_loss: 0.6930 - val_acc: 0.5156
Epoch 13/15
7/7 [==============================] - 1s - loss: 0.7619 - acc: 0.5179 - val_loss: 0.6928 - val_acc: 0.5278
Epoch 14/15
7/7 [==============================] - 1s - loss: 0.8200 - acc: 0.5316 - val_loss: 0.6935 - val_acc: 0.4805
Epoch 15/15
7/7 [==============================] - 1s - loss: 0.6959 - acc: 0.5045 - val_loss: 0.6928 - val_acc: 0.5273

In [126]:
# model.save_weights('first_try.h5')  # always save your weights after training or during training
weights = model.weights[6:]
weights[0].eval().shape


Out[126]:
(256L, 32L)

Using VGG16 Bottleneck Features


In [183]:
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow(Xtrain,
        batch_size=batch_size, shuffle=True)  # since we use binary_crossentropy loss, we need binary labels

# this is a similar generator, for validation data
validation_generator = test_datagen.flow(Xtest,
        batch_size=batch_size, shuffle=True)

In [172]:
# train_batches = train_generator.flow(Xtrain, yetrain, batch_size=batch_size, shuffle=True)
# val_batches = test_datagen.flow(Xtest, yetest, batch_size=batch_size, shuffle=False)


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-172-bb9ea781a7b5> in <module>()
----> 1 train_batches = train_generator.flow(Xtrain, yetrain, batch_size=batch_size, shuffle=True)
      2 val_batches = test_datagen.flow(Xtest, yetest, batch_size=batch_size, shuffle=False)

AttributeError: 'NumpyArrayIterator' object has no attribute 'flow'

In [ ]:
bottleneck_features_train = vmodel.predict_generator(
        train_generator, 500)
np.save(open('bottleneck_features_train.npy', 'w'),
            bottleneck_features_train)

In [ ]:
top_model = Sequential()
top_model.add(Flatten(input_shape=(256,32),weights=np.zeros((256,32))))
top_model.add(Dense(32))
top_model.add(Activation('relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(2))
top_model.add(Activation('sigmoid'))

In [138]:
# top_model.set_weights(weights)
top_model.layers[0].set_weights(weights[0].eval())

In [ ]:
top_model_weights_path = 'first_try.h5'
top_model.load_weights(top_model_weights_path)

# add the model on top of the convolutional base
vmodel.add(top_model)

# set the first 25 layers (up to the last conv block)
# to non-trainable (weights will not be updated)
for layer in model.layers[:25]:
    layer.trainable = False

# compile the model with a SGD/momentum optimizer
# and a very slow learning rate.
vmodel.compile(loss='binary_crossentropy',
              optimizer=SGD(lr=1e-4, momentum=0.9),
              metrics=['accuracy'])

# prepare data augmentation configuration
# train_datagen = ImageDataGenerator(
#     rescale=1. / 255,
#     shear_range=0.2,
#     zoom_range=0.2,
#     horizontal_flip=True)

# test_datagen = ImageDataGenerator(rescale=1. / 255)

# train_generator = train_datagen.flow_from_directory(
#     train_data_dir,
#     target_size=(img_height, img_width),
#     batch_size=batch_size,
#     class_mode='binary')

# validation_generator = test_datagen.flow_from_directory(
#     validation_data_dir,
#     target_size=(img_height, img_width),
#     batch_size=batch_size,
#     class_mode='binary')

# fine-tune the model

In [ ]:
epochs = 25
vmodel.fit_generator(
    train_generator,
    samples_per_epoch=nb_train_samples,
    epochs=epochs,
    validation_data=validation_generator,
    nb_val_samples=nb_validation_samples)