In [1]:
from __future__ import print_function
import numpy as np 
np.random.seed(1337)

In [2]:
import keras
from keras.datasets import cifar10
from keras.models import Model
from keras.layers import Dense, Activation, Flatten, Input, MaxPooling2D
from keras.layers import Conv2D
import h5py  # to ensure we have this package installed 

from keras.callbacks import ModelCheckpoint


Using TensorFlow backend.

In [3]:
batch_size = 32
num_classes = 10
epochs = 150

In [4]:
# The data, shuffled and split between train and test sets:
(x_train, y_train), (x_test, y_test) = cifar10.load_data()

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255

print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')


x_train shape: (50000, 32, 32, 3)
50000 train samples
10000 test samples

In [5]:
# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

Inception Module

Take a look at the inception module figure here: https://arxiv.org/pdf/1409.4842.pdf


In [6]:
# input layer is the same as our typical CNN model 
inputs = Input(shape=(32, 32, 3))

## ----------- New Stuff Starts Here --------- 


tower_1 = Conv2D(64, (1, 1), padding='same', activation='relu')(inputs)
tower_1 = Conv2D(64, (3, 3), padding='same', activation='relu', name='t1_conv')(tower_1)

tower_2 = Conv2D(64, (1, 1), padding='same', activation='relu')(inputs)
tower_2 = Conv2D(64, (5, 5), padding='same', activation='relu')(tower_2)

tower_3 = MaxPooling2D((3, 3), strides=(1, 1), padding='same')(inputs)
tower_3 = Conv2D(64, (1, 1), padding='same', activation='relu')(tower_3)

x = keras.layers.concatenate([tower_1, tower_2, tower_3], axis=1) 

tower_4 = Conv2D(64, (1, 1), padding='same', activation='relu')(x)
tower_4 = Conv2D(64, (3, 3), padding='same', activation='relu', name='t4_conv')(tower_4)

tower_5 = Conv2D(64, (1, 1), padding='same', activation='relu')(x)
tower_5 = Conv2D(64, (5, 5), padding='same', activation='relu')(tower_5)

tower_6 = MaxPooling2D((3, 3), strides=(1, 1), padding='same')(x)
tower_6 = Conv2D(64, (1, 1), padding='same', activation='relu')(tower_6)

x = keras.layers.concatenate([tower_4, tower_5, tower_6], axis=1) 

## ----------- New Stuff Ends Here --------- 

# Rest of the model, again, remains the same 

x = Conv2D(8, (3, 3))(x)    
x = Activation('relu')(x) 
x = MaxPooling2D(pool_size=(2, 2))(x) 
x = Flatten()(x) 

x = Dense(num_classes)(x) 

output = Activation('softmax')(x)

In [7]:
model = Model([inputs], output)

In [8]:
model.summary()  # Notice the 'Connected To' in the summary


__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            (None, 32, 32, 3)    0                                            
__________________________________________________________________________________________________
conv2d_1 (Conv2D)               (None, 32, 32, 64)   256         input_1[0][0]                    
__________________________________________________________________________________________________
conv2d_2 (Conv2D)               (None, 32, 32, 64)   256         input_1[0][0]                    
__________________________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D)  (None, 32, 32, 3)    0           input_1[0][0]                    
__________________________________________________________________________________________________
t1_conv (Conv2D)                (None, 32, 32, 64)   36928       conv2d_1[0][0]                   
__________________________________________________________________________________________________
conv2d_3 (Conv2D)               (None, 32, 32, 64)   102464      conv2d_2[0][0]                   
__________________________________________________________________________________________________
conv2d_4 (Conv2D)               (None, 32, 32, 64)   256         max_pooling2d_1[0][0]            
__________________________________________________________________________________________________
concatenate_1 (Concatenate)     (None, 96, 32, 64)   0           t1_conv[0][0]                    
                                                                 conv2d_3[0][0]                   
                                                                 conv2d_4[0][0]                   
