RBM in Julia

一昨日Rで書いたRBMを使ってdeep learning tutorialで紹介されているMNIST手書き文字画像(観測ノード数はピクセル数と同じ784、訓練データが60000画像)のデータを食わせてみたら激しく遅いのでC++より書きやすくて実行効率もいいとうたっているJuliaで書き直してみました。

元のRのコードが動けばいいレベルだったこともあって2000倍以上速くなりました。Rのコードにも改善を少し反映し、ソース一式がGistに置いてあります。(元のコードに少しバグがあったのでそれも直して一昨日のブログエントリ中のコードも更新)

Julia版のダミーデータでの実行結果

init OK.
step 1 : err=0.48333333333333334
step 2 : err=0.4777777777777778
step 3 : err=0.4722222222222222
step 5 : err=0.4722222222222222
step 8 : err=0.4527777777777778
step 37 : err=0.44722222222222224
step 50 : err=0.4444444444444444
step 65 : err=0.4222222222222222
step 138 : err=0.4166666666666667
step 248 : err=0.4166666666666667
step 336 : err=0.4
["theta"=>Theta(4x3 Array{Float64,2}:
  0.0431936   0.0366259   0.0158433
 -0.0263127  -0.0249457  -0.0318039
 -0.0396297  -0.0404271  -0.0259556
  0.0352671   0.0358384   0.0274096,[0.7931471805599453,-0.27314355131420986,-0.27314355131420986,-0.12314355131420984],[-0.013569603640624033,-0.013700729830354374,-0.014453002676093538]),
"learn_info"=>"step 336 : err=0.4","reconstruct"=>reconstruct]

0	0	1	1
0	1	0	1
1	0	0	1
1	0	1	0
1	0	1	1
1	1	1	1
1	0	1	0
1	0	0	1
1	1	1	0

R版と同様に動いてます。

MNIST手書き文字画像データの実行結果

サンプルが動いたのでMNISTのほうもやってみたところ、自分のサブマシン(Core i3 2.4GHz, 8GB mem Win7 x64)で隠れノード100で訓練データ60000画像に対してCD1の1ステップを計算するのに12分くらいです。並列化を実装して、性能のいいマシンを使えばさらに速くなりそう。もろもろ完成したらAWSのHPCインスタンスを1時間くらい使ってやろうと思います。

以下、まとめなど

高速化関連メモ

  • なるべく添え字を消して行列演算で済ませてネイティブライブラリが使われるようにする
  • 同じ計算は2度やらない。数式だと良く見てないと気付かないことが結構ある感じ

Julia関連メモ

  • Juliaのベクトルは縦ベクトルなことに注意
  • テンソルスカラーは別扱い。ベクトルの要素数が1のときにスカラーにならないのに注意。
    • というかこれはRのほうが特別扱いなだけなんだけど
  • 要素どうしの演算なときはドット付きの演算子を使うこと
  • 配列を内包表現で作ると要素の型がAnyになるの注意(かなりハマった)
  • serialize/desializeで変数ダンプできるのが便利
  • JuliaStudio IDEとかもあって便利なんだけど起動がもうちょっと速くなってほしい。。

Juliaも慣れてきたのか、なかなか可愛くなってきました。

ピュアRと比較してアルゴリズム実装言語としては開発効率が変わらないように思うので、今後はこの手のアルゴリズムは最初からJuliaで書こうと思います。

今日はRBMの高速化に作業時間を使って多層化DBNまではたどり着けず。近日中にまた続きをやるつもり。