CIFAR-10でstate of the artのスコアが出せる、インターネットに落ちている中で最強のコード

DecMeg2014をやっているときにCUDA使いて〜と思うことがあったので、最近、GTX760というGPUを購入して、Kaggle PlaygroundのCIFAR-10(有名な物体認識のデータセット)で試していたのですが、CIFAR-10のstate of the artである0.912を微妙に超える精度(0.9173)が出せるようになったのでソースコードを公開します。

nagadomi/kaggle-cifar10-torch7 · GitHub

この結果は、"ベンチマークサイト Kaggle"で現在3位にランキングされています。

内容的には特に面白いことはしていなくて、cropping,scaling,horizontal reflectionで学習データを180万件(36x)まで増殖させたあとでNIN(Network In Network)というConvolutional Neural Networkの畳み込み層をMLPにしたモデルを学習しているだけです(層数等、論文実装とは違います)。
データ増やすしすぎだろ、と思うかもしれませんが、自分が試した感じだと、NINを使うとデータを増やせば増やすほど精度が上がります。またNINは層数が多くなるので、データが少ないと学習がうまくいかないというのもあります。学習データが1万件程度だと全く学習できません(ほとんどのクラスの精度が0%になってしまう)。そういうわけで、めちゃくちゃデータを増やして学習するので、学習時間がめちゃくちゃかかります。CUDAを使って1 epochに90分くらいかかり、10 epochくらい回さないと精度が上がりらないので、15時間くらいはかかります。

実装は、Torch7で行なっています。Torch7は、Pylearn2やcaffe、cuda-convnetなどと比べるとマイナーなNeural Networkのライブラリですが、Neural language modelsというパッケージ(nn)を使うと複雑な構造のNeural Networkも自然なコードで書けるので、プログラミングが得意な人にとっては、最強の開発環境ではないかと個人的には思っています。DecMeg2014では、Torch7で書いた複雑奇怪なNeural Networkで5位になっているので、実用上問題無いレベルで使えると思います。
ただ、CUDAの実装は微妙なものが多く、例えば、SpatialMaxPoolingのCUDA実装はkernelとstrideのサイズが同じじゃないと動かなかったりします。kernelをstrideより大きくするoverlapping poolingは画像認識において精度が向上できることが知られていて、cuda-convnetのサンプルなど精度を重視している実装はほとんどこれを使っているのですが、Torch7が対応してないので、このコードでは使っていません。
ということで、まだまだ改善の余地はあるので、興味ある方はこのコードの知見を活かし、Kaggleで2位になったあとソースコードgithubに置いておいてください。
(1位はたぶん無視していい存在だと思う)

追記 (2014/8/28)

epoch 20まで増やしたら、0.92210で現在2位になった。
時間かかってもちゃんと実験するべきだった。

追記 (2014/11/8)

最終結果を書きました。ソースコードの内容も変更されています。
Kaggle CIFAR-10の話 - デー