私はpytorchでモデルを訓練しています。 10エポックごとに、トレーニングとテストデータセット全体のトレーニングとテストエラーを評価しています。何らかの理由で、評価関数がGPUでメモリ不足を引き起こしています。トレーニングと評価に同じバッチサイズを使用しているため、これは奇妙です。 net.forward()メソッドが繰り返し呼び出され、すべての非表示の値がメモリに格納されているためと考えられますが、これを回避する方法がわかりません。
def evaluate(self, data):
correct = 0
total = 0
loader = self.train_loader if data == "train" else self.test_loader
for step, (story, question, answer) in enumerate(loader):
story = Variable(story)
question = Variable(question)
answer = Variable(answer)
_, answer = torch.max(answer, 1)
if self.config.cuda:
story = story.cuda()
question = question.cuda()
answer = answer.cuda()
pred_prob = self.mem_n2n(story, question)[0]
_, output_max_index = torch.max(pred_prob, 1)
toadd = (answer == output_max_index).float().sum().data[0]
correct = correct + toadd
total = total + captions.size(0)
acc = correct / total
return acc
optimizer.zero_grad()
を使用しないため、検証中に失敗すると思います。 zero_gradはdetach
を実行し、テンソルを葉にします。これは、トレーニング部分のすべてのエポックで一般的に使用されます。
PyTorch 0.4.0のVariableでの揮発性フラグの使用は削除されました。参照- migration_guide_to_0.4.
0.4.0から、検証中に勾配が計算されないようにするには、torch.no_grad()を使用します
移行ガイドのコード例。
# evaluate
with torch.no_grad(): # operations inside don't track history
for input, target in test_loader:
...
0.3.Xの場合、volatileを使用するとうまくいくはずです。
評価中に使用されるすべての変数に対してvolatileフラグをTrueに設定して使用することをお勧めします。
story = Variable(story, volatile=True)
question = Variable(question, volatile=True)
answer = Variable(answer, volatile=True)
したがって、勾配と操作履歴は保存されず、多くのメモリを節約できます。また、バッチ処理の最後にこれらの変数への参照を削除することもできます。
del story, question, answer, pred_prob
モデルを評価モードに設定することを忘れないでください(評価が終了したら、トレーニングモードに戻ります)。たとえば、このように
model.eval()