web-dev-qa-db-ja.com

PyTorchによるインプレース操作

PyTorchのインプレースオペレーションを処理する方法を知りたいと思っていました。私が覚えているように、autogradでインプレース操作を使用することは常に問題がありました。

そして、実際には、以下のコードが機能することに驚いています。テストしていませんが、このコードはバージョン0.3.1でエラーを発生させたと思います。

基本的には、テンソルベクトルの特定の位置を次のように特定の値に設定します。

my_tensor[i] = 42

作業例コード:

# test parameter a
a = torch.Rand((2), requires_grad=True)
print('a ', a)
b = torch.Rand(2)

# calculation
c = a + b

# performing in-place operation
c[0] = 0
print('c ', c)
s = torch.sum(c)
print('s ', s)

# calling backward()
s.backward()

# optimizer step
optim = torch.optim.Adam(params=[a], lr=0.5)
optim.step()

# changed parameter a
print('changed a', a)

出力:

a  tensor([0.2441, 0.2589], requires_grad=True)
c  tensor([0.0000, 1.1511], grad_fn=<CopySlices>)
s  tensor(1.1511, grad_fn=<SumBackward0>)
changed a tensor([ 0.2441, -0.2411], requires_grad=True)

明らかにバージョン0.4.1では。これは警告やエラーなしで問題なく機能します。

ドキュメントのこの記事を参照: autograd-mechanics

Autogradでのインプレース操作のサポートは難しい問題であり、ほとんどの場合、それらの使用はお勧めしません。 Autogradの積極的なバッファの解放と再利用により、非常に効率的になり、インプレース操作で実際にメモリ使用量が大幅に低下することはほとんどありません。 メモリの負荷が高い場合を除いて、それらを使用する必要がない場合があります。

しかし、それが機能したとしても、ほとんどの場合、インプレース操作の使用は推奨されません。


だから私の質問は:

  • muchインプレース操作の使用はパフォーマンスにどのように影響しますか?

  • テンソルの1つの要素を特定の値に設定したい場合に、インプレース操作をどのように回避しますか?

前もって感謝します!

14
MBT

インプレース操作がパフォーマンスにどの程度影響するかはわかりませんが、2番目のクエリに対処できます。インプレースopsの代わりにマスクを使用できます。

a = torch.Rand((2), requires_grad=True)
print('a ', a)
b = torch.Rand(2)

# calculation
c = a + b

# performing in-place operation
mask = np.zeros(2)
mask[1] =1
mask = torch.tensor(mask)
c = c*mask
...
2
Umang Gupta

2番目のクエリでは、c[i] = iまたは同様の操作、__setitem__は通常呼び出されます。その操作をインプレースにするために、__setitem__関数(それがc[i] = i操作。

0
BBloggsbott