cBlog

Tips for you.

ゼロから作るDeep Learning読むお( ^ω^) #4

前回までの「ゼロから作るDeep Learning読むお( ^ω^)」

yaritakunai.hatenablog.com

 

まずは今更ですが

ソースコードの文字コードについて

この本がGitHubで配布しているソースコードには、1行目にこう書いてある。

# coding: utf-8

これはどの文字コードで書かれているのかインタープリタに伝えるためで、ソースコードの1行目(shebangがあるときは2行目)に書く。

よく見かけるのはこちらだが、

# -*- coding: utf-8 -*-

coding: nameまたはcoding=nameが含まれている形式ならなんでもいいようだ。

Python 3ではデフォルトの文字コードがUTF-8になっているので、なくても動く。

 

参考

Unicode HOWTO — Python 3.5.2 ドキュメント

 

4章 ニューラルネットワークの学習(4.4節)

コードについて

gradient_2d.py
if __name__ == '__main__':

これまたよく見かける表記。

__name__は、スクリプトファイルとして実行されたときに'__main__'が代入される特別な変数。一方、インポートされたときはモジュール名が入る。

つまり、このブロックにはメインプログラムとして実行されたときだけ動作すべきコードが書いてある。

 

参考

if __name__ == '__main__': について - へたれプログラマな日々

 

2次元プロットに使うnp.meshgrid()の技法がわかりにくかったので追ってみる。

>>> x0 = np.arange(-2, 2.5, 1)  # 1刻みに変更
>>> x0
array([-2., -1.,  0.,  1.,  2.])
>>> x1 = np.arange(-2, 2.5, 1)
>>> x1
array([-2., -1.,  0.,  1.,  2.])
>>> X, Y = np.meshgrid(x0, x1)
>>> X
array([[-2., -1.,  0.,  1.,  2.],
       [-2., -1.,  0.,  1.,  2.],
       [-2., -1.,  0.,  1.,  2.],
       [-2., -1.,  0.,  1.,  2.],
       [-2., -1.,  0.,  1.,  2.]])
>>> Y
array([[-2., -2., -2., -2., -2.],
       [-1., -1., -1., -1., -1.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.]])

np.meshgrid()を使うとX[x, y]Y[x, y]の組み合わせで平面上の座標を表せることがわかる。

次に、plt.quiver()に渡すためにXYを1次元に潰す。

>>> X = X.flatten()
>>> X
array([-2., -1.,  0.,  1.,  2., -2., -1.,  0.,  1.,  2., -2., -1.,  0.,
        1.,  2., -2., -1.,  0.,  1.,  2., -2., -1.,  0.,  1.,  2.])
>>> Y = Y.flatten()
>>> Y
array([-2., -2., -2., -2., -2., -1., -1., -1., -1., -1.,  0.,  0.,  0.,
        0.,  0.,  1.,  1.,  1.,  1.,  1.,  2.,  2.,  2.,  2.,  2.])
>>> np.array([X, Y])
array([[-2., -1.,  0.,  1.,  2., -2., -1.,  0.,  1.,  2., -2., -1.,  0.,
         1.,  2., -2., -1.,  0.,  1.,  2., -2., -1.,  0.,  1.,  2.],
       [-2., -2., -2., -2., -2., -1., -1., -1., -1., -1.,  0.,  0.,  0.,
         0.,  0.,  1.,  1.,  1.,  1.,  1.,  2.,  2.,  2.,  2.,  2.]])

np.array([X, Y])の0行目はx0座標を、1行目はx1座標を表す。

numerical_gradient()内にあるenumerate()は、各要素に分解するとともにインデックスを付ける関数である。

ちなみに、このコードはplt.legend()があるのでエラーが出る。

 

gradient_method.py
        x_history.append( x.copy() )

x.copy()としているのはオブジェクトの中身をappendしたいから(xだと値の参照)。

plt.plot( [-5, 5], [0,0], '--b')

は、(-5, 0)から(5, 0)に直線を引いている。--は破線、bblueを指定している。

同様に、oだとcircle点のプロット。

 

勉強メモ

  • 重みパラメータの更新は、損失関数の勾配方向に重みを更新する作業の繰り返し
  • 微分の代わりに、微小な値を与えたときの差分を利用した計算が数値微分
  • 数値微分によって損失関数の勾配を求めることが可能

 

感想

Pythonコードが私にとっては難しくなり、読むのがキツくなってきた。(クラスとか使ったことない。1ファイルで済むのしか書いたことない。)章ごとにコードも理解しようとするのではなく、全体を読んでDeep Learningの仕組みを理解してから、実装するにはどうすればいいか考えながら(独自に一から実装するつもりで)コードを読んだ方がいいのかもしれない。(大抵、人のコードを読むのは苦手。)

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装

ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装