KerasでCifar10分類、とりあえずCNNのAlexModelで

GPUマシンが使えるようになったので、Kerasで用意されているデータセットの中にcifar10があったので学習・分類してみた。
モデルはcifar10の作成者でもあり、ILSVRC2012優勝者でもあるAlex Krinzhvskyさんの優勝時のモデルがベース。
モデルの構成について深層学習 (機械学習プロフェッショナルシリーズ)にあった表を参考にした。

モデル作成してて感じたのはやっぱりKerasの自由度の低さ。
レイヤーに差し込む層のタイプによってはストライドが設定できないなど、完全な再現は無理だった。
この辺はKerasでオリジナルのレイヤーを作成して対応していく必要があるのかも。
もう少し調べてから改めて実装したい。

とりあえず、モデル学習のためのスクリプトが下記。

from keras.datasets import cifar10
from keras.models import Model
from keras.layers import Flatten, Dense, Input, Dropout
from keras.layers import Convolution2D, MaxPooling2D, BatchNormalization
from keras.optimizers import Adam
from keras.utils import np_utils

def make_network():
    input_shape = (3,32, 32)
    img_input = Input(shape=input_shape)    


    # Block 1
    x = Convolution2D(96, 11, 11, activation='relu', border_mode='same', name='conv1')(img_input)
    x = MaxPooling2D((3, 3), strides=(2, 2), name='pool1')(x)

    # Block 2
    x = BatchNormalization(name='norm1_')(x)
    x = Convolution2D(256, 5, 5, activation='relu', border_mode='same', name='conv2')(x)
    x = MaxPooling2D((3, 3), strides=(2, 2), name='pool2')(x)

    # Block 3
    x = BatchNormalization(name='norm2_')(x)
    x = Convolution2D(384, 3, 3, activation='relu', border_mode='same', name='conv3')(x)
    x = Convolution2D(384, 3, 3, activation='relu', border_mode='same', name='conv4')(x)
    x = Convolution2D(256, 3, 3, activation='relu', border_mode='same', name='conv5')(x)
    x = MaxPooling2D((3, 3), strides=(2, 2), name='pool5')(x)

    #Classification block
    x = Flatten(name='flatten')(x)
    x = Dense(1024, activation='relu', name='fc6')(x)
    x = Dropout(p = 0.5)(x)
    x = Dense(1024, activation='relu', name='fc7')(x)
    x = Dropout(p = 0.5)(x)
    x = Dense(10, activation='softmax', name='fc8')(x)

    model = Model(img_input, x)

    return model
    

def train_model(model, X_train, Y_train, nb_epoch, batch_size):
    adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
    model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['accuracy'])

    model.fit(X_train, Y_train,
              batch_size=batch_size,
              nb_epoch=nb_epoch,
              validation_split=0.1,
              verbose=1)



if __name__ == '__main__':
  (X_train, y_train), (X_test, y_test) = cifar10.load_data()
    batch_size = 32
    nb_classes = 10
    nb_epoch = 200
    data_augmentation = True
    
    
    # convert class vectors to binary class matrices
    nb_classes = 10
    
    #きっとone-hotエンコーディング
    Y_train = np_utils.to_categorical(y_train, nb_classes)
    Y_test = np_utils.to_categorical(y_test, nb_classes) 
    
    X_train = X_train.astype('float32')
    X_test = X_test.astype('float32')
    X_train /= 255 
    X_test /= 255  
    
    model = make_network()
    %time train_model(model, X_train, Y_train, nb_epoch = nb_epoch, batch_size = batch_size)
    
    #モデルのセーブ
    model.save('CNN_Trained_for_cifar10.h5')

データサイズが50,000で45,000を学習用、残りを評価用に使い、GPUがGeForce GTX 960、メモリ容量が2GBのマシンでEpoch数を200回にして学習。
かかった時間が13時間半と、自分の予想より結構長かった。
最後にモデルをセーブしておいたので、とりあえずこのモデルの評価はまた次回。

参考

深層学習 (機械学習プロフェッショナルシリーズ)

深層学習 (機械学習プロフェッショナルシリーズ)