__________________________________________________________________________________________________
conv2d_5 (Conv2D)               (None, 96, 32, 64)   4160        concatenate_1[0][0]              
__________________________________________________________________________________________________
conv2d_6 (Conv2D)               (None, 96, 32, 64)   4160        concatenate_1[0][0]              
__________________________________________________________________________________________________
max_pooling2d_2 (MaxPooling2D)  (None, 96, 32, 64)   0           concatenate_1[0][0]              
__________________________________________________________________________________________________
t4_conv (Conv2D)                (None, 96, 32, 64)   36928       conv2d_5[0][0]                   
__________________________________________________________________________________________________
conv2d_7 (Conv2D)               (None, 96, 32, 64)   102464      conv2d_6[0][0]                   
__________________________________________________________________________________________________
conv2d_8 (Conv2D)               (None, 96, 32, 64)   4160        max_pooling2d_2[0][0]            
__________________________________________________________________________________________________
concatenate_2 (Concatenate)     (None, 288, 32, 64)  0           t4_conv[0][0]                    
                                                                 conv2d_7[0][0]                   
                                                                 conv2d_8[0][0]                   
__________________________________________________________________________________________________
conv2d_9 (Conv2D)               (None, 286, 30, 8)   4616        concatenate_2[0][0]              
__________________________________________________________________________________________________
activation_1 (Activation)       (None, 286, 30, 8)   0           conv2d_9[0][0]                   
__________________________________________________________________________________________________
max_pooling2d_3 (MaxPooling2D)  (None, 143, 15, 8)   0           activation_1[0][0]               
__________________________________________________________________________________________________
flatten_1 (Flatten)             (None, 17160)        0           max_pooling2d_3[0][0]            
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 10)           171610      flatten_1[0][0]                  
__________________________________________________________________________________________________
activation_2 (Activation)       (None, 10)           0           dense_1[0][0]                    
==================================================================================================
Total params: 468,258
Trainable params: 468,258
Non-trainable params: 0
__________________________________________________________________________________________________

In [9]:
# initiate RMSprop optimizer
opt = keras.optimizers.rmsprop(lr=0.0001, decay=1e-6)

# Let's train the model using RMSprop
model.compile(loss='categorical_crossentropy',
              optimizer=opt,
              metrics=['accuracy'])

filepath="../checkpoints/cifar10-inception2-{epoch:02d}-{val_acc:.2f}.hdf5"
checkpoint = ModelCheckpoint(filepath, 
                             monitor='val_acc', 
                             verbose=1, 
                             mode='max')

model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          validation_data=(x_test, y_test),
          callbacks=[checkpoint])


Train on 50000 samples, validate on 10000 samples
Epoch 1/150
50000/50000 [==============================] - 163s 3ms/step - loss: 1.6057 - acc: 0.4292 - val_loss: 1.3769 - val_acc: 0.5091

Epoch 00001: saving model to ../checkpoints/cifar10-inception2-01-0.51.hdf5
Epoch 2/150
50000/50000 [==============================] - 159s 3ms/step - loss: 1.2724 - acc: 0.5516 - val_loss: 1.2164 - val_acc: 0.5633

Epoch 00002: saving model to ../checkpoints/cifar10-inception2-02-0.56.hdf5
Epoch 3/150
50000/50000 [==============================] - 155s 3ms/step - loss: 1.1300 - acc: 0.6040 - val_loss: 1.1313 - val_acc: 0.5970

Epoch 00003: saving model to ../checkpoints/cifar10-inception2-03-0.60.hdf5
Epoch 4/150
50000/50000 [==============================] - 154s 3ms/step - loss: 1.0309 - acc: 0.6415 - val_loss: 1.1022 - val_acc: 0.6120

Epoch 00004: saving model to ../checkpoints/cifar10-inception2-04-0.61.hdf5
Epoch 5/150
50000/50000 [==============================] - 153s 3ms/step - loss: 0.9556 - acc: 0.6677 - val_loss: 0.9855 - val_acc: 0.6587

