ディープラーニングフレームワーク Caffe 初心者のお試し報告

[先週、投稿](http://qiita.com/wyamamo/items/35f1af82957d4ce160a2)したとおり Caffe をインストールしました。
付属のサンプルはそれらしく動きました。しかし、それだけでは寂しいので、自分で作成したデータで動作を確認しました。
大量のデータを用意できる余力もないので、本当に動作確認レベルの簡単さですが :grin: 

###テストデータ
用意したデータは以下の０〜９の数字の JPEG ファイルだけです。
＃ これ以外にも似たようなのを作ったのですが、動作を確認できず :tired_face: 

![num0.jpg](https://qiita-image-store.s3.amazonaws.com/0/107389/df2cf561-51f3-4831-481c-642dfa20031e.jpeg)
num0.jpg

![num1.jpg](https://qiita-image-store.s3.amazonaws.com/0/107389/51613e5d-4553-07df-2ae6-01fe78147c8c.jpeg)
num1.jpg

![num2.jpg](https://qiita-image-store.s3.amazonaws.com/0/107389/e6a5c163-d70b-728e-7512-1eef8ee49841.jpeg)
num2.jpg

![num3.jpg](https://qiita-image-store.s3.amazonaws.com/0/107389/51f7072a-cf9e-8ce0-e3e5-87292bfb3c34.jpeg)
num3.jpg

![num4.jpg](https://qiita-image-store.s3.amazonaws.com/0/107389/38f209c7-606b-d068-ceec-602f48120db6.jpeg)
num4.jpg

![num5.jpg](https://qiita-image-store.s3.amazonaws.com/0/107389/056929d1-7706-f9ed-4219-f43b5c6ee9f3.jpeg)
num5.jpg

![num6.jpg](https://qiita-image-store.s3.amazonaws.com/0/107389/a5d3a4b3-69d4-32c4-2a9e-71e8494ae989.jpeg)
num6.jpg

![num7.jpg](https://qiita-image-store.s3.amazonaws.com/0/107389/d61cec24-500b-cce5-e5cc-75413eb2051c.jpeg)
num7.jpg

![num8.jpg](https://qiita-image-store.s3.amazonaws.com/0/107389/ff562bad-f855-3bd6-107e-18d9cfb797d5.jpeg)
num8.jpg

![num9.jpg](https://qiita-image-store.s3.amazonaws.com/0/107389/68ab4fae-d015-87fb-8ebf-b752a4b3c899.jpeg)
num9.jpg


###作業ディレクトリの構成
Caffe をインストールしたディレクトリ下に **data/mytest0/** を作成して動かしました。

```
data/mytest0/
├── mytest0_solver4.prototxt
├── mytest0_iter_10000.caffemodel
├── mytest0_iter_10000.solverstate
├── mytrain0.txt
├── mytest0_train_lmdb
│   ├── data.mdb
│   └── lock.mdb
├── mytest0_traindup_lmdb
│   ├── data.mdb
│   └── lock.mdb
├── mytest0_train_traindup.prototxt
├── mytest_swap56.txt
├── mytest0_test_swap56_lmdb
│   ├── data.mdb
│   └── lock.mdb
├── mytest0_train_trainswap56.prototxt
└── train_dataset
    ├── num0.jpg
    ├── num1.jpg
    ├── num2.jpg
    ├── num3.jpg
    ├── num4.jpg
    ├── num5.jpg
    ├── num6.jpg
    ├── num7.jpg
    ├── num8.jpg
    └── num9.jpg
```

以下、テスト用に作成したファイルです。

**train_dataset** … 上述の JPEG ファイルをこのディレクトリに収めました。

**mytrain0.txt** … 学習データを作成するための情報です。

```
num0.jpg 0
num1.jpg 1
num2.jpg 2
num3.jpg 3
num4.jpg 4
num5.jpg 5
num6.jpg 6
num7.jpg 7
num8.jpg 8
num9.jpg 9
```

**mytest_swap56.txt** … テスト（２）用に 5 と 6 のデータを入替えたファイルです。

```
num0.jpg 0
num1.jpg 1
num2.jpg 2
num3.jpg 3
num4.jpg 4
num5.jpg 6
num6.jpg 5
num7.jpg 7
num8.jpg 8
num9.jpg 9
```

**mytest0_solver4.prototxt** … ソルバーのパラメータファイル
　lenet_solver.prototxt をベースに作成した。差分の diff を以下に示します。

```
diff -wu examples/mnist/lenet_solver.prototxt data/mytest0/mytest0_solver4.prototxt
--- examples/mnist/lenet_solver.prototxt	2016-06-17 00:43:37.467578586 +0900
+++ data/mytest0/mytest0_solver4.prototxt	2016-06-19 15:08:55.512925064 +0900
@@ -1,5 +1,5 @@
 # The train/test net protocol buffer definition
-net: "examples/mnist/lenet_train_test.prototxt"
+net: "data/mytest0/mytest0_train_traindup.prototxt"
 # test_iter specifies how many forward passes the test should carry out.
 # In the case of MNIST, we have test batch size 100 and 100 test iterations,
 # covering the full 10,000 testing images.
@@ -20,6 +20,6 @@
 max_iter: 10000
 # snapshot intermediate results
 snapshot: 5000
-snapshot_prefix: "examples/mnist/lenet"
+snapshot_prefix: "data/mytest0/mytest0"
 # solver mode: CPU or GPU
 solver_mode: CPU
```


**mytest0_train_traindup.prototxt** … ネットワークのパラメータファイル
　lenet_train_test.prototxt をベースに作成した。差分を diff で以下に示します。

```
diff -wu examples/mnist/lenet_train_test.prototxt data/mytest0/mytest0_train_traindup.prototxt
--- examples/mnist/lenet_train_test.prototxt	2016-06-12 16:55:47.446382219 +0900
+++ data/mytest0/mytest0_train_traindup.prototxt	2016-06-19 15:09:50.460971396 +0900
@@ -1,6 +1,6 @@
-name: "LeNet"
+name: "MyTest"
 layer {
-  name: "mnist"
+  name: "mytest0"
   type: "Data"
   top: "data"
   top: "label"
@@ -11,13 +11,13 @@
     scale: 0.00390625
   }
   data_param {
-    source: "examples/mnist/mnist_train_lmdb"
+    source: "data/mytest0/mytest0_train_lmdb"
     batch_size: 64
     backend: LMDB
   }
 }
 layer {
-  name: "mnist"
+  name: "mytest0"
   type: "Data"
   top: "data"
   top: "label"
@@ -28,7 +28,7 @@
     scale: 0.00390625
   }
   data_param {
-    source: "examples/mnist/mnist_test_lmdb"
+    source: "data/mytest0/mytest0_traindup_lmdb"
     batch_size: 100
     backend: LMDB
   }
```

**mytest0_train_trainswap56.prototxt** … ネットワークのパラメータファイル
　mytest0_train_traindup.prototxt から一行だけ修正した。

```
diff -wu data/mytest0/mytest0_train_{traindup,trainswap56}.prototxt
--- data/mytest0/mytest0_train_traindup.prototxt	2016-06-19 15:09:50.460971396 +0900
+++ data/mytest0/mytest0_train_trainswap56.prototxt	2016-06-25 11:50:55.114186459 +0900
@@ -28,7 +28,7 @@
     scale: 0.00390625
   }
   data_param {
-    source: "data/mytest0/mytest0_traindup_lmdb"
+    source: "data/mytest0/mytest0_test_swap56_lmdb"
     batch_size: 100
     backend: LMDB
   }
```

以下のファイル・ディレクトリはコマンドの出力です。

 - mytest0_iter_10000.caffemodel
 - mytest0_iter_10000.solverstate
 - mytest0_train_lmdb
 - mytest0_traindup_lmdb
 - mytest0_test_swap56_lmdb

### 学習データの作成


```
../../build/tools/convert_imageset train_dataset/ mytrain0.txt mytest0_train_lmdb 1 -backend lmdb 28 28
I0619 14:16:50.619668  5035 convert_imageset.cpp:89] A total of 10 images.
I0619 14:16:50.620254  5035 db_lmdb.cpp:35] Opened lmdb mytest0_train_lmdb
I0619 14:16:50.735833  5035 convert_imageset.cpp:153] Processed 10 files.
```

### 学習の実行

```
./build/tools/caffe train --solver=data/mytest0/mytest0_solver4.prototxt
```

　この結果 **mytest0_iter_10000.caffemodel** が作成されます。
　所要時間は約２時間半と、テストが数分で終わるのに対して桁違いに時間がかかる。


### テストデータ（１）の作成
　学習データと同じ内容で異なる lmdb を作成

```
../../build/tools/convert_imageset train_dataset/ mytrain0.txt mytest0_traindup_lmdb 1 -backend lmdb 28 28
I0619 15:09:56.534297  6100 convert_imageset.cpp:89] A total of 10 images.
I0619 15:09:56.534826  6100 db_lmdb.cpp:35] Opened lmdb mytest0_traindup_lmdb
I0619 15:09:56.603402  6100 convert_imageset.cpp:153] Processed 10 files.
```

### テストの実行（１） … テストデータ（１）を使用

```
./build/tools/caffe test -model ./data/mytest0/mytest0_train_traindup.prototxt -weights ./data/mytest0/mytest0_iter_10000.caffemodel
```

出力ログの末尾のみを以下に抜粋する。

```
I0619 20:32:14.349992 14900 caffe.cpp:275] Batch 49, accuracy = 1
I0619 20:32:14.350070 14900 caffe.cpp:275] Batch 49, loss = 9.35604e-05
I0619 20:32:14.350086 14900 caffe.cpp:280] Loss: 9.35604e-05
I0619 20:32:14.350109 14900 caffe.cpp:292] accuracy = 1
I0619 20:32:14.350132 14900 caffe.cpp:292] loss = 9.35604e-05 (* 1 = 9.35604e-05 loss)
```

学習データ自体をテストデータに指定したテストで **accuracy = 1** となったので正しい結果だと思います :smile: 

### テストデータ（２）の作成
　学習データ（テストデータ（１））を一部変更した内容

```
../../build/tools/convert_imageset train_dataset/ mytest_swap56.txt mytest0_test_swap56_lmdb -backend lmdb 28 28
I0625 11:47:31.779678  3924 convert_imageset.cpp:89] A total of 10 images.
I0625 11:47:31.780181  3924 db_lmdb.cpp:35] Opened lmdb mytest0_test_swap56_lmdb
I0625 11:47:31.890821  3924 convert_imageset.cpp:153] Processed 10 files.
```


###テストの実行（２） … テストデータ（２）を使用

```
./build/tools/caffe test -model ./data/mytest0/mytest0_train_trainswap56.prototxt -weights ./data/mytest0/mytest0_iter_10000.caffemodel
```

出力ログの末尾のみを以下に抜粋する。

```
I0625 11:51:35.768973  3970 caffe.cpp:275] Batch 49, accuracy = 0.8
I0625 11:51:35.769052  3970 caffe.cpp:275] Batch 49, loss = 2.09494
I0625 11:51:35.769068  3970 caffe.cpp:280] Loss: 2.09494
I0625 11:51:35.769095  3970 caffe.cpp:292] accuracy = 0.8
I0625 11:51:35.769121  3970 caffe.cpp:292] loss = 2.09494 (* 1 = 2.09494 loss)
```

10個あるデータのうち2つを入替えて誤らせたテストなので **accuracy = 0.8** は期待通りかと :blush: 



以上、自作データで期待する結果らしきものが得られました。ディープラーニングの一端に触れることができたかな :yum: 


ところで、Caffe のコマンドがコアダンプしても焦らないこと。自分の場合は以下をチェックしたら解消しました。
　・パス指定の誤り
　・出力でレクトリが既存だったため mkdir できない