未分類

chainerに足し算のお勉強をさせてみた

今回は、深層学習 ディープラーニングのフレームワークchainerに足し算のお勉強をさせてみた。
で、勉強した後にテストをして正解が取れるかどうか確認してみようと。

環境
ubuntu 14.04
python 2.7系
chainer 1.17.0
CPUモード

なるべくわかりやすいように、コードは最小限で。
クラス名などはローマ字読みにして、さも付けました感を強調してみた。
コードが短い上に計算も単純なので、CPUモードで充分動かせる。
GPUを導入していないメモリ2G程度のショボPCでも使えるので、ちょこっと動かしたい方にもお勧めだ。

まずインポートは概ね下記が定番のようなので、きっちりと忘れずに。
後日、モデルを保存するので、serializersもインポートしておく。

[py]
import numpy as np
import chainer.functions as F
import chainer.links as L
from chainer import Variable, optimizers, Chain, serializers

[/py]

で、お勉強の足し算がこれ。
xに入力した2つのデータを足すと、教師ラベルであるtの答えになる。
例えば、xの[0,1]を足すとtの[1]が答えになる。

[py]
x=Variable(np.array([[0,1],[1,2],[2,3],[3,4]],dtype=np.float32))
t=Variable(np.array([[1],[3],[5],[7]],dtype=np.float32))

[/py]

ここがChainを継承したオリジナルのクラス、TasouModel()の所。
書き方も概ね定番なので、
initで初期化、今回は2入力の1出力なので、L.Linear(2,1)とする。
callには、やらせたいコードを記入。ここでは1層目にxを渡してリターンするだけ。

[py]
class TasouModel(Chain):
    def __init__(self):
        super(TasouModel, self).__init__(
            
            l1=L.Linear(2,1),
        )


    def __call__(self,x):
        h = self.l1(x)
        return h

[/py]

下記も定番。最適化にはSGDを採用した。
ちなみに、桁数を増やす際はAdamにした方が上手くいく。

[py]
model = TasouModel()
optimizer = optimizers.SGD()
#optimizer = optimizers.Adam()
optimizer.setup(model)

[/py]

下記がお勉強させている所。とりあえず100回ループでやってみる。
model.zerograds()で初期化して、
y=model(x) でモデルにxを与える。

loss=F.mean_squared_error(y, t) でyとtの誤差を出して
loss.backward() で逆伝播
optimizer.update() でパラメータ値を更新する

print “loss”,loss.data で誤差が減っていく様子を眺めて

print “y.data”,y.data でとりあえず計算が合っているかチェックする

[py]
for i in range(100):
    model.zerograds()
    y=model(x)
    loss=F.mean_squared_error(y, t)
    loss.backward()
    optimizer.update()
    
    print "loss",loss.data


print "y.data",y.data


[/py]

こんな感じで実行した結果がこれ。


loss 0.000531732861418
loss 0.00052492209943
loss 0.000518201501109
loss 0.000511576014105
loss 0.000505022529978
y.data [[ 0.96305263]
[ 2.98112226]
[ 4.99919176]
[ 7.01726151]]

lossのところの誤差が徐々に減っていくのがわかる。
で、yの値がほぼ1、3、5、7であるのがわかる。

100ループでこれなので、1000ループも回せばもっと正解に近づくはず。

じゃあ、やってみましょう。1000ループはこちら。


loss 5.18807041772e-07
loss 5.12161477673e-07
loss 5.05823720687e-07

y.data [[ 1.0011692 ]
[ 3.00059748]
[ 5.00002575]
[ 6.99945354]]

yの値がぱっちり正解。
lossの誤差も0.000000〜と、ほとんど0なのでこれもOK.

それでは最後にテストをしてみましょう。
chainer君、がんばってちょーだいな。

問題はこちら。
5と6、7と8、9と10をそれぞれ足して、正解が出せるかな。
下記のコードを最後に追加する。

[py]

xt=Variable(np.array([[5,6],[7,8],[9,10]],dtype=np.float32))
yt=model(xt)

print "yt.data",yt.data

[/py]

実行した結果がこれ。

yt.data [[ 11.00018406]
[ 15.00030804]
[ 19.00043106]]

11、15、19と、合ってますね。大正解です。

ん〜ん。マシンとはいえ、勉強させて正解が出た暁には、我が子のようにかわいいと思うから不思議だ。

えっ、これの何がすごいのかって?
まあ単純にchainer君に
1+2
を渡せば3を返してくれる。

しかーし。
今回のコードはどこにも「足せ」とは書いていない。
「+」記号も無し。
私は数字と答えを渡したのみだ。
あとはchainer君が勝手に正解を見つけだしたってこと。

ここがすごいんですねえ。
人間だって数字と答えだけで、計算方法わかりまっかってことだ。

さてさて、
今回はわかりやすさを念頭においたので、1層でのお勉強となったが、これを何層にも重ねていくと深層学習 ディープラーニングになる。

次回は、複数層重ねたやつを書きますかな。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です