PyTorchでzero_grad()を呼び出す必要があるのはなぜですか?


回答:


163

ではPyTorch、PyTorch後続の逆方向パスで勾配累積するため逆伝播を開始する前に勾配をゼロに設定する必要があります。これは、RNNのトレーニング中に便利です。したがって、デフォルトのアクションは、すべての呼び出しで勾配累積(つまり合計)することloss.backward()です。

このため、トレーニングループを開始するときzero out the gradientsは、パラメータの更新を正しく行うようにするのが理想的です。それ以外の場合、勾配は、最小(または最大化の目的の場合は最大)に向かう意図された方向以外の方向を指します。

簡単な例を次に示します。

import torch
from torch.autograd import Variable
import torch.optim as optim

def linear_model(x, W, b):
    return torch.matmul(x, W) + b

data, targets = ...

W = Variable(torch.randn(4, 3), requires_grad=True)
b = Variable(torch.randn(3), requires_grad=True)

optimizer = optim.Adam([W, b])

for sample, target in zip(data, targets):
    # clear out the gradients of all Variables 
    # in this optimizer (i.e. W, b)
    optimizer.zero_grad()
    output = linear_model(sample, W, b)
    loss = (output - target) ** 2
    loss.backward()
    optimizer.step()

また、あなたがやっている場合はバニラ勾配降下を、次のようになります。

W = Variable(torch.randn(4, 3), requires_grad=True)
b = Variable(torch.randn(3), requires_grad=True)

for sample, target in zip(data, targets):
    # clear out the gradients of Variables 
    # (i.e. W, b)
    W.grad.data.zero_()
    b.grad.data.zero_()

    output = linear_model(sample, W, b)
    loss = (output - target) ** 2
    loss.backward()

    W -= learning_rate * W.grad.data
    b -= learning_rate * b.grad.data

:勾配の累積(つまり合計)は.backward()、がlossテンソルで呼び出されたときに発生します。


3

zero_grad() エラー(または損失)を減らすために勾配法を使用する場合、最後のステップから損失なしでループを再開します。

使用しない場合zero_grad()、損失は減少し、必要に応じて増加しません。

例えば:

を使用zero_grad()すると、次の出力が得られます。

model training loss is 1.5
model training loss is 1.4
model training loss is 1.3
model training loss is 1.2

使用しないzero_grad()場合は、次の出力が得られます。

model training loss is 1.4
model training loss is 1.9
model training loss is 2
model training loss is 2.8
model training loss is 3.5
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.