読者です 読者をやめる 読者になる 読者になる

まんぼう日記

takataka's diary

MNIST の Logistic Regression Theano版

MNIST の Logistic Regression - まんぼう日記 のつづき.自分で書いてた Logistic Regression のコードを,Theano を使って書き直してみます.

 

関連記事:

 

Logistic Regression してみる - まんぼう日記 の logreg0122.py を,Theano 0.6 を使って書き直します.GPGPUはここでは考えません.いきなり完成形を示すよりは,どんな風に考えて作っていったか示す方が人の役に立ちそうな気がしたので,4段階に分かれてます.

 

2015-01-30 追記:Theano で Multi Layer Perceptron - まんぼう日記 に5段階目があります.プログラムを整理してよりすっきりさせました.

 

Version 1  とりあえず動くようにしてみる

とりあえず動くこと優先.

参考:

 

ソースはこちら:  logreg_theano0128v1.py & logreg_mnist0128v1.py

 

とりあえず動けばええとはいえ,theano0128v1では,データに対する出力を計算する部分( softmax ),負の対数尤度を計算する部分( negLL ),勾配を計算する部分( grad )の三つに分けて,grad は softmax と negLL を呼ぶ構造にしたかった(同じことを複数箇所に書くのはバグのもとやから)ので,こんなんにしてみました.T_hoge で theano.tensor.dmatrix などを受け取って出力シンボルを求める計算を記述して,Tfunc_hoge でそれに対応した theano.function を作る,って感じ.Tfunc_grad が,Theano の真骨頂である,symbolic な微分を自動で求めて関数作ってる部分です.

 

mnist0128v1 は,MNIST の Logistic Regression - まんぼう日記 の mnist0127 とほぼ同じ動作ですが,あっちでは i = 0 の時に1epoch学習した後の対数尤度や誤識別率を表示してて変やったので,こっちでは i = 0 の時には一度も学習してない(パラメータが初期値のまま)時点での値を表示するように直してあります.

 

実行結果はこんなん:

### training:   NL =  50000 NV =  10000  D =  784  K =  10  batchsize =  1000
0 2.31660467932 90.366 90.69
10 0.309808738215 8.596 8.18
20 0.287221831739 8.006 7.72
30 0.278583830839 7.796 7.61
40 0.270594330435 7.57 7.36
50 0.265719866209 7.382 7.24
60 0.26200883933 7.236 7.2
70 0.259776793529 7.23 7.27
80 0.257140946168 7.172 7.31
90 0.255506273611 7.1 7.23
100 0.253509908629 7.03 7.09
### test:   NT =  10000
100 0.268935967478 7.03 7.09 7.57

自前のプログラムの時と微妙に値が違うのは,繰り返し回数が1回ずれてるせいかな.

 

Version 2  クラス化

クラスにして,パラメータ W と b はインスタンス変数とするように改良.

ソースはこちら:  logreg_theano0128v2.py & logreg_mnist0128v2.py

実行結果は v1 と全く同じなので省略.

 

Version 3  共有変数を使うようにする

さらに,W と b を Theano の shared variable とするように改良.今の所 v2 と違わなさそうですが,GPU 使う場合等はそうした方が効率がよいらしいので.

参考:

ソースはこちら:  logreg_theano0128v3.py & logreg_mnist0128v3.py

実行結果はやぱし v1 と全く同じなので省略.

 

Version 4  慣性項を追加してみる 

ついでに,慣性項を追加してみることにします.

\begin{align} \Delta w & \leftarrow -\eta \frac{\partial E}{\partial w} + \mu \Delta w \\ w & \leftarrow w + \Delta w\end{align}

てな感じで.

参考: "Neural Networks for Pattern Recognition" by Christopher M. Bishop - ブクログ 7.5.2節

 

ソースはこちら:  logreg_theano0128v4.py & logreg_mnist0128v4.py

実行結果はこんなん.\( \mu = 0.8 \) です.

### training:   NL =  50000 NV =  10000  D =  784  K =  10  batchsize =  1000
0 2.31660467932 90.366 90.69
10 0.268851914937 7.466 7.5
20 0.255575513098 7.14 7.17
30 0.251016552684 7.078 7.19
40 0.244067230428 6.81 6.99
50 0.242250866431 6.672 7.19
60 0.239362571994 6.684 6.95
70 0.237671531305 6.652 6.96
80 0.234112554851 6.52 7.03
90 0.235349472422 6.536 7.11
100 0.235323919271 6.528 7.24
# NT =  10000
100 0.27820580727 6.528 7.24 7.72

ちなみに nepoch を 40/60 にしてみたら,

# NT =  10000
40 0.268985562654 6.81 6.99 7.52
60 0.271530866005 6.684 6.95 7.58

でした.

 

 

やれやれ,10月に Pylearn2 の tutorial でお勉強 - 5時間目 - まんぼう日記 に書いたことがようやく動き出せるようになりました.