Windowsで超便利なディープラーニングのライブラリのchainerを使う方法
研究でも少しディープラーニングを扱っておきたかったので今回はディープラーニングを簡単に実装して動かすためのライブラリであるchainerを用いる方法を載せたいと思います。
公式ではWindowsに非対応ですが、mnistのサンプルとimagenetの学習まで独自のデータセットを用いてgpuで動かせたのでubuntuじゃなくても動かせます。(とりあえずは)
環境
日本の企業が提供しているDNN用のライブラリ
ドキュメントは英語のみの提供と日本人に厳しいS仕様
http://docs.chainer.org/en/stable/index.html
OS:Windows7
GPU:NVIDIA TITAN X
Python:2.7(64bitバージョン)
コンパイラ:Microsoft Visual C++ Compiler for Python2.7
GPUを使う場合(cuDNNはダウンロードに会員登録が必要)
CUDA Toolkit, cuDNN
- chainerをインストールするまで
Pythonとコンパイラをインストール後、GPUを使う場合はCUDA Toolkitをインストールし、所定のディレクトリにcuDNNを配置した後にchainerをインストールします。cudaのディレクトリは標準ではC:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.5
の様な場所にあると思いますので、ダウンロードしたものをcudaのディレクトリにコピーします。
Pythonが正しくインストール出来たら、コマンドプロンプトを開いてpipコマンドが使えるはずです。まずはpip install -U pipとpip install -U setuptoolsをしましょう。その後pip install chainer で運が良ければインストールできます。エラーが出る場合は、エラーをよく読み、根気強く必要な物をインストールしたりする作業が必要です。アンインストールするときは pip uninstall chainerでアンインストールできます。
大体多いエラーは必要なものが無いというのが多かったのでpip install **** でインストールして再度チャレンジすれば良いと思います。コンパイラも忘れずにインストールしておかないとエラーが出ます。
- 手書き文字認識mnistのサンプル
chainerのサンプルコードはgithubから入手できます。
https://github.com/pfnet/chainer
examplesの中のmnistというフォルダが手書き文字認識のサンプルプログラムです。
幾つか中身が入っていると思いますが、net.pyはネットワークが記述されたプログラム、train_mnist.pyが学習の流れが書かれたプログラムです。
使い方は簡単で、コマンドプロンプトをからpython train_mnist.py -g 0 で実行できます。
すると下の画像のようにずらずらと学習結果が出てくると思います。
もし実行できない場合はpython train_mnist.py を試してみてください。
これが動けばchainerのインストールは成功してますがGPUのライブラリのインストールに失敗しています。
動かなければchainerが上手くインストールできてないです。
- 画像分類のimagenetのサンプル
こちらのプログラムはサンプルそのままではmultiprocessing関係のエラーがでるのでWindowsで動きません。少しだけ修正が必要です。
以下train_imagenet.pyの一番下の部分
if __name__ == '__main__': # Invoke threads feeder = threading.Thread(target=feed_data) feeder.daemon = True feeder.start() logger = threading.Thread(target=log_result) logger.daemon = True logger.start() train_loop() feeder.join() logger.join() # Save final model serializers.save_npz(args.out, model) serializers.save_npz(args.outstate, optimizer)
if __name__ == '__main__': を追加してその下を全てインデントして下さい。
これだけでWindowsでも学習できるようになります。
独自のデータセットを使う際には、train.txt, test.txtが必要になり、それぞれ学習データ・テストデータへのパスとラベルが書かれたファイルです。
C:\Users\user\Desktop\stop256\test\neg0.png 0
C:\Users\user\Desktop\stop256\test\neg1.png 0
C:\Users\user\Desktop\stop256\test\neg2.png 0
C:\Users\user\Desktop\stop256\test\neg3.png 0
C:\Users\user\Desktop\stop256\test\neg4.png 1
C:\Users\user\Desktop\stop256\test\neg5.png 1
C:\Users\user\Desktop\stop256\test\neg6.png 1
C:\Users\user\Desktop\stop256\test\neg7.png 1
C:\Users\user\Desktop\stop256\test\neg8.png 2
C:\Users\user\Desktop\stop256\test\neg9.png 2
C:\Users\user\Desktop\stop256\test\neg10.png 2
C:\Users\user\Desktop\stop256\test\neg11.png 2
この様な感じでパス[半角スペース]ラベルとなっています。
画像は256×256の画像を用意して下さい。無理やりリサイズさせてもokです。
学習にはpython train_imagenet.py train.txt test.txt -g 0 で学習が始まります。
デフォルトではNetwork In NetworkというCNNで学習できます。
学習が終わるとmodelというファイルができます。これが学習済みのネットワークで、このモデルを使って識別等を行うことが可能です。
識別のために、nin.pyを書き換えます。
import math import chainer import chainer.functions as F import chainer.links as L class NIN(chainer.Chain): """Network-in-Network example model.""" insize = 227 def __init__(self): w = math.sqrt(2) # MSRA scaling super(NIN, self).__init__( mlpconv1=L.MLPConvolution2D( 3, (96, 96, 96), 11, stride=4, wscale=w), mlpconv2=L.MLPConvolution2D( 96, (256, 256, 256), 5, pad=2, wscale=w), mlpconv3=L.MLPConvolution2D( 256, (384, 384, 384), 3, pad=1, wscale=w), mlpconv4=L.MLPConvolution2D( 384, (1024, 1024, 1000), 3, pad=1, wscale=w), ) self.train = True def clear(self): self.loss = None self.accuracy = None def __call__(self, x, t): self.clear() h = F.max_pooling_2d(F.relu(self.mlpconv1(x)), 3, stride=2) h = F.max_pooling_2d(F.relu(self.mlpconv2(h)), 3, stride=2) h = F.max_pooling_2d(F.relu(self.mlpconv3(h)), 3, stride=2) h = self.mlpconv4(F.dropout(h, train=self.train)) h = F.reshape(F.average_pooling_2d(h, 6), (x.data.shape[0], 1000)) self.loss = F.softmax_cross_entropy(h, t) self.accuracy = F.accuracy(h, t) return self.loss def predict(self, x_data): x = chainer.Variable(x_data, volatile=True) h = F.max_pooling_2d(F.relu(self.mlpconv1(x)), 3, stride=2) h = F.max_pooling_2d(F.relu(self.mlpconv2(h)), 3, stride=2) h = F.max_pooling_2d(F.relu(self.mlpconv3(h)), 3, stride=2) h = self.mlpconv4(F.dropout(h, train=self.train)) h = F.reshape(F.average_pooling_2d(h, 6), (x.data.shape[0], 1000)) return F.softmax(h)
predictという関数を追加しています。
この関数を使って評価を行うプログラムは他の開発者さんのものをお借りします。
https://github.com/shi3z/chainer_imagenet_tools/blob/master/inspection.py
これで画像識別までをWindows環境下でchainerを用いて動かすことができます。
まだサンプルを動かせただけですので、何か不具合が見つかるかもしれませんが、とりあえずはWindowsで動かして遊べる事を確認しました。