In [1]:
from __future__ import absolute_import
from __future__ import print_function
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.optimizers import SGD, Adadelta, Adagrad
from keras.utils import np_utils, generic_utils
from six.moves import range


WARNING (theano.configdefaults): g++ not detected ! Theano will be unable to execute optimized C-implementations (for both CPU and GPU) and will default to Python implementations. Performance will be severely degraded. To remove this warning, set Theano flags cxx to an empty string.
WARNING:theano.configdefaults:g++ not detected ! Theano will be unable to execute optimized C-implementations (for both CPU and GPU) and will default to Python implementations. Performance will be severely degraded. To remove this warning, set Theano flags cxx to an empty string.
Couldn't import dot_parser, loading of dot files will not be possible.

In [2]:
'''
    Train a (fairly simple) deep CNN on the CIFAR10 small images dataset.
    GPU run command:
        THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python cifar10_cnn.py
    It gets down to 0.65 test logloss in 25 epochs, and down to 0.55 after 50 epochs.
    (it's still underfitting at that point, though).
    Note: the data was pickled with Python 2, and some encoding issues might prevent you
    from loading it in Python 3. You might have to load it in Python 2,
    save it in a different format, load it in Python 3 and repickle it.
'''


Out[2]:
"\n    Train a (fairly simple) deep CNN on the CIFAR10 small images dataset.\n    GPU run command:\n        THEANO_FLAGS=mode=FAST_RUN,device=gpu,floatX=float32 python cifar10_cnn.py\n    It gets down to 0.65 test logloss in 25 epochs, and down to 0.55 after 50 epochs.\n    (it's still underfitting at that point, though).\n    Note: the data was pickled with Python 2, and some encoding issues might prevent you\n    from loading it in Python 3. You might have to load it in Python 2,\n    save it in a different format, load it in Python 3 and repickle it.\n"

In [3]:
batch_size = 32
nb_classes = 10
nb_epoch = 200
data_augmentation = True

In [4]:
# shape of the image (SHAPE x SHAPE)
shapex, shapey = 32, 32
# number of convolutional filters to use at each layer
nb_filters = [32, 64]
# level of pooling to perform at each layer (POOL x POOL)
nb_pool = [2, 2]
# level of convolution to perform at each layer (CONV x CONV)
nb_conv = [3, 3]
# the CIFAR10 images are RGB
image_dimensions = 3

In [5]:
# the data, shuffled and split between tran and test sets
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
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, 3, 32, 32)
50000 train samples
10000 test samples

In [6]:
# convert class vectors to binary class matrices
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)

In [9]:
y_train.shape, Y_train.shape


Out[9]:
((50000, 1), (50000, 10))

In [10]:
model = Sequential()

In [11]:
model.add(Convolution2D(nb_filters[0], image_dimensions, nb_conv[0], nb_conv[0], border_mode='full'))
model.add(Activation('relu'))
model.add(Convolution2D(nb_filters[0], nb_filters[0], nb_conv[0], nb_conv[0]))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(nb_pool[0], nb_pool[0])))
model.add(Dropout(0.25))

In [12]:
model.add(Convolution2D(nb_filters[1], nb_filters[0], nb_conv[0], nb_conv[0], border_mode='full'))
model.add(Activation('relu'))
model.add(Convolution2D(nb_filters[1], nb_filters[1], nb_conv[1], nb_conv[1]))
model.add(Activation('relu'))
model.add(MaxPooling2D(poolsize=(nb_pool[1], nb_pool[1])))
model.add(Dropout(0.25))

In [13]:
model.add(Flatten())

In [14]:
# the image dimensions are the original dimensions divided by any pooling
# each pixel has a number of filters, determined by the last Convolution2D layer
model.add(Dense(nb_filters[-1] * (shapex / nb_pool[0] / nb_pool[1]) * (shapey / nb_pool[0] / nb_pool[1]), 512))
model.add(Activation('relu'))
model.add(Dropout(0.5))

In [15]:
model.add(Dense(512, nb_classes))
model.add(Activation('softmax'))

In [17]:
# let's train the model using SGD + momentum (how original).
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)


INFO (theano.gof.compilelock): Refreshing lock /Users/rbussman/.theano/compiledir_Darwin-14.5.0-x86_64-i386-64bit-i386-2.7.10-64/lock_dir/lock
INFO:theano.gof.compilelock:Refreshing lock /Users/rbussman/.theano/compiledir_Darwin-14.5.0-x86_64-i386-64bit-i386-2.7.10-64/lock_dir/lock

In [18]:
if not data_augmentation:
    print("Not using data augmentation or normalization")

    X_train = X_train.astype("float32")
    X_test = X_test.astype("float32")
    X_train /= 255
    X_test /= 255
    model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch)
    score = model.evaluate(X_test, Y_test, batch_size=batch_size)
    print('Test score:', score)

