LoginSignup
30
27

More than 3 years have passed since last update.

Chainer ⇒ PyTorch移行を試してみた

Last updated at Posted at 2019-12-07

今週、PFNよりChainerの開発を停止するという発表があって驚きました。

Chainer/CuPy v7のリリースと今後の開発体制について

深層学習・機械学習・Pythonの素人でしたが、深層学習ブームの中、2015年の秋くらいから使い始めて、Chainer meetup(#3,#8)でも発表させて頂きました。

新しい機能もあまり使っていなかったので、しらばくこのままChainerを使い続けることもできますが、これを機にPyTorchを一度試してみました。

公式の移行ドキュメントを見ると、関数の対応など書いてあり、とても参考になります。

Chainer ⇒ PyTorchへの移行ドキュメント(公式)

以下は個人的な移行時のメモとして置いておきます。

PyTorch インストール

  • OS: Windows 10, ubuntu 18.04
  • GPU: RTX 2080
  • python 3.7(anaconda)
  • Cuda 10.1
  • Chainer 7.0.0a1
  • Cupy-cuda101 7.0.0a1

PyThorch公式からOSやPython,Cudaバージョンなどを選択すると以下のようなコマンドが表示されるので、それを実行するとPyTorchのインストールが5分足らずで完了します。

20191207_01.png

$ conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Windows・ubuntu両方、GPUでそのまま動いたので、Chainerで使っているCudaのバージョンが合えば、インストールはとても簡単なようです。

コードの移行

ChainerとPytorchはとても似ているので、だいたい対応するクラス・関数があります。
Trainerとかは使ってないので、そのあたりの変換については触れていません。

細かい関数の対応は公式の対応表が便利です。

以下のimportから学習までの簡単な全体コードはこちらに置きました

import 関係

# import chainer
# import chainer.links as L
# import chainer.functions as F
# from chainer import optimizers

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

データ型の変換

ChainerのValiableにあたるものは、Pytorchではtensorのようです。

  • Numpy ⇒ Variable, tensor
# x = chainer.Variable(x_array)
x = torch.tensor(x_array)
  • Variable, tensor ⇒ Numpy
# y_array = y.data
y_array = y.detach().numpy()

※グラフ形成後はy.detach()が必要なようです

  • CPU(Variable, tensor) ⇒ GPU(Variable, tensor)
# x.to_gpu()
x = x.to("cuda")
  • GPU(Variable, tensor) ⇒ CPU(Variable, tensor)
# y.to_cpu()
y = y.to("cpu")

ネットワーク

#class MLP(chainer.Chain):
#    def __init__(self):
#        super(MLP, self).__init__()
#        with self.init_scope():
#            self.l1 = L.Linear(None, 1000)  
#            self.l2 = L.Linear(None, 1000)  
#            self.l3 = L.Linear(None, 10)  
#
#    def forward(self, x):
#        h1 = F.relu(self.l1(x))
#        h2 = F.relu(self.l2(h1))
#        return self.l3(h2)


class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.l1 = nn.Linear(784, 1000)  
        self.l2 = nn.Linear(1000, 1000)  
        self.l3 = nn.Linear(1000, 10)  

    def forward(self, x):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        return self.l3(h2)

関数名が同じ名前の場合もあれば、L.Convolution2D ⇒ nn.Conv2d のように違う場合もあります。あまり調べていませんが、Noneにあたるものはつかえない?のかもしれません。

モデル・Optimizerセットアップ

# model = MLP()
# model.to_gpu()
# optimizer = optimizers.SGD(lr=0.01)
# optimizer.setup(model)

model = MLP()
model = model.to("cuda")
optimizer = optim.SGD(model.parameters(), lr=0.01)

学習

# y = model(x)
# loss = F.mean_squared_error(y, t)
# model.cleargrads()
# loss.backward()
# optimizer.update()

y = model(x)
loss = F.mse_loss(y, t)
model.zero_grad()
loss.backward()
optimizer.step()

最後に

今回とりあえず、今研究で使っているChainerのコードをPyTorchに手で書き換えを試して動かしてみました。Pytorchは全然使ったことはなかったですが、公式の移行ドキュメントやWebで都度調べるくらいで、1日で動くまでできました。基本的に似ているので、関数の対応を確認して、複数あるところは置換使ってというのを地道に続ければOKでした。

だた、動かしてみるとwindowsで約2割、ubuntuで約1割程度遅くなったので、いつ完全移行するかはゆっくり考えてみようと思います。

Chainerを使って4年経ちますが、Chainerがなかったら深層学習の世界に入ることはなく、普通のサラリーマンを続けていたかもしれません。良かったかはまだわかりませんが、研究生活はそれなりに楽しく過ごせております。

Chainerの皆様、ありがとうございました!

参考

30
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
27