雑多な趣味の記録帳

tom01h.exblog.jp

タグ:ニューラルネット ( 52 ) タグの人気記事

Cora の tiny-dnn をプロファイル

前に zero-riscy に BNN 命令を追加したときの失敗 を繰り返さないために、今回はプロファイルをとってみます。
といっても何等かツールを使うわけでもなく、せっかくの綺麗なプログラムをグローバル変数で汚しています。

使っているネットを再度挙げると↓の感じです。
nn << conv(28, 28, 5, 1, 6, padding::valid, true, 1, 1, backend_type)
<< max_pool(24, 24, 6, 2)
<< relu()
<< conv(12, 12, 5, 6, 16, padding::valid, true, 1, 1, backend_type)
<< max_pool(8, 8, 16, 2)
<< relu()
<< conv(4, 4, 4, 16, 10, padding::valid, true, 1, 1, backend_type)
<< softmax(10);

階層の種類ごと、順伝搬と逆伝搬の時間を計ってみました。
pool forward 5549ms elapsed
activ forward 331ms elapsed
cov forward 72249ms elapsed
activ back 588ms elapsed
pool back 2120ms elapsed
cov back 155182ms elapsed
Epoch 1/1 finished. 241.665s elapsed.

グラフにするとこんな感じです。
f0054075_21460647.png

[PR]
by tom01h | 2018-07-14 22:59 | Trackback | Comments(0)

Cora の Petalinux で Hello World と tiny-dnn

Cora Z7 で Petalinux が起動できたので、アプリケーションソフトを動かしてみたいと思います。
参考にしたのは ここ 。まずは Hello World から試します。
ホストOS で
$ arm-linux-gnueabi-gcc hello.c -g -o hello -static
Petalinux を入れた SD カードに hello をコピーして
root@Cora-Z7-07S:~# mount /dev/mmcblk0p1 /mnt/
root@Cora-Z7-07S:~# /mnt/hello
Hello Zynq World!!
次は、調子に乗って tiny-dnn を試してみましょう。
まずはホストOSでコンパイルしますが、その前に tiny_dnn/config.h の #define CNN_SINGLE_THREAD を有効にします。そして、
[追記 FPUを使うために ”-mfpu=neon -mtune=cortex-a9 -mcpu=cortex-a9 -mfloat-abi=softfp” を追加する]
$ arm-linux-gnueabi-g++ -O3 -mfpu=neon -mtune=cortex-a9 -mcpu=cortex-a9 -mfloat-abi=softfp -Wall -Wpedantic -Wno-narrowing -Wno-deprecated -DNDEBUG -std=gnu++14 -I ../../ -DDNN_USE_IMAGE_API train.cpp -o train -static
train と data/ を SD カードにコピーして、
root@Cora-Z7-07S:~# mount /dev/mmcblk0p1 /mnt/
root@Cora-Z7-07S:~# /mnt/train --data_path /mnt/data/ --learning_rate 1 --epochs 3 --minibatch_size 16 --backend_type internal
これは… 遅いなんてもんじゃない。667MHz じゃないのかよ~
Intel の 100 倍遅いじゃないか(--)
[追記 FPU を使ったら 5倍速くなった。けど Intel の 20倍遅い…]
f0054075_23384691.png
これ、FPGA にオフロードしようと思ったけど、よく考えたら物理アドレス分からないんだねぇ。PL からアプリの配列を触ったりはできないのか。PS からデータをくべるしかないのかな? 7 世代の Zynq は PL から PS には HP ポートあるけど、PS から PL は GP ポートしかないんじゃなかったっけ?

[PR]
by tom01h | 2018-07-13 21:40 | Trackback | Comments(0)

tiny-dnn 試行2

