前回で、データを読み込み、DLのモデルを DigitsChainクラスとして定義した。
今回は、このDigitsChainクラスよりモデルを作り、読み込んでいたデータを使って、学習とテストをやってみる。
実際のプログラムは以下のようになる。
# 学習モデルの初期化
model = DigitsChain() # モデルの生成
optimizer = optimizers.SGD()
optimizer.setup(model)
# 学習ループ
for i in range(10000):
x = Variable(xtrain)
y = Variable(ytrain)
model.zerograds()
loss = model(x,y) # lossを求める (forward)
loss.backward() # 微分(backward)
optimizer.update() # 調整
# Testデータで学習成果を確認する
xt = Variable(xtest, volatile='on') # 学習不要
yy = model.fwd(xt)
ans = yy.data
nrow, ncol = ans.shape
ok = sum([np.argmax(ans[i,:])==yans[i] for i in range(nrow)])
print( ok, "/", nrow, " = ", (ok * 1.0)/nrow ) # 正解率
これって、Irisのときと同一に見えるはずだ。
たった1行違うだけ。
model = DigitsChain() # モデルの生成
つまり、粗い手書き文字用に作ったDigitsChainクラスのオブジェクトを作って、前と同じ変数modelに与えている。
今回の変更は1行、それ以前の変更も数行であり、全体で10行も変更していない。
というか、変更する必要がありそうなところが見つからない。
さて、とりあえず動かしてから考えよう。
Chainer$ python3 digits0.py
546 / 599 = 0.911519198664
Chainer$
テスト結果は91.15%の正解率で、ちゃんと動いているようだ。
IrisからDigitsへの変更は、同じクラス分けタイプのデータを使ってクラス分けしたので、僅かな変更で済んだ。
4種のデータからなるIrisと、8×8の画像データからなるDigitsが、ほぼ同じプログラムで動いてしまうのだ。
この適応性の高さは恐ろしいほどだ。