Epoch 00005: saving model to ../checkpoints/cifar10-inception2-05-0.66.hdf5
Epoch 6/150
50000/50000 [==============================] - 152s 3ms/step - loss: 0.8965 - acc: 0.6903 - val_loss: 0.9809 - val_acc: 0.6554

Epoch 00006: saving model to ../checkpoints/cifar10-inception2-06-0.66.hdf5
Epoch 7/150
50000/50000 [==============================] - 151s 3ms/step - loss: 0.8472 - acc: 0.7077 - val_loss: 0.9198 - val_acc: 0.6755

Epoch 00007: saving model to ../checkpoints/cifar10-inception2-07-0.68.hdf5
Epoch 8/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.8057 - acc: 0.7212 - val_loss: 0.9503 - val_acc: 0.6732

Epoch 00008: saving model to ../checkpoints/cifar10-inception2-08-0.67.hdf5
Epoch 9/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.7700 - acc: 0.7350 - val_loss: 0.9017 - val_acc: 0.6928

Epoch 00009: saving model to ../checkpoints/cifar10-inception2-09-0.69.hdf5
Epoch 10/150
50000/50000 [==============================] - 151s 3ms/step - loss: 0.7380 - acc: 0.7481 - val_loss: 0.8816 - val_acc: 0.6983

Epoch 00010: saving model to ../checkpoints/cifar10-inception2-10-0.70.hdf5
Epoch 11/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.7082 - acc: 0.7561 - val_loss: 0.8974 - val_acc: 0.6977

Epoch 00011: saving model to ../checkpoints/cifar10-inception2-11-0.70.hdf5
Epoch 12/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.6804 - acc: 0.7678 - val_loss: 0.8932 - val_acc: 0.6955

Epoch 00012: saving model to ../checkpoints/cifar10-inception2-12-0.70.hdf5
Epoch 13/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.6531 - acc: 0.7771 - val_loss: 0.8748 - val_acc: 0.7021

Epoch 00013: saving model to ../checkpoints/cifar10-inception2-13-0.70.hdf5
Epoch 14/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.6301 - acc: 0.7843 - val_loss: 0.8789 - val_acc: 0.7087

Epoch 00014: saving model to ../checkpoints/cifar10-inception2-14-0.71.hdf5
Epoch 15/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.6065 - acc: 0.7949 - val_loss: 0.8636 - val_acc: 0.7098

Epoch 00015: saving model to ../checkpoints/cifar10-inception2-15-0.71.hdf5
Epoch 16/150
50000/50000 [==============================] - 151s 3ms/step - loss: 0.5825 - acc: 0.8019 - val_loss: 0.8830 - val_acc: 0.7049

Epoch 00016: saving model to ../checkpoints/cifar10-inception2-16-0.70.hdf5
Epoch 17/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.5610 - acc: 0.8085 - val_loss: 0.9162 - val_acc: 0.6994

Epoch 00017: saving model to ../checkpoints/cifar10-inception2-17-0.70.hdf5
Epoch 18/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.5400 - acc: 0.8181 - val_loss: 0.8968 - val_acc: 0.7059

Epoch 00018: saving model to ../checkpoints/cifar10-inception2-18-0.71.hdf5
Epoch 19/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.5190 - acc: 0.8242 - val_loss: 0.8989 - val_acc: 0.7094

Epoch 00019: saving model to ../checkpoints/cifar10-inception2-19-0.71.hdf5
Epoch 20/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.4991 - acc: 0.8321 - val_loss: 0.9161 - val_acc: 0.7022

Epoch 00020: saving model to ../checkpoints/cifar10-inception2-20-0.70.hdf5
Epoch 21/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.4795 - acc: 0.8385 - val_loss: 0.9733 - val_acc: 0.6908

Epoch 00021: saving model to ../checkpoints/cifar10-inception2-21-0.69.hdf5
Epoch 22/150
50000/50000 [==============================] - 151s 3ms/step - loss: 0.4616 - acc: 0.8446 - val_loss: 0.9049 - val_acc: 0.7072

