このメソッドzero_grad()
は、トレーニング中に呼び出す必要があります。しかし、ドキュメントはあまり役に立ちません
| zero_grad(self)
| Sets gradients of all model parameters to zero.
なぜこのメソッドを呼び出す必要があるのですか?
このメソッドzero_grad()
は、トレーニング中に呼び出す必要があります。しかし、ドキュメントはあまり役に立ちません
| zero_grad(self)
| Sets gradients of all model parameters to zero.
なぜこのメソッドを呼び出す必要があるのですか?
回答:
では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
テンソルで呼び出されたときに発生します。
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