ディープラーニングと言えばTensorFlowだのKerasだのChainerだの、高級なインタフェースを持ったツールを使うケースが多いが、例えばマイコンや組み込みプロセッサなどでディープラーニングを動かしたいときは、そこまで高級な機能はいらず、C++などで簡単に記述されたCNNの実装のほうが実行しやすかったりする。
というわけで、RISC-V上で(というかFPGA上などで動いている非力なプロセッサ)でCNNを動かすことができれば面白そうだ。 「ゼロから作るディープラーニング」を見ながら位置からC++で実装してもよいけど大変そうなので、とりあえず簡単なフレームワークは無いかと探して、mojo-cnnというC++のCNN実装を見つけた。
mojo-cnn を使ってCIFAR-10を動かしたい
さっそくgit cloneして動作させてみる。環境はUbuntu 18.04 LTS上にダウンロードして試行した。 MNISTはもう飽きてしまったのでCIFAR-10を使ってみたい。ちょうとmojo-cnnにもCIFAR-10を動かすための環境がある。
単純にcloneしてビルドすると以下のようにエラーが出る。
$ git clone https://github.com/gnawice/mojo-cnn.git $ cd mojo-cnn/example $ make g++ -I../mojo/ -std=c++11 -fopenmp -O3 -DMOJO_OPM -DMOJO_AVX -msse4 -mavx test.cpp -o test In file included from test.cpp:44:0: ../mojo/mojo.h:31:0: warning: "MOJO_AVX" redefined #define MOJO_AVX // turn on AVX / SSE3 / SIMD optimizations <command-line>:0:0: note: this is the location of the previous definition In file included from ../mojo/network.h:38:0, from ../mojo/mojo.h:78, from test.cpp:44: ../mojo/layer.h:41:10: fatal error: windows.h: No such file or directory #include <windows.h> ^~~~~~~~~~~ compilation terminated. makefile:7: recipe for target 'test' failed make: *** [test] Error 1
#include <windows.h>
を除去しても以下のようなエラーで進まない。
diff --git a/mojo/layer.h b/mojo/layer.h index 4abef77..1e2e773 100644 --- a/mojo/layer.h +++ b/mojo/layer.h @@ -38,7 +38,7 @@ namespace mojo { -#include <windows.h> +// #include <windows.h> /* double PCFreq = 0.0; __int64 CounterStart = 0;
g++ -I../mojo/ -std=c++11 -fopenmp -O3 -DMOJO_OPM -DMOJO_AVX -msse4 -mavx test.cpp -o test In file included from test.cpp:44:0: ../mojo/mojo.h:31:0: warning: "MOJO_AVX" redefined #define MOJO_AVX // turn on AVX / SSE3 / SIMD optimizations <command-line>:0:0: note: this is the location of the previous definition In file included from ../mojo/mojo.h:76:0, from test.cpp:44: ../mojo/core_math.h: In function ‘void mojo::dotsum_unwrapped_2x2(const float*, const float*, float*, int)’: ../mojo/core_math.h:178:2: error: ‘_mm256_zeroupper’ was not declared in this scope _mm256_zeroupper(); ^~~~~~~~~~~~~~~~ ../mojo/core_math.h:178:2: note: suggested alternative: ‘_mm_setzero_pd’ _mm256_zeroupper(); ...
どうもLinux環境だとAVXのIntrinsicが使えないようなので、これを使わないようにしよう。
- AVX / SSE を使うオプションを削除する。またVGGはOpenCVを使うので除去した。
diff --git a/examples/makefile b/examples/makefile index ee79729..70267b4 100644 --- a/examples/makefile +++ b/examples/makefile @@ -1,7 +1,7 @@ CC=g++ -CFLAGS_OMP= -I../mojo/ -std=c++11 -fopenmp -O3 -DMOJO_OPM -DMOJO_AVX -msse4 -mavx +CFLAGS_OMP= -I../mojo/ -std=c++11 -O3 -all: test train_mnist train_cifar vgg +all: test train_mnist train_cifar test: test.cpp $(CC) $(CFLAGS_OMP) test.cpp -o test
--- a/mojo/mojo.h +++ b/mojo/mojo.h @@ -28,8 +28,8 @@ #pragma once -#define MOJO_AVX // turn on AVX / SSE3 / SIMD optimizations -#define MOJO_OMP // allow multi-threading through openmp +// #define MOJO_AVX // turn on AVX / SSE3 / SIMD optimizations +// #define MOJO_OMP // allow multi-threading through openmp //#define MOJO_LUTS // use look up tables, uses more memory //#define MOJO_CV3 // use OpenCV 3.x utilities //#define MOJO_CV2 // use OpenCV 2.x utilities
これでコンパイルできるようになったのでだが、次にトレーニングデータとしてCIFAR-10のデータセットをダウンロードしてこなければならない。
$ cd ../data/ $ curl -L http://www.cs.toronto.edu/~kriz/cifar-10-binary.tar.gz | tar xvz
これでシミュレーションを開始しよう。
$ ./train_cifar == Network Configuration ==================================================== 0 : I1 : input 32 32 3 identity 1 : C1 : convolution 3 16 1 elu 2 : P1 : semi_stochastic_pool 3 3 3 : C2 : convolution 3 64 1 elu 4 : P2 : semi_stochastic_pool 4 4 5 : FC2 : fully_connected 10 softmax I1-C1, C1-P1, P1-C2 C2-P2, P2-FC2 == CIFAR-10 Epoch 1 =============================================== 0:00:00 mini batch: 16 training time: 236.644 seconds on 1 threads model updates: 1805 (37% of records) estimated accuracy: 43.39% testing: 20% (13sec remaining) ... == CIFAR-10 Epoch 129 ============================================= 7:00:58 mini batch: 16 training time: 175.415 seconds on 1 threads model updates: 1061 (26% of records) estimated accuracy: 68.424% test accuracy: 67.69% (32.31% error) saved model: ../models/snapshots/tmp_129.txt == CIFAR-10 Epoch 130 ============================================= 7:04:10 mini batch: 16 training time: 175.767 seconds on 1 threads model updates: 1061 (26% of records) estimated accuracy: 68.426% test accuracy: 67.69% (32.31% error) saved model: ../models/snapshots/tmp_130.txt == CIFAR-10 Epoch 131 ============================================= 7:07:23 mini batch: 16 training time: 175.754 seconds on 1 threads model updates: 1062 (26% of records) estimated accuracy: 68.436% test accuracy: 67.66% (32.34% error) saved model: ../models/snapshots/tmp_131.txt Elvis just left the building. No further improvement in training found. Stopping..
EPOCH 131までかかってる... しかも7時間も。さすがにAVXもなし、GPUもなしというのでかなりきつい。