[C++]deep learningのC++11実装を良い感じにした+解説文つけた

以前CNN(畳み込みニューラルネット)の実装を公開して放置していたら、じわじわstarが溜まってきた。(みんなCaffe使ったほうがいいんじゃ…)と思いつつも、少し前からコードを整理して少し良い感じにしたので、改めて宣伝。

github.com

良い感じなところ

  • ヘッダをincludeするだけでOK、外部依存なし
    • 並列化したい場合だけintel TBBが必要
  • 最近の流行を含め、最小限のパーツは揃っている
    • 活性化関数はtanh/sigmoid/softmax/relu/leaky-reluなど
    • ソルバーはSGD/adagrad/RMSPropなど
    • 詳しくはreadme
  • そこそこ速い
    • GPUには勝てないが、MNIST程度のタスクなら10分程度で終わる
  • コードが(比較的)少ない
    • 全部で3000行程度

こんな感じに、C++のコードでモデルを定義して学習します。

// 損失関数とソルバーを先に指定
network<mse, adagrad> net;

// レイヤーを上から順に積む
net << convolutional_layer<tan_h>(32, 32, 5, 1, 6) // 32x32in, conv5x5, 1-6 f-maps
    << average_pooling_layer<relu>(28, 28, 6, 2) // 28x28in, 6 f-maps, pool2x2
    << fully_connected_layer<relu>(14 * 14 * 6, 120)
    << fully_connected_layer<softmax>(120, 10);

// 学習データのロード
std::vector<label_t> train_labels;
std::vector<vec_t> train_images;
parse_mnist_labels("train-labels.idx1-ubyte", &train_labels);
parse_mnist_images("train-images.idx3-ubyte", &train_images);

// 学習 (50-epoch, 30-minibatch)
net.train(train_images, train_labels, 30, 50);

// 重みを保存
std::ofstream ofs("weights");
ofs << net;

ふつうにPC上で使う分にはCaffeやChainerをお勧めしますが、tiny-cnnはコードが小さいので、「なんらかのコードを読むことで、deep learningへの理解を深めたい」という方の役には立てるかもしれません。実装も黒魔術的な事はやらずに、なるべく素直に書いているつもり。というわけで、簡単なニューラルネットの解説+実装の解説もwiki上に公開しました。

実装ノート · nyanp/tiny-cnn Wiki · GitHub

PRMLとか深層学習本よりも初歩的な内容にとどまっていますので、より詳しくはこれらの本を読みましょう。

パターン認識と機械学習 上

パターン認識と機械学習 上

深層学習 (機械学習プロフェッショナルシリーズ)

深層学習 (機械学習プロフェッショナルシリーズ)

内容の問題点、間違いについてはissuesまで投稿お待ちしてます。