(前回の続きです)

※tflearnの参考ページ
http://tflearn.org/getting_started/

 

前回は全結合型ネットワークを試してみましたが、今回は畳み込みネットワークを試してみます。
畳み込みネットワークは主に画像処理に利用されるので、画像を扱うことの多い生物学関係での応用が期待されます。

まず、中間層で畳み込みニューラルネットワークを試してみました。
以下は、Pythonソースコードのサンプルです。

――― 畳み込みニューラルネットワーク(CNN)のソース

## パラメータは適当に設定しています。
## 学習時間が長いので学習結果を再利用できるように保存処理を追加しました。
import numpy as np
import datetime as dt
import tensorflow as tf
import tflearn as tfl

## データダウンロード
trainX, trainY, testX, testY = tfl.datasets.mnist.load_data(‘./data/mnist/’, one_hot=True)
trainX = trainX.reshape([-1, 28, 28, 1])
testX = testX.reshape([-1, 28, 28, 1])

## 初期処理 28×28のモノクロ画像
tf.reset_default_graph()
net = tfl.input_data(shape=[None, 28, 28, 1])

## 中間層1
## 畳み込み層 フィルタ数34 サイズ7 活性化 ReLU
## ゼロパディング、スライド1
net = tfl.layers.conv.conv_2d(net, 34, 7, activation=’relu’)
##プーリング層 プーリング領域3
net = tfl.layers.conv.max_pool_2d(net, 3)

## 全結合
net = tfl.fully_connected(net, 68, activation=’relu’)
net = tfl.dropout(net, 0.5)

## 出力層
net = tfl.fully_connected(net, 10, activation=’softmax’)
net = tfl.regression(net, optimizer=’sgd’, learning_rate=0.5, loss=’categorical_crossentropy’)

## 学習
time1 = dt.datetime.now();
model = tfl.DNN(net)
model.fit(trainX, trainY, n_epoch=20, batch_size=100, validation_set=0.1, show_metric=True)
time2 = dt.datetime.now();

## 学習結果を保存
savepath = ‘./data/mnist/model1.ckpt’
model.save(savepath)
print(‘結果保存’)
print(savepath)

## テスト
time3 = dt.datetime.now();
result = model.predict(testX)
time4 = dt.datetime.now();

## 結果表示
print(‘学習時間’)
print(‘start:’ + str(time1))
print(‘end:’ + str(time2))
print(‘テスト実行時間’)
print(‘start’ + str(time3))
print(‘end’ + str(time4))

pred = np.array(result).argmax(axis=1)
label=testY.argmax(axis=1)

print(‘精度’)
accuracy = np.mean(pred == label, axis=0)
print(accuracy)

――― 実行結果

結果保存
./data/mnist/model1.ckpt
学習時間
start:2018-02-12 14:35:23.470289
end:2018-02-12 15:29:51.263895
テスト実行時間
start2018-02-12 15:29:51.421936
end2018-02-12 15:30:01.542453
精度
0.9888

全結合型よりもだいぶ学習時間がかかっていますが、制度は少し良い結果がでました。
次は、保存された学習結果を読み出しで利用するソースです。

――― 保存された学習結果を読み出して実行するソース

import numpy as np
import datetime as dt
import tensorflow as tf
import tflearn as tfl

## データダウンロード(テスト用)
trainX, trainY, testX, testY = tfl.datasets.mnist.load_data(‘./data/mnist/’, one_hot=True)
trainX = trainX.reshape([-1, 28, 28, 1])
testX = testX.reshape([-1, 28, 28, 1])

## 初期処理 28×28のモノクロ画像
tf.reset_default_graph()
net = tfl.input_data(shape=[None, 28, 28, 1])

## ネットワークの定義
## 中間層1
## 畳み込み層 フィルタ数34 サイズ7 活性化 ReLU
## ゼロパディング、スライド1
net = tfl.layers.conv.conv_2d(net, 34, 7, activation=’relu’)
##プーリング層 プーリング領域3
net = tfl.layers.conv.max_pool_2d(net, 3)

## 全結合
net = tfl.fully_connected(net, 68, activation=’relu’)
net = tfl.dropout(net, 0.5)

## 出力層
net = tfl.fully_connected(net, 10, activation=’softmax’)
net = tfl.regression(net, optimizer=’sgd’, learning_rate=0.5, loss=’categorical_crossentropy’)

## 学習結果を読み込み
model = tfl.DNN(net)
loadpath = ‘./data/mnist/model1.ckpt’
model.load(loadpath)
print(‘学習結果の読み込み’)
print(loadpath)

## テスト
time3 = dt.datetime.now();
result = model.predict(testX)
time4 = dt.datetime.now();

## 結果表示
print(‘テスト実行時間’)
print(‘start’ + str(time3))
print(‘end’ + str(time4))

pred = np.array(result).argmax(axis=1)
label=testY.argmax(axis=1)

print(‘精度’)
accuracy = np.mean(pred == label, axis=0)
print(accuracy)

――― 実行結果
学習結果の読み込み
./data/mnist/model1.ckpt
テスト実行時間
start2018-02-12 18:27:53.449303
end2018-02-12 18:28:01.692120
精度
0.9888

もう少し制度を上げるために中間層を2層にしてみます。
ネットワークの構成で2層目を追加しました。

――― 畳み込2層のソース(一部抜粋)

## 中間層1
## 畳み込み層 フィルタ数34 サイズ7 活性化 ReLU
## ゼロパディング、スライド1
net = tfl.layers.conv.conv_2d(net, 34, 7, activation=’relu’)
##プーリング層 プーリング領域3
net = tfl.layers.conv.max_pool_2d(net, 3)

## 中間層2
## 畳み込み層 フィルタ数68 サイズ 7 活性化 ReLU
## ゼロパディング、スライド1
net = tfl.layers.conv.conv_2d(net, 68, 7, activation=’relu’)
##プーリング層 プーリング領域3
net = tfl.layers.conv.max_pool_2d(net, 3)

## 全結合
net = tfl.fully_connected(net, 136, activation=’relu’)
net = tfl.dropout(net, 0.5)

――― 実行結果
学習時間
start:2018-02-12 15:39:55.144169
end:2018-02-12 17:53:44.195134
テスト実行時間
start2018-02-12 17:53:44.326100
end2018-02-12 17:54:05.020110
精度
0.9937

2層にして学習時間が2時間以上かかっていますが、精度が上がっています。
この結果では1000文字中6文字程度のミスが発生することになりますが、
人間が目で見てもこの程度のミスはありそうなので、とりあえず今回はこの程度で良しとします。

今回は練習用でしたが、実用的な利用では目的に応じて手法を選ぶ必要があります。
例えば、タブレットPCの手書き入力では、レスポンス速度を重視して多少の精度は犠牲にする必要があるかもしれません。
例えば、申し込み書類の手書き文字を、サーバで一括処理して後日返信する場合は、速度よりも精度を上げる方が良いかもしれません。
など、さまざまな用途に応じた使い分け考えられます。

 

(S.Onda 2018/2/12)