Vagrant上のUbuntuでTorch7のCPU開発環境を作る
男もすなるTorch7といふものを、女もしてみむとてするなり。
まずはVagrant上にUbuntuを立てて開発環境を作ります。
Vagrant上ではGPUは使えませんが、あくまで体験版という事で。あと私は男です。
インストール〜開発環境構築まで
UbuntuのVagrantを作成してログイン
$ vagrant box add ubuntu-14.04 https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box $ vagrant init ubuntu-14.04 $ vagrant up $ vagrant ssh
Torchのインストール
続いてTorchのインストールを行います。
不明点あればhttp://torch.ch/docs/getting-started.htmlをどうぞ。
$ curl -s https://raw.githubusercontent.com/torch/ezinstall/master/install-deps | bash $ git clone https://github.com/torch/distro.git ~/torch --recursive $ cd ~/torch; ./install.sh $ source ~/.bashrc $ th #Torchのコンソールが立ち上がる事を確認
Torchでよく使うパッケージのインストール
参考:http://ultraist.hatenablog.com/entry/2015/01/30/221102
※cutorch,cunnはCUDAを使うパッケージなので、GPU環境が無い場合は使えません。
$ luarocks install cwrap $ luarocks install torch $ luarocks install optim $ luarocks install nn $ luarocks install image $ luarocks install cutorch $ luarocks install cunn
Tutorial
ここまででTorchのインストールは終了ですが、せっかくなので簡単なTutorialをやります。
今回はCaffeの学習済みモデルをそのままTorchのモジュールに変換できるloadcaffeを使って、Network-in-Network Imagenetのモデルで分類をやってみます。
CUDAをインストール
vagrant上ではGPUは使えませんが、後々必要なのでCUDAのインストールを行います。
参考:https://github.com/BVLC/caffe/wiki/Ubuntu-14.04-VirtualBox-VM
$ sudo apt-get install build-essential $ sudo apt-get install linux-headers-`uname -r` $ sudo apt-get install curl $ curl -O "http://developer.download.nvidia.com/compute/cuda/6_5/rel/installers/cuda_6.5.14_linux_64.run" $ chmod +x cuda_6.5.14_linux_64.run $ sudo ./cuda_6.5.14_linux_64.run --kernel-source-path=/usr/src/linux-headers-`uname -r`/ Do you accept the previously read EULA? (accept/decline/quit): accept #利用規約に同意 Install NVIDIA Accelerated Graphics Driver for Linux-x86_64 340.29? ((y)es/(n)o/(q)uit): n #VM上なのでグラフィックドライバは入れない Install the CUDA 6.5 Toolkit? ((y)es/(n)o/(q)uit): y #Toolkitをインストールする Enter Toolkit Location [ default is /usr/local/cuda-6.5 ]: #Toolkitのパスはデフォルト Do you want to install a symbolic link at /usr/local/cuda? ((y)es/(n)o/(q)uit): y #シンボリックリンクをインストール Install the CUDA 6.5 Samples? ((y)es/(n)o/(q)uit): y #CUDAサンプルをインストール Enter CUDA Samples Location [ default is /root ]: #CUDAサンプルのパスはデフォルト
CUDAのパス設定及び依存関係のインストール
最後のapt-getはCaffeを使うために必要な依存関係なんですが、loadcaffeを使う場合必要ないものが混じっているかと思います。
$ echo 'export PATH=/usr/local/cuda/bin:$PATH' >> ~/.bashrc $ echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64:/usr/local/lib' >> ~/.bashrc $ source ~/.bashrc $ sudo apt-get update --fix-missing $ sudo apt-get install -y libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libboost-all-dev libhdf5-serial-dev protobuf-compiler gfortran libjpeg62 libfreeimage-dev libatlas-base-dev git python-dev python-pip libgoogle-glog-dev libbz2-dev libxml2-dev libxslt-dev libffi-dev libssl-dev libgflags-dev liblmdb-dev python-yaml sudo easy_install pillow
loadcaffeのインストール
ソースのダウンロード
luarocks install loadcaffe
で簡単にインストールしたいところですが、
CPU環境で走らせた時にエラーが出てしまったので、git cloneでソースを落としてきて一部書き換えてからインストールを行います。GPU環境の人は普通にインストールして大丈夫かと思います。
$ git clone https://github.com/szagoruyko/loadcaffe
$ cd loadcaffe
ソースの一部書き換え
loadcaffeはデフォルトでCPU環境で使えないモジュールをrequireするためそのまま使うとエラーが出てしまいます。 なので、CPU環境でも動くようにloadcaffe/loadcaffe.cppのconvertProtoToLuaV1,convertProtoToLuaV2関数内の以下の箇所を書き換えます。
※SpatialStochasticPoolingはnnモジュールに無かったので、CPU環境では使えないかと思います。
変更前
ofs << "require '" << cuda_package << "'\n"; ofs << "require 'cunn'\n"; ofs << "local model = {}\n"; if(std::string(cuda_package)=="ccn2") ofs<< "table.insert(model, {'torch_transpose_dwhb', nn.Transpose({1,4},{1,3},{1,2})})\n"; else if(std::string(cuda_package)=="nn" || std::string(cuda_package)=="cudnn") ofs<< "require 'inn'\n";
case NN: if(param.pool() == caffe::PoolingParameter::MAX) sprintf(buf, "nn.SpatialMaxPooling(%d, %d, %d, %d, %d, %d):ceil()", kW, kH, dW, dH, padW, padH); else if(param.pool() == caffe::PoolingParameter::AVE) sprintf(buf, "inn.SpatialAveragePooling(%d, %d, %d, %d)", kW, kH, dW, dH); // padding is not supported yet else if(param.pool() == caffe::PoolingParameter::STOCHASTIC) sprintf(buf, "inn.SpatialStochasticPooling(%d, %d, %d, %d)", kW, kH, dW, dH); break;
変更後
ofs << "require '" << cuda_package << "'\n"; ofs << "local model = {}\n"; if(std::string(cuda_package)=="ccn2") ofs<< "table.insert(model, {'torch_transpose_dwhb', nn.Transpose({1,4},{1,3},{1,2})})\n"; else if(std::string(cuda_package)=="cudnn") ofs<< "require 'inn'\n";
case NN: if(param.pool() == caffe::PoolingParameter::MAX) sprintf(buf, "nn.SpatialMaxPooling(%d, %d, %d, %d, %d, %d):ceil()", kW, kH, dW, dH, padW, padH); else if(param.pool() == caffe::PoolingParameter::AVE) sprintf(buf, "nn.SpatialAveragePooling(%d, %d, %d, %d)", kW, kH, dW, dH); // padding is not supported yet else if(param.pool() == caffe::PoolingParameter::STOCHASTIC) sprintf(buf, "inn.SpatialStochasticPooling(%d, %d, %d, %d)", kW, kH, dW, dH); break;
コンパイル
ソースを書き換えたらコンパイルします。
$ luarocks make $ th #Torchコンソール立ち上げ $ require 'loadcaffe' #エラーが出ない事を確認
Tutorialプログラムの実行
事前準備
Torch7公式Tutorialの7_imagenet_classification/classify.luaを実行すると、
CaffeのNetwork-in-Network Imagenet学習済みモデルを用いて分類が行えます。
classify.luaはcuda()を使っておりそのままでは動かないので、cuda()関数を空実装に置き換えてくれるfakecudaモジュールを使います。(classify.lua内のcuda()を消すのでも大丈夫です)
$ luarocks install https://raw.githubusercontent.com/soumith/fakecuda/master/fakecuda-scm-1.rockspec $ git clone https://github.com/torch/tutorials.git $ cd tutorial/7_imagenet_classification $ vi classify.lua #ファイル頭に以下の2行を追加 use_cpu = true require('fakecuda').init(use_cpu)
実行
デフォルトでは金魚画像の分類を行います。無事に分類されたら成功です。
あとは好きな画像で分類してみてください。
$ th classify.lua ==> Loading network Successfully loaded ./nin_imagenet.caffemodel . . . predicted class 1: goldfish, Carassius auratu predicted class 2: macaw predicted class 3: lorikeet predicted class 4: flamingo predicted class 5: pinwheel
ちなみに
で分類してみた結果
predicted class 1: restaurant, eating house, eating place, eatery predicted class 2: library predicted class 3: bookshop, bookstore, bookstall predicted class 4: barber chair predicted class 5: pool table, billiard table, snooker table
悪くないですね。
以上です。機械学習はモデルが既にあるなら特に難しい事は無いはずなのですが、何故かとっつきにくいイメージありますね。 次回があればOpenRestyを用いた簡易APIの作成や、Fine-Tuningを用いた独自分類モデルの作成を行いたいと思います。