import numpy as np import pandas as pd from time import time from sklearn.model_selection import train_test_split import keras import keras.layers as layers from keras import optimizers from keras.preprocessing.image import ImageDataGenerator from keras.models import Model from keras.layers import Input, Activation, Concatenate from keras.layers import Flatten, Dropout from keras.layers import Convolution2D, MaxPooling2D from keras.layers import GlobalAveragePooling2D # Training variables EPOCHS = 30 BATCH_SIZE = 480 # dataset def prepare_mnist_data(rows=28, cols=28, nb_classes=10, categorical=False, padding = True, debug = True): """ Get MNIST data """ from keras.datasets import mnist from keras.utils import np_utils (X_train, y_train), (X_test, y_test) = mnist.load_data() X_train = X_train.reshape(X_train.shape[0], 1, rows, cols) X_test = X_test.reshape(X_test.shape[0], 1, rows, cols) X_train = X_train.astype('float32') X_test = X_test.astype('float32') X_train /= 255 X_test /= 255 X_train, X_validation, y_train, y_validation = train_test_split(X_train, y_train, test_size=0.2, random_state=0) if padding: # Pad images with 0s X_train = np.pad(X_train, ((0,0),(0,0),(2,2),(2,2)), 'constant') X_test = np.pad(X_test, ((0,0),(0,0),(2,2),(2,2)), 'constant') X_validation = np.pad(X_validation, ((0,0),(0,0),(2,2),(2,2)), 'constant') if categorical: # 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) y_validation = np_utils.to_categorical(y_validation, nb_classes) if debug: print('X_train shape:', X_train.shape) print(X_train.shape[0], 'train samples') print(X_test.shape[0], 'test samples') print(X_validation.shape[0], 'validation samples') if not categorical: train_labels_count = np.unique(y_train, return_counts=True) dataframe_train_labels = pd.DataFrame({'Label':train_labels_count[0], 'Count':train_labels_count[1]}) print(dataframe_train_labels) return X_train, X_test, X_validation, y_train, y_test, y_validation # SqueezeNet def SqueezeNet(nb_classes, inputs=(1, 32, 32)): """ Keras Implementation of SqueezeNet(arXiv 1602.07360) @param nb_classes: total number of final categories Arguments: inputs -- shape of the input images (channel, cols, rows) """ input_img = Input(shape=inputs) conv1 = Convolution2D( 96, (7, 7), activation='relu', kernel_initializer='glorot_uniform', strides=(2, 2), padding='same', name='conv1', data_format="channels_first")(input_img) maxpool1 = MaxPooling2D( pool_size=(3, 3), strides=(2, 2), name='maxpool1', data_format="channels_first")(conv1) fire2_squeeze = Convolution2D( 16, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire2_squeeze', data_format="channels_first")(maxpool1) fire2_expand1 = Convolution2D( 64, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire2_expand1', data_format="channels_first")(fire2_squeeze) fire2_expand2 = Convolution2D( 64, (3, 3), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire2_expand2', data_format="channels_first")(fire2_squeeze) merge2 = Concatenate(axis=1)([fire2_expand1, fire2_expand2]) fire3_squeeze = Convolution2D( 16, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire3_squeeze', data_format="channels_first")(merge2) fire3_expand1 = Convolution2D( 64, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire3_expand1', data_format="channels_first")(fire3_squeeze) fire3_expand2 = Convolution2D( 64, (3, 3), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire3_expand2', data_format="channels_first")(fire3_squeeze) merge3 = Concatenate(axis=1)([fire3_expand1, fire3_expand2]) fire4_squeeze = Convolution2D( 32, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire4_squeeze', data_format="channels_first")(merge3) fire4_expand1 = Convolution2D( 128, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire4_expand1', data_format="channels_first")(fire4_squeeze) fire4_expand2 = Convolution2D( 128, (3, 3), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire4_expand2', data_format="channels_first")(fire4_squeeze) merge4 = Concatenate(axis=1)([fire4_expand1, fire4_expand2]) maxpool4 = MaxPooling2D( pool_size=(3, 3), strides=(2, 2), name='maxpool4', data_format="channels_first")(merge4) fire5_squeeze = Convolution2D( 32, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire5_squeeze', data_format="channels_first")(maxpool4) fire5_expand1 = Convolution2D( 128, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire5_expand1', data_format="channels_first")(fire5_squeeze) fire5_expand2 = Convolution2D( 128, (3, 3), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire5_expand2', data_format="channels_first")(fire5_squeeze) merge5 = Concatenate(axis=1)([fire5_expand1, fire5_expand2]) fire6_squeeze = Convolution2D( 48, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire6_squeeze', data_format="channels_first")(merge5) fire6_expand1 = Convolution2D( 192, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire6_expand1', data_format="channels_first")(fire6_squeeze) fire6_expand2 = Convolution2D( 192, (3, 3), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire6_expand2', data_format="channels_first")(fire6_squeeze) merge6 = Concatenate(axis=1)([fire6_expand1, fire6_expand2]) fire7_squeeze = Convolution2D( 48, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire7_squeeze', data_format="channels_first")(merge6) fire7_expand1 = Convolution2D( 192, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire7_expand1', data_format="channels_first")(fire7_squeeze) fire7_expand2 = Convolution2D( 192, (3, 3), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire7_expand2', data_format="channels_first")(fire7_squeeze) merge7 = Concatenate(axis=1)([fire7_expand1, fire7_expand2]) fire8_squeeze = Convolution2D( 64, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire8_squeeze', data_format="channels_first")(merge7) fire8_expand1 = Convolution2D( 256, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire8_expand1', data_format="channels_first")(fire8_squeeze) fire8_expand2 = Convolution2D( 256, (3, 3), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire8_expand2', data_format="channels_first")(fire8_squeeze) merge8 = Concatenate(axis=1)([fire8_expand1, fire8_expand2]) maxpool8 = MaxPooling2D( pool_size=(3, 3), strides=(2, 2), name='maxpool8', data_format="channels_first")(merge8) fire9_squeeze = Convolution2D( 64, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire9_squeeze', data_format="channels_first")(maxpool8) fire9_expand1 = Convolution2D( 256, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire9_expand1', data_format="channels_first")(fire9_squeeze) fire9_expand2 = Convolution2D( 256, (3, 3), activation='relu', kernel_initializer='glorot_uniform', padding='same', name='fire9_expand2', data_format="channels_first")(fire9_squeeze) merge9 = Concatenate(axis=1)([fire9_expand1, fire9_expand2]) fire9_dropout = Dropout(0.5, name='fire9_dropout')(merge9) conv10 = Convolution2D( nb_classes, (1, 1), activation='relu', kernel_initializer='glorot_uniform', padding='valid', name='conv10', data_format="channels_first")(fire9_dropout) global_avgpool10 = GlobalAveragePooling2D(data_format='channels_first')(conv10) softmax = Activation("softmax", name='softmax')(global_avgpool10) return Model(inputs=input_img, outputs=softmax) # Get dataset X_train, X_test, X_validation, y_train, y_test, y_validation = prepare_mnist_data(categorical = True) # Check model = SqueezeNet(10) model.summary() # Preparation model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adam(), metrics=['accuracy']) # Trainer and validator train_generator = ImageDataGenerator().flow(X_train, y_train, batch_size=BATCH_SIZE) validation_generator = ImageDataGenerator().flow(X_validation, y_validation, batch_size=BATCH_SIZE) # Training from keras.callbacks import TensorBoard steps_per_epoch = X_train.shape[0]//BATCH_SIZE validation_steps = X_validation.shape[0]//BATCH_SIZE tensorboard = TensorBoard(log_dir="logs/{}".format(time())) model.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=EPOCHS, validation_data=validation_generator, validation_steps=validation_steps, shuffle=True, callbacks=[tensorboard]) # Saving the model in keras format (.h5) model.save('squeezenet_keras_v2.2.4.h5') print(">>> Model saved!")