【Chainer基礎最終】15分で組んでみよう。はじめてのChainerを解説

【Chainer基礎最終】15分で組んでみよう。はじめてのChainerを解説

どん

 

どどん

 

ドーーーーーーン

注意:このエラーは、作業時間3時間中に発生したごく一部のものです。

 

 

かかった・・・今回のチャレンジは時間がかかった・・・

エラーエラーエラーれらー

失敗の雨あられ。いや、もはや暴風雨

「テンペスト・オブ・エラー」ですよ。

途中で放棄して「乃木坂工事中」見てましたよ。生ちゃんかわいい。

プログラマーの方々は日々こんな苦労をしてるんだろうとしみじみ感じてしまいました。乃木中見ながら。

あ、どもアイーンです。

 

今回は、開発環境をSpyderに変更して作業を行います。

理由はエラーです。お察しください。

SpyderはAnaconda3を導入したときに同時に入ってます。

みなさんも今回はSpyderを使ってみてください。

 

さて、今回は、まずコードを全て載せておきます。

ババン

import chainer
from chainer import Variable, Chain, optimizers
import chainer.links as L
import chainer.functions as F
import numpy as np
import matplotlib.pyplot as plt

x, t = [ ], [ ]
for i in np.linspace(-1, 1, 100):
    x.append([i])
    if i < 0:
        t.append([0])
    else:
        t.append([1])

class chain1(Chain):
    def __init__(self):
        super(chain1, self).__init__(
            l1=L.Linear(1, 10),
            l2=L.Linear(10, 1),
        )

    def predict(self, x):
        h1 = F.sigmoid(self.l1(x))
        return self.l2(h1)


x = Variable(np.array(x, dtype=np.float32))
t = Variable(np.array(t, dtype=np.float32))

model = chain1()

opt = chainer.optimizers.Adam()
opt.setup(model)


y = None
for i in range(100000):

    model.cleargrads()
    y = model.predict(x)

    if i%10000 == 0:
        plt.plot(x.data.flatten(), y.data.flatten())
        plt.title("i = " + str(i))
        plt.show()

    loss = F.mean_squared_error(y, t)
    loss.backward()

    opt.update()

plt.plot(x.data.flatten(), y.data.flatten())
plt.title("Last")
plt.show()

 

さぁ、ここまで着いてこれた方は、一目見てもうお気づきになれませんね。僕もです。

ここでは、「ステップ関数」をディープラーニングで作ってみたいと思います。

 

ステップ関数とは?

ステップ関数とは、ある閾値を超えた入力があった場合、1を出力

それ以外は0を出力するとっても単純な関数です。

こんな感じ。

 

深層学習でステップ関数つくってみた

まずはimport

 

import chainer
from chainer import Variable, Chain, optimizers
import chainer.links as L
import chainer.functions as F
import numpy as np
import matplotlib.pyplot as plt

 

最終行は、matplotlibというグラフを描くためのimportです。

グラフと、記述方法はのちほど。

 

それでは、

x, t = [ ], [ ] 
    for i in np.linspace(-1, 1, 100):
        x.append([i])
        if i < 0:
            t.append([0])
        else:
            t.append([1])

 

xtというリストを作り、繰り返し処理で

xにテストデータ、tに正解データを入れていきます。

for文で使われているnp.linspace()という処理は

「-1から1の間で100回分、等差数列を作るよ」

「等差数列とは、だんだんと同じ数字を足してったものだよ」

5,7,9,11,13,15・・・

コレは、5にだんだん2を足していった等差数列です。

xの中には

          [-1.        ],
          [-0.97979796],
          [-0.959596  ],
          [-0.93939394],
          [-0.9191919 ],
          [-0.8989899 ],
          [-0.8787879 ],
          [-0.85858583],
          [-0.83838385],
          [-0.8181818 ],
          [-0.7979798 ],
          [-0.7777778 ],
          [-0.75757575],
          [-0.7373737 ],
          [-0.7171717 ],
          [-0.6969697 ],
      ・
      ・
      ・
          [ 0.8989899 ],
          [ 0.9191919 ],
          [ 0.93939394],
          [ 0.959596  ],
          [ 0.97979796],
          [ 1.        ]

こんな数が100個入ってます。これがテストデータ。

tには

 [0],
 [0],
 [0],
 [0],
 [0],
 [0],
 [0],
 [0],
 [0],
 [0],
 [0],
 [0],
 [0],
・
・
・
 [1],
 [1],
 [1],
 [1],
 [1],
 [1],
 [1],
 [1],
 [1],
 [1],
 [1]

