Deep Learning フレームワークざっくり紹介 Advent Calendar 2017 の 9日目 の記事です。
PyTorchとCaffe2で、モデル表現の標準フォーマットであるONNX (Open Neural Network Exchange)を使ってみます。
環境
今回はmacを使います。
- macOS 10.13
- python 2.7.14 ( anaconda2-5.0.1 )
PyTorch
元々はLuaという言語で書かれたTorchのPython版として、ChainerをForkしてFacebook AI Researchの方が開発したDeepLearningフレームワークです。
Chainerと同じく、Define by Runを採用しており動的ネットワークを書くことができます。書き方も基本的にはChainerとかなり似ています。
また、比較的新しいフレームワークで、2017年はじめにβ版が発表されて有名になりました。
Google Trendsでも2017年2月頃を堺にChainerを抜いています。
日本といくつかの国はChainerの検索数が多いですが、他の国では圧倒的にPyTrochの方が優位です。
インストール
公式ページに環境毎のインストール方法が書いています。condaやpipであれば、簡単にインストールできます。condaでのインストールを推奨しているみたいです。
condaの場合
$ conda install pytorch torchvision -c soumith
pipの場合
$ pip install install http://download.pytorch.org/whl/cu75/torch-0.2.0.post3-cp36-cp36m-manylinux1_x86_64.whl $ pip install torchvision
しかし、現時点の最新バージョンである0.2.0版にはまだnn.onnx
が含まれていないので、ONNXを利用するためには、masterブランチを使う必要があり、ソースからのインストールが必要です。
$ conda install numpy pyyaml setuptools cmake cffi $ git clone --recursive https://github.com/pytorch/pytorch $ cd pytorch $ MACOSX_DEPLOYMENT_TARGET=10.13 CC=clang CXX=clang++ python setup.py install
10分以上かかりましたが、エラーなくインストールできました。
モデル定義
シンプルなCNNのモデルです。
import torch.nn as nn import torch.nn.functional as F class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(1, 10, kernel_size=5) self.conv2 = nn.Conv2d(10, 20, kernel_size=5) self.conv2_drop = nn.Dropout2d() self.fc1 = nn.Linear(320, 50) self.fc2 = nn.Linear(50, 10) def forward(self, x): x = F.relu(F.max_pool2d(self.conv1(x), 2)) x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) x = x.view(-1, 320) x = F.relu(self.fc1(x)) x = F.dropout(x, training=self.training) x = self.fc2(x) return F.log_softmax(x)
Caffe2
Caffe2は、元々Caffeを開発したFacebookのYangqing Jia氏が中心となり開発されました。
インストールは、公式サイトを参考に行います。ソースからのインストールを試みたのですが、上手くいかなかったので諦めてDockerを使いました。
$ docker pull caffe2ai/caffe2:c2v0.8.0.cpu.min.ubuntu16.04
ONNX
ONNX (Open Neural Network Exchange) は、FacebookとMicrosoftが提唱しているモデル表現の標準フォーマットです。異なるフレームワークで作成されたモデルを別のフレームワークでも使えるようにするといったものです。
PyTorchで書いたモデルをエクスポートしてCaffe2で使ったり、MXNetモデルをCognitive Toolkitで使ったりすることができます。
PyTorchの他、Caffe2, Microsoft Cognitive Toolkit, Apache MXNetがONNXをサポートしています。TensorflowやApple CoreMLでも使えるみたいです。
Import | Export | |
---|---|---|
Caffe2 | OK | OK |
Cognitive Toolkit | OK | OK |
MXNet | OK | OK |
PyTorch | NG? | OK |
公式のチュートリアルもあるので、こちらも参考にしてみてください。
インストール
ONNXのインストールは、condaかpipで行います。condaでのインストールが推奨されているようです。
condaの場合
$ conda install -c conda-forge onnx
pipの場合
$ pip install onnx
モデルのエクスポート
先程のPyTorchモデルをエクスポートしてみます。
from torch.autograd import Variable import torch.onnx model = Net() x = Variable(torch.randn(1, 1, 28, 28)) torch.onnx.export(model, x, 'model.onnx', verbose=True)
今回は、そのままエクスポートを行いますが、通常は学習済みモデルをエクスポートします。
PyTorchは動的にネットワークを定義(Define by Run)することができますが、ONNXのフォーマットに出力するためには、入力次元を指定する必要があります。
torch.onnx.export
で指定したファイル(model.onnx
)にバイナリ形式で出力されます。verbose=True
とすると人間が読める形式でコマンドラインに表示されます。
graph(%0 : Float(64, 1, 28, 28) %1 : Float(10, 1, 5, 5) %2 : Float(10) %3 : Float(20, 10, 5, 5) %4 : Float(20) %5 : Float(50, 320) ... %22 : Float(64, 50), %23 : UNKNOWN_TYPE = Dropout[is_test=1, ratio=0.5](%21) %26 : Float(64, 10) = Gemm[alpha=1, beta=1, broadcast=1, transB=1](%22, %7, %8) %27 : Float(64, 10) = Softmax[axis=1](%26) %28 : Float(64, 10) = Log(%27) return (%28); }
モデルファイルの中身はonnx
モジュールを使って確認することもできます。恐らくどのフレームワークで作成したモデルファイルでも同じように確認することができます。
import onnx import onnx.helper model = onnx.load("model.onnx") print(onnx.helper.printable_graph(model.graph))
graph torch-jit-export (%name: "0" type { tensor_type { elem_type: FLOAT shape { dim { dim_value: 1 } ...
モデルのインポート
PyTorchではまだインポートがサポートされていないみたいなので、Caffe2で利用してみます。
Caffe2でONNXモデルを利用するためにonnx-caffe2
をインストールします。
condaの場合
$ conda install -c ezyang onnx-caffe2
pipの場合
$ pip install onnx-caffe2
準備が整ったら、先程エクスポートしたmodel.onnx
をインポートして利用してみます。
import numpy as np import onnx from onnx_caffe2.backend import prepare model = onnx.load("model.onnx") rep = prepare(model) outputs = rep.run(np.random.randn(1, 1, 28, 28).astype(np.float32)) print outputs[0] # >>> array([[-2.34730482, -2.28282928, -2.2903831 , -2.40077782, -2.38225985, # -2.35983896, -2.3191402 , -2.38344955, -2.22534752, -2.07859206]], dtype=float32)
model.onnx
の重みはランダムであり、入力したデータもランダムですが、正しく出力できているようです。
まとめ
PyTorchで作成したONNXモデルをCaffe2で利用してみました。ONNXは、まだ提唱されたばかりで、今後大きく変更される可能性はありますが、異なるDeepLearningフレームワークの互換性を得るための標準フォーマットとしては期待されます。