C++プログラマがWindows上でCaffeを使ってDeep Learningするお話（６）　学習（詳細）編

今回は、もう少し「caffe.exe」の中身を見ていきます。
なお、今回も学習処理（「caffe.exe train」）についてのみとなります。

# 処理の流れ
学習時の処理は、以下のような流れで行われます。

1. 引数の解析
2. 初期化
3. 学習の実行

## 引数の解析
これはGoogleの「gflags」を利用して、引数の解析を行っています。
（gflags::ParseCommandLineFlags()）

「gflags」の説明は省きますが、以下のように引数の定義がされていますので、これに従って解析を行います。

```
DEFINE_string(gpu, "",
    "Optional; run in GPU mode on given device IDs separated by ','."
    "Use '-gpu all' to run on all available GPUs. The effective training "
    "batch size is multiplied by the number of devices.");
DEFINE_string(solver, "",
    "The solver definition protocol buffer text file.");
DEFINE_string(model, "",
    "The model definition protocol buffer text file.");
DEFINE_string(phase, "",
    "Optional; network phase (TRAIN or TEST). Only used for 'time'.");
DEFINE_int32(level, 0,
    "Optional; network level.");
DEFINE_string(stage, "",
    "Optional; network stages (not to be confused with phase), "
    "separated by ','.");
DEFINE_string(snapshot, "",
    "Optional; the snapshot solver state to resume training.");
DEFINE_string(weights, "",
    "Optional; the pretrained weights to initialize finetuning, "
    "separated by ','. Cannot be set simultaneously with snapshot.");
DEFINE_int32(iterations, 50,
    "The number of iterations to run.");
DEFINE_string(sigint_effect, "stop",
             "Optional; action to take when a SIGINT signal is received: "
              "snapshot, stop or none.");
DEFINE_string(sighup_effect, "snapshot",
             "Optional; action to take when a SIGHUP signal is received: "
             "snapshot, stop or none.");
```

また同時に、やはりGoogleの「google-glog」でログの初期化を行います。
（google::InitGoogleLogging()）

## 初期化
ソース的には、caffe.cppのtrain()で学習処理が行われます。
ただコードのほとんどは初期化処理になります。

まず「caffe::ReadSolverParamsFromTextFileOrDie()」でソルバファイルの解析を行います。
実際にはGoogleの「Protocol Buffers」で処理を行っています。
（google::protobuf::TextFormat::Parse()）
ここで読み込むパラメータ等はあらかじめ「caffe\src\caffe\proto\caffe.proto」で記述しておき、ビルド時に「caffe\src\caffe\proto\caffe.pb.cc」に変換されて利用されます。
（scriptの「ProtoCompile.cmd」で変換処理が記述されています）
解析した結果は、caffe::SolverParameterのオブジェクト「solver_param」に保存されます。

その後、設定されていないパラメータ値を設定したりします。

パラメータ設定後、「solver_param」を使用してcaffe::Solverのオブジェクト「solver」を作成します。
この時、単精度 or 倍精度で処理を行うかを指定します。

## 学習の実行
「caffe::Solver::solve()」で学習を実行します。
これだけです。

なお、マルチGPUの対応もされています。

ちなみに、「caffe::Solver::solve()」の中での処理ですが、イテレータでグリグリ回しながら、

- テストのタイミングが来たらテストをする
- トレーニングをする
- ロス率を計算する
- ログを表示する
- 情報を更新する
- スナップショットのタイミングが来たらファイル出力する

を繰り返します。

# おまけ
学習の処理はcaffeネームスペースの中でほぼ全て行われているので、利用者側が書かなくてはいけないコードはほとんどありません。
ただ、CNN以外のDeepLearning処理を行いたいとか、自分でレイヤーを作りたいとかだと、caffeネームスペース内のクラスを修正したり追加することになります。

# 関連記事
[C++プログラマがWindows上でCaffeを使ってDeep Learningするお話（１）](http://qiita.com/mine820/items/37862e45aa66c2ad8b80)
[C++プログラマがWindows上でCaffeを使ってDeep Learningするお話（２）](http://qiita.com/mine820/items/9ea5812fc25a70419f31)
[C++プログラマがWindows上でCaffeを使ってDeep Learningするお話（３）](http://qiita.com/mine820/items/f4395a3ac734085e5ed1)
[C++プログラマがWindows上でCaffeを使ってDeep Learningするお話（４）](http://qiita.com/mine820/items/41347cd99278d0dc6715)
[C++プログラマがWindows上でCaffeを使ってDeep Learningするお話（５）](http://qiita.com/mine820/items/e8857fee3fa0b4ada170)
[C++プログラマがWindows上でCaffeを使ってDeep Learningするお話（７）](http://qiita.com/mine820/items/1e100330d163f9959c65)
[C++プログラマがWindows上でCaffeを使ってDeep Learningするお話（８）](http://qiita.com/mine820/items/30fcc4e5f794c42b4bd7)