else:
    print("Using real time data augmentation")

    # this will do preprocessing and realtime data augmentation
    datagen = ImageDataGenerator(
        featurewise_center=True,  # set input mean to 0 over the dataset
        samplewise_center=False,  # set each sample mean to 0
        featurewise_std_normalization=True,  # divide inputs by std of the dataset
        samplewise_std_normalization=False,  # divide each input by its std
        zca_whitening=False,  # apply ZCA whitening
        rotation_range=20,  # randomly rotate images in the range (degrees, 0 to 180)
        width_shift_range=0.2,  # randomly shift images horizontally (fraction of total width)
        height_shift_range=0.2,  # randomly shift images vertically (fraction of total height)
        horizontal_flip=True,  # randomly flip images
        vertical_flip=False)  # randomly flip images

    # compute quantities required for featurewise normalization
    # (std, mean, and principal components if ZCA whitening is applied)
    datagen.fit(X_train)

    for e in range(nb_epoch):
        print('-'*40)
        print('Epoch', e)
        print('-'*40)
        print("Training...")
        # batch train with realtime data augmentation
        progbar = generic_utils.Progbar(X_train.shape[0])
        for X_batch, Y_batch in datagen.flow(X_train, Y_train):
            loss = model.train_on_batch(X_batch, Y_batch)
            progbar.add(X_batch.shape[0], values=[("train loss", loss)])

        print("Testing...")
        # test time!
        progbar = generic_utils.Progbar(X_test.shape[0])
        for X_batch, Y_batch in datagen.flow(X_test, Y_test):
            score = model.test_on_batch(X_batch, Y_batch)
            progbar.add(X_batch.shape[0], values=[("test loss", score)])


Using real time data augmentation
----------------------------------------
Epoch 0
----------------------------------------
Training...
50000/50000 [==============================] - 5094s - train loss: 1.5760  
Testing...
10000/10000 [==============================] - 322s - test loss: 1.2737   
----------------------------------------
Epoch 1
----------------------------------------
Training...
50000/50000 [==============================] - 5032s - train loss: 1.2557  
Testing...
10000/10000 [==============================] - 323s - test loss: 1.0844   
----------------------------------------
Epoch 2
----------------------------------------
Training...
50000/50000 [==============================] - 5032s - train loss: 1.1119  
Testing...
10000/10000 [==============================] - 322s - test loss: 0.9516   
----------------------------------------
Epoch 3
----------------------------------------
Training...
50000/50000 [==============================] - 5023s - train loss: 1.0350  
Testing...
10000/10000 [==============================] - 323s - test loss: 0.9255   
----------------------------------------
Epoch 4
----------------------------------------
Training...
50000/50000 [==============================] - 5025s - train loss: 0.9826  
Testing...
10000/10000 [==============================] - 322s - test loss: 0.8485   
----------------------------------------
Epoch 5
----------------------------------------
Training...
50000/50000 [==============================] - 5028s - train loss: 0.9372  
Testing...
10000/10000 [==============================] - 323s - test loss: 0.8029   
----------------------------------------
Epoch 6
----------------------------------------
Training...
50000/50000 [==============================] - 5565s - train loss: 0.9038  
Testing...
10000/10000 [==============================] - 369s - test loss: 0.7880   
----------------------------------------
Epoch 7
----------------------------------------
Training...
50000/50000 [==============================] - 5789s - train loss: 0.8790  
Testing...
10000/10000 [==============================] - 342s - test loss: 0.7912   
----------------------------------------
Epoch 8
----------------------------------------
Training...
29504/50000 [================>.............] - ETA: 2128s - train loss: 0.8570
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-18-7b8b1bcd330e> in <module>()
     38         progbar = generic_utils.Progbar(X_train.shape[0])
     39         for X_batch, Y_batch in datagen.flow(X_train, Y_train):
---> 40             loss = model.train_on_batch(X_batch, Y_batch)
     41             progbar.add(X_batch.shape[0], values=[("train loss", loss)])
     42 

/Users/rbussman/anaconda/lib/python2.7/site-packages/keras/models.pyc in train_on_batch(self, X, y, accuracy, sample_weight)
    357             return self._train_with_acc(*ins)
    358         else:
--> 359             return self._train(*ins)
    360 
    361 

/Users/rbussman/anaconda/lib/python2.7/site-packages/theano/compile/function_module.pyc in __call__(self, *args, **kwargs)
    593         t0_fn = time.time()
    594         try:
--> 595             outputs = self.fn()
    596         except Exception:
    597             if hasattr(self.fn, 'position_of_error'):

/Users/rbussman/anaconda/lib/python2.7/site-packages/theano/gof/vm.pyc in __call__(self)
    231                         old_s[0] = None
    232             except:
--> 233                 link.raise_with_op(node, thunk)
    234 
    235 

/Users/rbussman/anaconda/lib/python2.7/site-packages/theano/gof/vm.pyc in __call__(self)
    227                 for thunk, node, old_storage in zip(self.thunks, self.nodes,
    228                                                     self.post_thunk_clear):
--> 229                     thunk()
    230                     for old_s in old_storage:
    231                         old_s[0] = None

/Users/rbussman/anaconda/lib/python2.7/site-packages/theano/gof/op.pyc in rval()
    741 
    742                 def rval():
--> 743                     fill_storage()
    744                     for o in node.outputs:
    745                         compute_map[o][0] = True

/Users/rbussman/anaconda/lib/python2.7/site-packages/theano/gof/cc.pyc in __call__(self)
   1524 
   1525     def __call__(self):
-> 1526         failure = run_cthunk(self.cthunk)
   1527         if failure:
   1528             task, taskname, id = self.find_task(failure)

KeyboardInterrupt: 

In [19]:
progbar.seen_so_far


Out[19]:
29504

In [20]:
score


Out[20]:
array(0.8118864751409853)

In [ ]: