Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
23
Help us understand the problem. What is going on with this article?
@vintersnow

pytorch 0.4の変更点

More than 3 years have passed since last update.

もう先週になりますがpytorch0.4が出ました。
自分がpytorchを使い始めたのは0.3以降なので初めてのメジャー(?)バージョンアップになります。
1.0以下のバージョンアップはやはり安定しないもので、大きな変更がいくつかありますね。

主な変更点

Release notes

  • TensorとVariableの統合
  • ゼロ次元テンソル
  • dtypesとtesnorsの導入
  • advanced indexingの完全サポート
  • FFT
  • 計算グラフのチェックポイント機能
  • ボトルネック分析機能
  • 確率分布の拡充
  • ONNXでRNNのサポート
  • winodes対応

TensorとVariableの統合

0.4以降は何回もVariable(x)なんて書く必要がなくなりました!
Tensorに計算グラフを保持する機能が追加され、backwardすることが出来ます。

>>> x = torch.DoubleTensor([1,2,3])
>>> x
tensor([ 1.,  2.,  3.], dtype=torch.float64)
>>> x.requires_grad
False

デフォルトだとrequires_grad=Falseとなっており計算グラフを保持してくれないので、有効にするためにはmy_tensor.requires_grad_(requires_grad=True)を呼び出すか、有効な状態で作成する必要があります。

>>> x.requires_grad_()
tensor([ 1.,  2.,  3.], dtype=torch.float64)
>>> x.requires_grad
True
>>> y = torch.ones(1, requires_grad=True)
>>> y.requires_grad
True

いままでVariableからTensorを取り出すために.dataを使っていたと思いますが、0.4では.datarequires_grad=FalseとなったTensorを返すようになります。

>>> yd = y.data
>>> yd.requires_grad
False

ただ、.dataで計算グラフの途中のノードを参照して変更を行った場合逆伝播時に問題が起きるらしく、葉ノードを生成する.detach()の使用が推奨されているようです。(ここらへん良く理解できいなので後で調べます。)

ゼロ次元テンソル

いままではスカラーを表すテンソルは存在せず、長さ1のベクトルを代用していました。
なのでスカラ値を示すテンソルが出来ました。以上。

>>> a = torch.tensor(1)
>>> a
tensor(1)
>>> a.size()
torch.Size([])

これに伴いいくつかの関数の返り値が変わります。

>>> b = torch.arange(1,5)
>>> b
tensor([ 1.,  2.,  3.,  4.])
>>> b.sum()
tensor(10.)

ゼロ次元テンソルからpythonの値を取り出す場合、.item()を使います。
loss.data[0]と書く必要がなくなりました。
というより、ゼロ次元なのでindexingすると警告が出ます。0.5でエラーになるようです。

>>> loss.item()
1
>>> loss.data[0]
__main__:1: UserWarning: invalid index of a 0-dim tensor. This will be an error in PyTorch 0.5. Use tensor.item() to convert a 0-dim tensor to a Python number
tensor(1)

dtypes等の導入

Numpyに似たテンソルの作成方法が出来るようになりました。
いままでFloatTensorなどテンソルの作成にはクラスごとに使い分けていたのが、tensorの引数を変えることで出来るようになります。

>>> device = torch.device('cpu')
>>> torch.tensor([1,2,3], dtype=torch.float32, device=device)
tensor([ 1.,  2.,  3.])
>>> torch.randn(3, dtype=torch.float32, device=device)
tensor([ 1.6814, -0.6660,  0.7717])

dtypedevicelayoutをそれぞれ指定出来ます。

  • dtypeは型を表します
    • torch.float32torch.int32など
  • deviceは作成する場所を表します
    • cpucuda:0などで指定します。cudaと指定した場合デフォルトのGPUを使用します
  • layoutはテンソルのレイアウト(?)を表します
    • 現状密なテンソル(torch.strided)と疎なテンソル(torch.sparse_coo)が存在します

また.cudaの代わりに.to(device)というのが導入されました。
CPUとGPUの両方で使えるコードを以下のように作れます。

# いままで
model = Model()
if use_cuda:
    model = model.cuda()

# 0.4以降
device = torch.device('cuda:0')  # or 'cpu'
model = model.to(device)

deviceを共有することで、条件分岐などを無くスッキリ書けます。

advanced indexing

Numpyのadvanced indexingが使えるようになりました。
ブロードキャストなどです。
numpy芸は出来ないので、なにが出来るようになったのか実感がないですが、便利なのでしょう。

計算グラフのチェックポイント

ニューラルネットワークの計算時には逆伝播のために計算結果をすべて保持する必要がありメモリを大変食います。
そこで、一度計算結果を捨てて逆伝播の時に必要となったら再計算することで使用メモリを減らすチェックポイントを作れるようになりました。
再計算するため訓練速度は落ちますが、重いのは大抵逆伝播の処理なので訓練時間が数倍になったりはしないと思います。

プロファイリングのためのツールの追加

ボトルネックを見つけるためのtorch.utils.bottleneckが追加されたようです。
0.3の時点でGPU usageを見るものはあった気がしますがどう変更されたのか気になりますね。
bottleneck docs

その他細かい変更

einsumの導入

tensorflowで使えたenisumが使えるようになりました。

>>> w = torch.tensor([[1,2], [2,3]])
>>> v = torch.tensor([3,4])
>>> torch.einsum('ik,k->i', (w, v))
tensor([ 11,  18])

速度的にどうなのか分かりませんが、複雑な演算をしたい時に便利です。

23
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
vintersnow
情熱のない大人になってしまった

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
23
Help us understand the problem. What is going on with this article?