ぱたへね

はてなダイアリーはrustの色分けができないのでこっちに来た

Kerasを使ってみた

Kerasを使ってひらがな認識のCNNを動かしてみました。情報を取り出すのが素のTensorflow, Caffe, Darknetに比べて非常に楽でした。

ひらがな認識をkerasで動かす

意外に簡単にできました。
https://github.com/natsutan/NPU/blob/master/example/keres_cnn/keras/chihay_cnn.py

ネットワークの構築はこう。MNISTのチュートリアルそのままです。

model = Sequential()

model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1],
                        border_mode='valid',
                        input_shape=input_shape))
model.add(Activation('relu'))
model.add(Convolution2D(nb_filters, kernel_size[0], kernel_size[1]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=pool_size))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(kana_num))
model.add(Activation('softmax'))

ネットワーク、学習結果の出力

Kerasはネットワークの情報を持ち出すのが、Kaffe, Tensorflowに比べてわかりやすい。ちなみにDarknetはさっぱりわからない。

モデルのJSON出力

to_json()を使う。

with open('output/cnn.json', 'w') as fp:
    json_string = model.to_json()
    fp.write(json_string)

改行がほしいが、プログラムで読む分は問題ない。

{"class_name": "Sequential", "config": [{"class_name": "Convolution2D", "config": {"subsample": [1, 1], "nb_filter": 32, "nb_col": 3, "trainable": true, "init": "glorot_uniform", "W_regularizer": null, "b_regularizer": null, "bias": true, "input_dtype": "float32", "W_constraint": null, "nb_row": 3, "name": "convolution2d_1", "activation": "linear", "activity_regularizer": null, "border_mode": "valid", "dim_ordering": "tf", "batch_input_shape": [null, 28, 28, 1], "b_constraint": null}}, {"class_name": "Activation", "config": {"activation": "relu", "trainable": true, "name": "activation_1"}}, {"class_name": "Convolution2D", "config": {"subsample": [1, 1], "nb_filter": 32, "nb_col": 3, "trainable": true, "init": "glorot_uniform", "W_regularizer": null, "b_regularizer": null, "W_constraint": null, "nb_row": 3, "name": "convolution2d_2", "activation": "linear", "activity_regularizer": null, "bias": true, "dim_ordering": "tf", "b_constraint": null, "border_mode": "valid"}}, {"class_name": "Activation", "config": {"activation": "relu", "trainable": true, "name": "activation_2"}}, {"class_name": "MaxPooling2D", "config": {"strides": [2, 2], "trainable": true, "name": "maxpooling2d_1", "pool_size": [2, 2], "dim_ordering": "tf", "border_mode": "valid"}}, {"class_name": "Dropout", "config": {"p": 0.25, "trainable": true, "name": "dropout_1"}}, {"class_name": "Flatten", "config": {"trainable": true, "name": "flatten_1"}}, {"class_name": "Dense", "config": {"output_dim": 128, "activation": "linear", "trainable": true, "b_regularizer": null, "init": "glorot_uniform", "W_regularizer": null, "input_dim": 4608, "b_constraint": null, "name": "dense_1", "W_constraint": null, "activity_regularizer": null, "bias": true}}, {"class_name": "Activation", "config": {"activation": "relu", "trainable": true, "name": "activation_3"}}, {"class_name": "Dropout", "config": {"p": 0.5, "trainable": true, "name": "dropout_2"}}, {"class_name": "Dense", "config": {"output_dim": 46, "activation": "linear", "trainable": true, "b_regularizer": null, "init": "glorot_uniform", "W_regularizer": null, "input_dim": 128, "b_constraint": null, "name": "dense_2", "W_constraint": null, "activity_regularizer": null, "bias": true}}, {"class_name": "Activation", "config": {"activation": "softmax", "trainable": true, "name": "activation_4"}}], "keras_version": "1.2.0"}
サマリー出力

summary()で簡単。

print(model.summary())

実行時にはこのように表示される。

____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to                     
====================================================================================================
convolution2d_1 (Convolution2D)  (None, 26, 26, 32)    320         convolution2d_input_1[0][0]      
____________________________________________________________________________________________________
activation_1 (Activation)        (None, 26, 26, 32)    0           convolution2d_1[0][0]            
____________________________________________________________________________________________________
convolution2d_2 (Convolution2D)  (None, 24, 24, 32)    9248        activation_1[0][0]               
____________________________________________________________________________________________________
activation_2 (Activation)        (None, 24, 24, 32)    0           convolution2d_2[0][0]            
____________________________________________________________________________________________________
maxpooling2d_1 (MaxPooling2D)    (None, 12, 12, 32)    0           activation_2[0][0]               
____________________________________________________________________________________________________
dropout_1 (Dropout)              (None, 12, 12, 32)    0           maxpooling2d_1[0][0]             
____________________________________________________________________________________________________
flatten_1 (Flatten)              (None, 4608)          0           dropout_1[0][0]                  
____________________________________________________________________________________________________
dense_1 (Dense)                  (None, 128)           589952      flatten_1[0][0]                  
____________________________________________________________________________________________________
activation_3 (Activation)        (None, 128)           0           dense_1[0][0]                    
____________________________________________________________________________________________________
dropout_2 (Dropout)              (None, 128)           0           activation_3[0][0]               
____________________________________________________________________________________________________
dense_2 (Dense)                  (None, 46)            5934        dropout_2[0][0]                  
____________________________________________________________________________________________________
activation_4 (Activation)        (None, 46)            0           dense_2[0][0]                    
====================================================================================================
Total params: 605,454
Trainable params: 605,454
Non-trainable params: 0
Pythonからの取得

get_config()でlistとして情報を取得できる。

config = model.get_config()
for l in config:
    print(l)

上のサマリーよりは詳しい情報が取れる。json出力と情報量は同じっぽい。

{'class_name': 'Convolution2D', 'config': {'subsample': (1, 1), 'nb_filter': 32, 'nb_col': 3, 'trainable': True, 'init': 'glorot_uniform', 'W_regularizer': None, 'b_regularizer': None, 'bias': True, 'input_dtype': 'float32', 'W_constraint': None, 'nb_row': 3, 'name': 'convolution2d_1', 'activation': 'linear', 'activity_regularizer': None, 'border_mode': 'valid', 'dim_ordering': 'tf', 'batch_input_shape': (None, 28, 28, 1), 'b_constraint': None}}
{'class_name': 'Activation', 'config': {'activation': 'relu', 'trainable': True, 'name': 'activation_1'}}
{'class_name': 'Convolution2D', 'config': {'subsample': (1, 1), 'nb_filter': 32, 'nb_col': 3, 'trainable': True, 'init': 'glorot_uniform', 'W_regularizer': None, 'b_regularizer': None, 'W_constraint': None, 'nb_row': 3, 'name': 'convolution2d_2', 'activation': 'linear', 'activity_regularizer': None, 'bias': True, 'dim_ordering': 'tf', 'b_constraint': None, 'border_mode': 'valid'}}
{'class_name': 'Activation', 'config': {'activation': 'relu', 'trainable': True, 'name': 'activation_2'}}
{'class_name': 'MaxPooling2D', 'config': {'strides': (2, 2), 'trainable': True, 'name': 'maxpooling2d_1', 'pool_size': (2, 2), 'dim_ordering': 'tf', 'border_mode': 'valid'}}
{'class_name': 'Dropout', 'config': {'p': 0.25, 'trainable': True, 'name': 'dropout_1'}}
{'class_name': 'Flatten', 'config': {'trainable': True, 'name': 'flatten_1'}}
{'class_name': 'Dense', 'config': {'output_dim': 128, 'activation': 'linear', 'trainable': True, 'b_regularizer': None, 'init': 'glorot_uniform', 'W_regularizer': None, 'input_dim': 4608, 'b_constraint': None, 'name': 'dense_1', 'W_constraint': None, 'activity_regularizer': None, 'bias': True}}
{'class_name': 'Activation', 'config': {'activation': 'relu', 'trainable': True, 'name': 'activation_3'}}
{'class_name': 'Dropout', 'config': {'p': 0.5, 'trainable': True, 'name': 'dropout_2'}}
{'class_name': 'Dense', 'config': {'output_dim': 46, 'activation': 'linear', 'trainable': True, 'b_regularizer': None, 'init': 'glorot_uniform', 'W_regularizer': None, 'input_dim': 128, 'b_constraint': None, 'name': 'dense_2', 'W_constraint': None, 'activity_regularizer': None, 'bias': True}}
{'class_name': 'Activation', 'config': {'activation': 'softmax', 'trainable': True, 'name': 'activation_4'}}
重みの出力

hd5形式で出力できる。

# save model
model.save('output/cnn.h5')

HD5のViewerで見るといい感じ