Bonus - CNN localization with Class Activation Mapping (CAM)

https://arxiv.org/pdf/1512.04150.pdf


In [1]:
import pickle

pickle_file = '-catsdogs.pickle'

with open(pickle_file, 'rb') as f:
    save = pickle.load(f)
    X_train = save['X_train']
    y_train = save['y_train']
    X_test = save['X_test']
    y_test = save['y_test']
    del save  # hint to help gc free up memory
    print('Training set', X_train.shape, y_train.shape)
    print('Test set', X_test.shape, y_test.shape)


('Training set', (14000, 64, 64), (14000, 1))
('Test set', (6000, 64, 64), (6000, 1))

In [2]:
import numpy as np
np.random.seed(1337)  # for reproducibility

from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D, AveragePooling2D
from keras.utils import np_utils
from keras.callbacks import ModelCheckpoint
from keras import backend as K

from keras.datasets import mnist


Using TensorFlow backend.

In [3]:
# number of classes
num_classes = 2

# image dimensions
img_rows, img_cols = X_train.shape[1],  X_train.shape[2]

if K.image_dim_ordering() == 'th':
    X_train = X_train.reshape(X_train.shape[0], 1, img_rows, img_cols)
    X_test = X_test.reshape(X_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    X_train = X_train.reshape(X_train.shape[0], img_rows, img_cols, 1)
    X_test = X_test.reshape(X_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

Y_train = np_utils.to_categorical(y_train, num_classes)
Y_test = np_utils.to_categorical(y_test, num_classes)

print input_shape


(1, 64, 64)

In [4]:
# training parameters
batch_size = 16
nb_epoch = 30

# network architecture
patch_size_1 = 3
patch_size_2 = 3
patch_size_3 = 3
patch_size_4 = 3

depth_1 = 128
depth_2 = 256
depth_3 = 512
depth_4 = 1024

pool_size = 2

In [5]:
model = Sequential()

model.add(Convolution2D(depth_1, patch_size_1, patch_size_1, border_mode='valid',
                        input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(pool_size, pool_size)))

model.add(Convolution2D(depth_2, patch_size_2, patch_size_2, border_mode='valid'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(pool_size, pool_size)))

model.add(Convolution2D(depth_3, patch_size_3, patch_size_3, border_mode='valid'))
model.add(Activation('relu'))
# model.add(MaxPooling2D(pool_size=(pool_size, pool_size)))

model.add(Convolution2D(depth_4, patch_size_4, patch_size_4, border_mode='valid'))
model.add(Activation('relu'))

model.add(AveragePooling2D(pool_size=(10, 10)))
model.add(Flatten())
model.add(Dense(num_classes))

model.add(Activation('softmax'))

In [8]:
import os

checkpoint_name = "-model-CAM-2.hdf5"

if os.path.isfile(checkpoint_name):
    model.load_weights(checkpoint_name)

checkpointer = ModelCheckpoint(checkpoint_name, verbose=0, save_best_only=True)

model.compile(loss='categorical_crossentropy',
              optimizer='adadelta',
              metrics=['accuracy'])

In [ ]:
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch,
          verbose=1, validation_data=(X_test, Y_test), callbacks=[checkpointer])


Train on 14000 samples, validate on 6000 samples
Epoch 1/30
14000/14000 [==============================] - 3156s - loss: 0.4258 - acc: 0.8065 - val_loss: 0.4470 - val_acc: 0.7883
Epoch 2/30
14000/14000 [==============================] - 3150s - loss: 0.3965 - acc: 0.8216 - val_loss: 0.3984 - val_acc: 0.8267
Epoch 3/30
14000/14000 [==============================] - 3350s - loss: 0.3694 - acc: 0.8355 - val_loss: 0.4074 - val_acc: 0.8123
Epoch 4/30
14000/14000 [==============================] - 2975s - loss: 0.3475 - acc: 0.8500 - val_loss: 0.4155 - val_acc: 0.8078
Epoch 5/30
14000/14000 [==============================] - 2837s - loss: 0.3279 - acc: 0.8571 - val_loss: 0.5676 - val_acc: 0.7360
Epoch 6/30
14000/14000 [==============================] - 2802s - loss: 0.3023 - acc: 0.8744 - val_loss: 0.4083 - val_acc: 0.8195
Epoch 7/30
14000/14000 [==============================] - 2780s - loss: 0.2816 - acc: 0.8814 - val_loss: 0.3203 - val_acc: 0.8617
Epoch 8/30
14000/14000 [==============================] - 2756s - loss: 0.2612 - acc: 0.8930 - val_loss: 0.3798 - val_acc: 0.8327
Epoch 9/30
14000/14000 [==============================] - 2749s - loss: 0.2392 - acc: 0.9001 - val_loss: 0.3424 - val_acc: 0.8483
Epoch 10/30
14000/14000 [==============================] - 2744s - loss: 0.2204 - acc: 0.9100 - val_loss: 0.3949 - val_acc: 0.8295
Epoch 11/30
14000/14000 [==============================] - 2737s - loss: 0.2000 - acc: 0.9199 - val_loss: 0.3242 - val_acc: 0.8685
Epoch 12/30
14000/14000 [==============================] - 2722s - loss: 0.1836 - acc: 0.9257 - val_loss: 0.3309 - val_acc: 0.8725
Epoch 13/30
14000/14000 [==============================] - 2789s - loss: 0.1638 - acc: 0.9352 - val_loss: 0.3324 - val_acc: 0.8772
Epoch 14/30
14000/14000 [==============================] - 2797s - loss: 0.1478 - acc: 0.9421 - val_loss: 0.4074 - val_acc: 0.8492
Epoch 15/30
 2560/14000 [====>.........................] - ETA: 108506s - loss: 0.1269 - acc: 0.9516

In [ ]: