backwardでエラーが発生
GANについてこの参考書をもとに勉強していたところ、エラーが発生。
解決に2日かかったので、記録として残します。
結論は、初心者にとって勝手な変更は厳禁ですね。
参考書
GANディープラーニング実装ハンドブック
エラー内容
GANの学習中にbackwardで逆伝播させるときにエラーが発生
例外が発生しました: RuntimeError
one of the variables needed for gradient computation has been modified by an inplace operation
参考書の通りに実施したのになぜと思っていた。。。
この逆伝播の時に発生
loss.bakward()
エラー内容は「PyTorchでの計算グラフ内の変数がインプレース(その場での変更)操作によって変更されたことが原因」のようで、このbackwardで更新される以外に、勝手にversionが書き変わってて、変数を変更していませんか?って事らしい
エラー全体はこんな感じ
例外が発生しました: RuntimeError
one of the variables needed for gradient computation has been modified by an inplace operation:
[MPSFloatType [1, 1024, 1, 1]] is at version 3; expected version 2 instead. Hint: the backtrace further above shows the operation that failed to compute its gradient.
The variable in question was changed in there or anywhere later. Good luck!
File "/Users/sm/VScode/EfficientGAN/main.py", line 233, in <module>
loss_ge.backward(retain_graph = True)
エラー原因
エラー原因はシンプルでした。
GeneratorとEncoderのlossの計算のときにDiscriminatorの損失計算と逆伝播で使用したp-trueをそのまま使っていたこと。そのため、loss_geのbackwardを計算するときに、すでにloss_dで損失の更新がなされてしまっていたので、loss_geのbackwardでのエラーとなった。
エラー発生コード(一部省略・変更)
# discriminatorの学習
optimizer_d.zero_grad()
E_x = model_Encode(x)
# 識別器からp_trueを取得
p_true, _ = model_Discriminate(x + noise1, E_x)
# (中略)
loss_d = criterion(p_true, y_true)
#ここで逆電波して識別器の学習をしている
loss_d.backward(retain_graph = True)
optimizer_d.step()
# generatorとencoderの学習
optimizer_ge.zero_grad()
G_E_x = model_Generate(E_x)
E_G_z = model_Encode(G_z)
# p_trueをもう一度取得 これを削除していたためエラーの原因となった
p_true, _ = model_Discriminate(x + noise1, E_x)
loss_ge = criterion(p_true, y_fake)
# (中略)
# このbackwardでエラー発生
loss_ge.backward(retain_graph = True)
optimizer_ge.step()