C++ 言語で記述されたニューラルネットのフレームワークの tiny-dnn を試しています。
これ、とりあえず動くようになりましたが、Intel CPU で動かしてもとっても遅いです。
$cd examples/mnist
$ g++ -pthread -Wall -Wpedantic -Wno-narrowing -Wno-deprecated -O3 -DNDEBUG -std=gnu++14 -I ../../ -DDNN_USE_IMAGE_API train.cpp -o train
$ ./train --data_path ../../data/ --learning_rate 1 --epochs 3 --minibatch_size 16 --backend_type internal
MNIST ごときに 60000 の学習データは必要ないので、20000 に減らします。
train_labels.resize(20000);
train_images.resize(20000);
当たり前ですが、だいたい3倍速くなります。
次に tanh を relu,sontmax に変更して、LeNet 特有の良く分からない connection_table を無しにします。打ち消しあったのか、速くなりません。併せて learning_rate 0.3 にすると、学習データを 20000 にして下がった分の認識率が元に戻ります。
次に、pooling を max pooling に変更して、層も1層減らすと全部で 5倍速くなりました。
さらに、入力データのパディングをやめて learning_rate 1 に戻すと、まだちょっとだけ速くなります。
nn << conv(28, 28, 5, 1, 6, padding::valid, true, 1, 1, backend_type)
<< maxpool(24, 24, 6, 2)
<< relu()
<< conv(12, 12, 5, 6, 16, padding::valid, true, 1, 1, backend_type)
<< maxpool(8, 8, 16, 2)
<< relu()
<< conv(4, 4, 4, 16, 10, padding::valid, true, 1, 1, backend_type)
<< softmax(10);
これくらい速くなるといろいろ試せますかね?
[PR]
by tom01h | 2018-07-10 22:34 | Trackback | Comments(0)

tiny-dnn

C++ 言語で記述されたニューラルネットのフレームワークの tiny-dnn を試してみようと思います。
まずはお試しにと思って MNIST の例題をコンパイルしてみようと思ったけど、エラーでコンパイルできない…
どうすんのこれ?と思って途方に暮れていると、Beginner's guide 発見。
書いてある通りに
$ mkdir build
$ cd build
$ cmake -DBUILD_EXAMPLES=ON ..
Makefile が出来た。いっぱいコンパイルするのも大変なので
$ make example_mnist_train
$ cd examples
$ ./example_mnist_train --data_path ../../data/ --learning_rate 1 --epochs 3 --minibatch_size 16 --backend_type internal
なんか動いた。でも、何でも自動でやってくれて、便利なんだけどわけわからないです。下のようなファイルがあったので参考に
build/examples/CMakeFiles/example_mnist_train.dir/flags.make
examples/mnist で直接↓でも出来ました。
$ g++ -pthread -msse3 -mavx -Wall -Wpedantic -Wno-narrowing -Wno-deprecated -O3 -DNDEBUG -std=gnu++14 -I ../../ -O3 -DCNN_USE_AVX -DCNN_USE_SSE -DDNN_USE_IMAGE_API train.cpp -o train
ちなみに、WSLのUbintu上の話です。
f0054075_12174370.png

[PR]
by tom01h | 2018-07-08 23:59 | Trackback | Comments(0)

アクティベーションの精度も下げる

ウェイトに続いてアクティベーションの精度も8bit整数に落としてみました。普通は推論時の演算精度を8bitに落とすことは学習時には考えないのかもしれませんが、ここでは、バイナリニューラルネットと同じように、学習時も順伝搬では8bit精度を扱います。なんでか分かりませんが、ウェイトだけ8bitにした時よりも認識精度が高いようです。
学習時に8bit化の準備をしておくと、推論プログラムに移植した時にバグなのか単なる精度低下なのか悩まなくて済みます。でも、固定少数をどこに置くか?学習率はいくつにするか?など、学習時の悩み事は増えます。
f0054075_02482775.png
もっと速いPCがあると良いのになぁ。

[PR]
by tom01h | 2018-06-25 02:52 | Trackback | Comments(0)

ウェイトの精度を下げる

ウェイトの精度を8bit整数とバイナリ{-1,1}にした時に、認識精度がどこまで下がるか実験してみました。
学習は水増しなし、蒸留ありでやっています。
8bit整数にすると1~2%の低下です。バイナリにすると3~4%の低下でした。
バイナリの方は、以前使っていたネットワークと同じような感じでしょうかね。
f0054075_21554340.png
次回はアクティベーションの精度を下げた実験をしたいと思います。

