はじめに
RubyからPyTorchを動かすTorch-rbを動かすところまでやってみたのでレポートします。
Torch-rbとは
Torch-rbはAndrew Kane氏が作成・公開している一連のRuby向け機械学習ライブラリの最新作です。ここ数ヶ月、Ankane氏はonnxruntimeのバインディング、Tensorflowのバインディング、LightGBMやxgboostのバインディングと、ものすごい勢いでRuby向けの機械学習ライブラリを制作・公開してきました。なかでも最新作にあたるtorch-rbに関してはREADMEから強い気合が伝わってきます。これまでのAnkaneプロダクツは、いずれもruby-ffiを利用したものですが、今回はriceを利用しているという特徴もあります。
torch-rbは絶賛開発中なので、ここに書いた情報はすぐに古くなる可能性があります。なるべく最新の情報を参照してください。
PyTorchのインストール
まずはpytorchをインストールします。Macを使っている方は、brew
コマンドで大丈夫みたいですが、Linuxを使っているのでサイトからダウンロードします。LanguageでC++を選択するのがポイントです。
たまたま手元のPCがノートパソコンでGPUの性能は高くないので、今回はCPUオンリーのものをダウンロードしました。
https://pytorch.org/
https://pytorch.org/get-started/locally/
ダウンロードしたら解凍してできたlibtorch
ディレクトリをどこに配置したらいいのか、実はあまりよくわかっていませんが、とりあえず/usr/local/lib
あたりに配置しましてみました。
つぎに、Githubからtorch-rbのリポジトリーをcloneします。
git clone https://github.com/ankane/torch-rb
まずはbundle install
しようと試みますが
bundle install
最初からエラーメッセージが出てつまづきます。どうやら、rice
のインストールでエラーが発生しているようです。rice は Ruby Interface for C++ Extensions です。
Unfortunately Rice does not build against a staticly linked Ruby.
You'll need to rebuild Ruby with --enable-shared to use this library.
If you're on rvm: rvm reinstall [version] -- --enable-shared
If you're on rbenv: CONFIGURE_OPTS="--enable-shared" rbenv install [version]
エラーメッセージを見ると--enable--shared
オプションをつけてRubyをビルドし直すように表示されますので言われたとおりにします。
CONFIGURE_OPTS="--enable-shared" rbenv install 2.6.5
うまくインストールされました。
Installed ruby-2.6.5 to /home/kojix2/.rbenv/versions/2.6.5
気を取り直して、bundle install
しなおします。今度はうまくいきました。
あとは以下のように--with-torch-dir
オプションをつけてインストールします。(Macの場合はこれらの過程は不要のようですので詳しくはREADMEをご覧ください)
bundle exec rake build
gem install pkg/torch-rb-0.1.4.gem -- --with-torch-dir=/usr/local/lib/libtorch/
mnist example を試す
さて、インストールがうまくいったら、お決まりのmnist exampleを試してみます。
cd examples/mnist
wget https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
gem install npy
ruby main.rb
class Net < Torch::NN::Module
def initialize
super
@conv1 = Torch::NN::Conv2d.new(1, 32, 3, stride: 1)
@conv2 = Torch::NN::Conv2d.new(32, 64, 3, stride: 1)
@dropout1 = Torch::NN::Dropout2d.new(p: 0.25)
@dropout2 = Torch::NN::Dropout2d.new(p: 0.5)
@fc1 = Torch::NN::Linear.new(9216, 128)
@fc2 = Torch::NN::Linear.new(128, 10)
end
def forward(x)
x = @conv1.call(x)
x = Torch::NN::F.relu(x)
x = @conv2.call(x)
x = Torch::NN::F.max_pool2d(x, 2)
x = @dropout1.call(x)
x = Torch.flatten(x, start_dim: 1)
x = @fc1.call(x)
x = Torch::NN::F.relu(x)
x = @dropout2.call(x)
x = @fc2.call(x)
output = Torch::NN::F.log_softmax(x)
output
end
end
左のターミナルにhtop
によるリソースの使用状況、右のターミナルに学習の進捗が表示されています。CPUを4コア使って頑張って計算してくれているのがわかりますね。しかしCPUやメモリをカツカツに使っている感じではなくて、バランスが取れていていいですね。
最終結果はこんな感じでした。
Train Epoch: 14 [59904/60000 (100%)] Loss: 0.197016
Test set: Average loss: 0.0298, Accuracy: 9909/10000 (99%)
素晴らしい。
推論だけでなく学習もPythonと遜色のない速度で実行できるRubyのディープラーニングライブラリは、私が知ってる範囲ではこれがはじめてです。今回はノートPCを使用して、i5-7200U CPUで計算しましたがまあまあ短時間で学習を終えることができました。
real 18m39.163s
user 47m20.107s
sys 0m26.818s
(ブラウザとか開いていたのでさらに早くなるかも)
ちょうどPFNがChainerをやめてPytorchに行くというニュースが入ってきました。今はちょうどそんな時期ですが、やっとRubyでもディープラーニングを勉強できる環境が整備されつつあるのではないでしょうか。
この記事は以上です。