Epoch 00022: saving model to ../checkpoints/cifar10-inception2-22-0.71.hdf5
Epoch 23/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.4427 - acc: 0.8521 - val_loss: 0.9120 - val_acc: 0.7137

Epoch 00023: saving model to ../checkpoints/cifar10-inception2-23-0.71.hdf5
Epoch 24/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.4227 - acc: 0.8586 - val_loss: 0.9376 - val_acc: 0.7129

Epoch 00024: saving model to ../checkpoints/cifar10-inception2-24-0.71.hdf5
Epoch 25/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.4055 - acc: 0.8662 - val_loss: 0.9384 - val_acc: 0.7175

Epoch 00025: saving model to ../checkpoints/cifar10-inception2-25-0.72.hdf5
Epoch 26/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.3885 - acc: 0.8711 - val_loss: 1.0215 - val_acc: 0.7007

Epoch 00026: saving model to ../checkpoints/cifar10-inception2-26-0.70.hdf5
Epoch 27/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.3710 - acc: 0.8789 - val_loss: 1.0452 - val_acc: 0.7029

Epoch 00027: saving model to ../checkpoints/cifar10-inception2-27-0.70.hdf5
Epoch 28/150
50000/50000 [==============================] - 150s 3ms/step - loss: 0.3548 - acc: 0.8845 - val_loss: 1.0194 - val_acc: 0.7118

Epoch 00028: saving model to ../checkpoints/cifar10-inception2-28-0.71.hdf5
Epoch 29/150
39392/50000 [======================>.......] - ETA: 29s - loss: 0.3352 - acc: 0.8897

KeyboardInterruptTraceback (most recent call last)
<ipython-input-9-052e5bee6b78> in <module>()
     17           epochs=epochs,
     18           validation_data=(x_test, y_test),
---> 19           callbacks=[checkpoint])

/usr/local/lib/python2.7/dist-packages/keras/engine/training.pyc in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
   1035                                         initial_epoch=initial_epoch,
   1036                                         steps_per_epoch=steps_per_epoch,
-> 1037                                         validation_steps=validation_steps)
   1038 
   1039     def evaluate(self, x=None, y=None,

/usr/local/lib/python2.7/dist-packages/keras/engine/training_arrays.pyc in fit_loop(model, f, ins, out_labels, batch_size, epochs, verbose, callbacks, val_f, val_ins, shuffle, callback_metrics, initial_epoch, steps_per_epoch, validation_steps)
    197                     ins_batch[i] = ins_batch[i].toarray()
    198 
--> 199                 outs = f(ins_batch)
    200                 outs = to_list(outs)
    201                 for l, o in zip(out_labels, outs):

/usr/local/lib/python2.7/dist-packages/keras/backend/tensorflow_backend.pyc in __call__(self, inputs)
   2664                 return self._legacy_call(inputs)
   2665 
-> 2666             return self._call(inputs)
   2667         else:
   2668             if py_any(is_tensor(x) for x in inputs):

/usr/local/lib/python2.7/dist-packages/keras/backend/tensorflow_backend.pyc in _call(self, inputs)
   2634                                 symbol_vals,
   2635                                 session)
-> 2636         fetched = self._callable_fn(*array_vals)
   2637         return fetched[:len(self.outputs)]
   2638 

/usr/local/lib/python2.7/dist-packages/tensorflow/python/client/session.pyc in __call__(self, *args, **kwargs)
   1397           ret = tf_session.TF_SessionRunCallable(
   1398               self._session._session, self._handle, args, status,
-> 1399               run_metadata_ptr)
   1400         if run_metadata:
   1401           proto_data = tf_session.TF_GetBuffer(run_metadata_ptr)

KeyboardInterrupt: 

Next Steps

Now you are in the position to go ahead and explore the Keras documentation on your own. There are some great examples here https://keras.io/getting-started/functional-api-guide/#more-examples


In [10]:
model_json = model.to_json()
with open("model.json", "w") as json_file:
    json_file.write(model_json)
# serialize weights to HDF5
model.save_weights("model.h5")
print("Saved model to disk")


Saved model to disk

In [ ]: