あっぱれ日和、 - What a "Appare" day -

あっぱれ日和、 - What a "Appare" day -

通りすがりのしがない映画好きが綴る、モノづくりの記録や備忘録。そして、影響を受けた映画の記録。

機械学習初心者がDeep Learningを試してみる ~CNN(Convolutional Neural Network, またの名を畳み込みニューラルネットワーク) 後編、Let`s学習~

はじめに、

こんにちは!
今回はCNNをKerasを用いて実装してみます。また、本記事は後編となります。画像の取得、画像の前加工、またCNNとは何ぞやなどは前編に記載してあります。前編は以下のリンクから行けます。興味のある方は読んでみてください
apao-m-appare99.hatenablog.com

結論から言うと全然いい認識結果は得られませんでした。。。

本記事はあくまでも機械学習ど素人のエンジニアもどきである私の記録になります。

【目次】

実装環境

今回実装する環境に関してですが、以下のようになります。

モデルを作成する

さて、それでは早速モデルを作成していきましょう。
今回参考にさせていただいた記事は以下の記事になります。(というかほぼコピペです。。。)
qiita.com

とりあえずこのモデルでどこまでの学習ができるかを試したいと思います。
モデルの作成のコードは以下のようになります。コードについてはコメントアウトの部分も参考にしてみてください。

from keras.models import Sequential
from keras.layers.convolutional import MaxPooling2D
from keras.layers import Activation, Conv2D, Flatten, Dense,Dropout
from keras.optimizers import SGD, Adadelta, Adagrad, Adam, Adamax, RMSprop, Nadam
import time

model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same',input_shape=X_train.shape[1:]))
'''
Conv2D: 2次元畳み込み層
Conv2D(32, (3, 3)で3×3の32種類のフィルタを各ピクセルにかける

padding='same' : 出力画像のサイズが変わらないようにパディングを実施する(ゼロパディング)

'''

model.add(Activation('relu')) # 活性化関数ReLU
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(dense_size))
model.add(Activation('softmax'))

model.summary()

次にmodelのコンパイルの部分ですね。コードは以下のようになります。ここの部分で処理が終わるまで20分ほどかかりました。

optimizers ="Adadelta"
results = {}
epochs = 50
model.compile(loss='categorical_crossentropy', optimizer=optimizers, metrics=['accuracy'])
results= model.fit(X_train, y_train, 
                   validation_split=0.2,
                   epochs=epochs)

●補足:batch sizeの指定がしていませんが、していない場合デフォルトでbatch sizeは32になります。

TestとValidationの学習における推移を見てみる

コードは以下のようにして推移のプロットを見てみる

import matplotlib.pyplot as plt
%matplotlib inline

acc = results.history['accuracy']
val_acc = results.history['val_accuracy']
loss = results.history['loss']
val_loss = results.history['val_loss']

epochs = range(len(acc))

# 1) Accracy Plt
plt.plot(epochs, acc,label = 'training acc')
plt.plot(epochs, val_acc, label= 'validation acc')
plt.title('Training and Validation acc')
plt.legend()

plt.figure()

# 2) Loss Plt
plt.plot(epochs, loss,label = 'training loss')
plt.plot(epochs, val_loss, label= 'validation loss')
plt.title('Training and Validation loss')
plt.legend()

plt.show()

結果は以下のようになりました。
まずは精度
f:id:appare99:20200517131213p:plain
学習(青の曲線)はうまくできているっぽいですが、検証のグラフ(オレンジの曲線)は20%あたりで止まってしまっています。。。
そして損失も見てみましょう。
f:id:appare99:20200517131439p:plain
こちらも学習の方(青の曲線)はうまく損失が減っていますが、検証のグラフ(オレンジの曲線)は増加していっています。

評価

ボロボロの結果なので期待なんて皆無ですが、一応評価を行います。

score = model.evaluate(X_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

'''
■以下の結果が出力されます。
Test loss: 7.079138089258713
Test accuracy: 0.23274695873260498
'''

...。
......。
.........。
...はい、精度は23%ですね。37のカテゴリに分ける問題と考えるとランダムよりはだいぶましな結果といえますが、これは認識器としては使い物にはならないですね。。。

まとめ

はい、ということで、ほぼコピペのモデルでCNNを実装してみましたが、結果は惨敗となりました。
まあ、はじめからうまくいくなんて思っていません。
改善を行っていくつもりです。85%は超えたいなーー。すいません、今日は惨敗でしたが、次回はリベンジということでやっていきます。