[PR]
by tom01h | 2018-06-18 23:16 | Trackback | Comments(0)

蒸留学習

以前 1度試してみたことがあるのですが、あまり分かりやすい結果が出ませんでした。
大雑把にいうと、いまいちな教師データで変な癖がつかないように?、自分より賢い学習済みのネット(教師ネット)の出した判断結果を教師データとして使った学習法です。
今回は水増しで学習したネットを教師ネットとします。
f0054075_17074444.png
水増しなしの学習で、蒸留なしで学習した時と、蒸留ありで学習した時を比較しました。
蒸留ありで学習すると、水増しありで学習した教師ネットと同じ精度を出すところまで行きました。
f0054075_17204961.png
先日書いた 100% に張り付いていた Train Accuracy というのはうそでした…

[PR]
by tom01h | 2018-06-17 19:58 | Trackback | Comments(0)

基本ネットワークの変更

バイナリニューラルネットで遊び始めたころはあまり良く分かっていなかったこともあって、全結合層のパラメータがとってもたくさんある構成になっていました。多分層間のバランスが悪いのは良くないのかと思い、ベースにするネットの構成を見直そうと思います。こんな感じ。
f0054075_19020293.png
で、学習させてみたのですが、Test Accuracy は 80% くらいで打ち止めです。多分テストデータが足りなくて過学習なのでしょうね。というわけで、水増しとかも取り入れて、学習方法も見直してみました。100% に張り付いていた Train Accuracy は下がりましたが Test Accuracy はあまり上がりません。下は、今まで使っていたネット(左)と新しいネット(右)の比較です。
f0054075_21462590.png
精度は微妙に上がっていますがパラメタ数は半分くらいに減っています。計算時間は倍増しました。

[PR]
by tom01h | 2018-06-14 20:53 | Trackback | Comments(0)

Google MobileNet V1/V2 について

バイナリニューラルネット (BNN) アクセラレータの実装も落ち着いてきたので、そろそろベンチマークのネットワークを更新したいと思っています。というのも、今使っているネットワークでは全結合層で使うパラメータの数がとっても多くなってしまっているためです。
そんなわけで、参考にならないかと思って Google の MobileNet とその V2 の論文を読んでみました。隅々まで読んだわけじゃないけど。
内容については他の方の要約 ( V1 V2 ) に譲るとして、さすが Google さん。つぶしのきかない BNN と違って、あくまで行列乗算での軽量化にこだわるのを見ると完敗した気分です。
で、V2 の方のボトルネック。BNN が活性化後にデータ量がぐっと減るのと同じで、ボトルネックでデータ量を減らしてきます。多分、ボトルネック間を一気に計算することで、中間データ用メモリのサイズを小さく出来るのだと思います。論文の Memory efficient inference には難しいことが書いてあって理解できませんが…
話がそれた。最後の方のアベレージプーリングが肝なのかと思います。

[PR]
by tom01h | 2018-06-12 00:12 | Trackback | Comments(0)

zero-riscy の Matrix Mult 命令をパイプライン処理したい2

zeroriscy の Matrix Mult 命令をパイプライン化しています。
この命令はコンパイラ対応していないので、正直いって検証がずぶずぶになってしまいます。
でも、思いつく限りはストール制御を入れておきたいと思います。変更点は
  1. 命令デコーダのマルチサイクル命令判定部分から mmult命令を削除
  2. mmult ユニットをパイプライン化
  3. WB ステージで待たされているレジスタアドレスの数を増やす
  4. mmult 命令が完了したけど EX ステージに負けてレジスタ書き込みできないときにストール
  5. mmult 命令実行中はロードストア命令を発行しない
4と5が思いついたストール条件です。他にもありそうなら教えてください。
github 更新しました。


[PR]
by tom01h | 2018-06-11 00:31 | PCとか | Trackback | Comments(0)