Pytorch quickstart调用model.eval(),但不调用model.train()

Pytorch quickstart调用model.eval(),但不调用model.train(),pytorch,Pytorch,在Pytorch中,代码在评估/测试期间使用model.eval(),但在培训期间不调用model.train() 根据和,一些模块,如BatchNorm和Dropout需要知道模型是否处于训练或评估模式。本教程中的模型不使用任何此类模块,因此会运行到收敛。是我遗漏了什么,还是Pytorch的第一个教程实际上有一个逻辑错误 培训: def系列(数据加载器、型号、损耗、优化器): size=len(dataloader.dataset) 对于枚举(数据加载器)中的批处理(X,y): 十、 y=X.

在Pytorch中,代码在评估/测试期间使用
model.eval()
,但在培训期间不调用
model.train()

根据和,一些模块,如
BatchNorm
Dropout
需要知道模型是否处于训练或评估模式。本教程中的模型不使用任何此类模块,因此会运行到收敛。是我遗漏了什么,还是Pytorch的第一个教程实际上有一个逻辑错误

培训:

def系列(数据加载器、型号、损耗、优化器):
size=len(dataloader.dataset)
对于枚举(数据加载器)中的批处理(X,y):
十、 y=X.to(设备),y.to(设备)
#计算预测误差
pred=模型(X)
损失=损失_fn(pred,y)
#反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
如果批次%100==0:
损耗,当前=损耗。项(),批次*长度(X)
打印(f“丢失:{loss:>7f}[{current:>5d}/{size:>5d}]”)
您可以看到上述代码中没有
model.train()

测试:

def测试(数据加载器,型号): size=len(dataloader.dataset) model.eval() 测试损耗,正确=0,0 使用手电筒。无梯度() 对于数据加载器中的X,y: 十、 y=X.to(设备),y.to(设备) pred=模型(X) 测试损失+=损失(预测,y)。项目() correct+=(pred.argmax(1)=y).type(torch.float.sum().item() 测试损耗/=尺寸 正确/=大小 打印(f“测试错误:\n精度:{(100*正确):>0.1f}%,平均损耗:{测试损耗:>8f}\n”) 在第二行,有一个
model.eval()

培训循环:

epochs=5
对于范围内的t(历元):
打印(f“历元{t+1}\n--------------------------------”)
列车(列车数据加载器、模型、损耗、优化器)
测试(测试数据加载器,型号)
打印(“完成!”)
此循环调用
train()
test()
方法,而不调用
model.train()
。因此,在第一次调用
test()
之后,模型始终处于“评估”模式。如果我们在模型中添加一个
BatchNorm
,我们将遇到一个难以发现的bug

主要问题:


在培训期间总是调用
model.train()
,在评估/测试期间总是调用
model.eval()
,这是一种好的做法吗?

我认为这本身并不是一个逻辑错误,但可能应该包括它以供参考。但是,正如您所说,这个模型在训练和评估中运行得非常好,因为模型函数中没有依赖于训练的状态。@jhso我同意。他们应该两个都用,或者一个也不用。