45
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

pytorch 0.4の変更点

Last updated at Posted at 2018-05-02

もう先週になりますが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])

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

45
23
1

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
45
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?