xの中身が0より小さい場合、tに0、大きければtに1が入るように

データが入っています。

.append()を使ったリストの追加処理はこんな感じです。

 

さぁ、テストデータと正解データの準備は完了

次は、ニューラルネットワークの構造を書いていきましょう。

 

class chain1(Chain):
  def __init__(self):
   super(MyChain, self).__init__(
    l1=L.Linear(1, 10),
    l2=L.Linear(10, 1),
   )

  def predict(self, x):
    h1 = F.sigmoid(self.l1(x))
    return self.l2(h1)

Chainクラスを継承して

l1には入力1個、出力10個

l2には入力10個、出力1個

のLinearを準備します。

 

predictには、入力されたリストにシグモイド関数を掛けて

出てきた数値をl2へ引き渡す処理です。

 

次はxtをVariableオブジェクトに変換します。

x = Variable(np.array(x, dtype=np.float32))
t = Variable(np.array(t, dtype=np.float32))

 

そして、optimizerをChainインスタンスにくっつけましょう。

model = chain1()

optimizer = chainer.optimizers.Adam()
optimizer.setup(model)

今回は、Adam()という最適化アルゴリズムを使用します。

なんか、最近ではおススメのアルゴリズムだそうです。

パフォーマンスがすごいとかなんとか。

いつか解説できたらいいね~^-^;

 

これでニューラルネットワークの構造は完成です。

ここから実行する処理の内容を書きます。

y = None
for i in range(100000):

  model.cleargrads()
  y = model.predict(x)

  if i%10000 == 0:
   plt.plot(x.data.flatten(), y.data.flatten())
   plt.title(“i = ” + str(i))
   plt.show()

  loss = F.mean_squared_error(y, t)
  loss.backward()

  opt.update()

出力yに初期値Noneを入れておきましょう。

for文で、10万回の繰り返し処理を書きます。

model.cleargrads()で勾配(微分値)を毎回初期化し

y = model.predict(x)でニューラルネットワークにxをぶち込み、yに出力処理を行います。

if文には、1万回に一回グラフを描写する処理を書いて、途中経過が見れるようにしましょう。

 

plt.plot(x.data.flatten(), y.data.flatten())
plt.title(“i = ” + str(i))
plt.show()

1行目でx.datay.dataを取ってきてグラフ化

2行目でタイトルを付けて

3行目でグラフを表示します。

 

最後は、損失関数を使って出力yと正解tの誤差を求めて、次の学習時に重みとバイアスが変更されるようにします。

loss = F.mean_squared_error(y, t)

ここでは二乗平均誤差を使います。

loss.backward()

この処理で誤差との勾配が求められます。

opt.update()

最後に、求めた勾配を使って重みとバイアスを更新します。

 

おまけとして、最後の学習結果が表示されるように

plt.plot(x.data.flatten(), y.data.flatten())
plt.title(“Last”)
plt.show()

を一番最後に書けば完成です。

それでは、実行してみましょ~

 

実行してみた:ステップ関数ディープラーニング

0回目:

ア「さて始まりましたディープラーニング、司会のアイーンです。これはまだ学習を一切行っていないたるみきった豚のような身体(データ)です。これが一体どう変わっていくのでしょうか、お楽しみに!」

1万回目:

ア「ここで初動を開始しましたね~。しかしゆるみきったわがままボディは未だボヨンボヨンです」

 

2万回目:

ア「おおっと!!ここで中央に急激な変化を感じさせる上昇線が見えてきました!上昇線の初めと終わりには取り切れていないぜい肉が見えていますが、今後の展開が期待できます」

 

3万回目:

ア「鋭くシャープになってきましたね~、まるで若い頃のアイーンのようです。」

 

ア「いいですね、変化してますね~」

 

ア「変わってきた変わってきた」

 

ア「いいね~・・・」

 

ア「・・・」

 

ア「(youtube:やっぱバナナマンはトークだな。)オカンお茶まだ~?」

 

ア「(流れ星ウケるw)・・・え?なに?もう終わるって?」

 

10万回目:

ア「素晴らしいですね~、中央のダブつきは少し残っているようですが、15万回も実行すれば完璧なステップ関数するのではないでしょうか。本日の実況は、わたくしアイーンがお届けしました。See You Next Time!」

 

いかがでしたでしょうか。

最小限の手数でディープラーニングの体験が出来たと思います。

これでChainerの基礎知識は固まったのではないでしょうか。

 

15分で作るディープラーニングを書くのに3時間かかったことも、今となってはいい思い出でしょう。

そうに違いありません。

間違くなく。

 

 

それでは