我有一个ResNet-8网络,用于一个基于图像的域适应项目,基本上我已经在一个数据集上训练了网络,现在我想在另一个模拟实时环境的数据集上对其进行评估,以尝试预测一个图像一次,但有趣的部分来了:
我想要对目标数据集进行评估的方法是对每张图像进行训练模式的前向通过,以便更新批处理规范层统计信息(使用torch.no_grad(),因为我不想这样做)然后更新网络参数,但仅“调整”批处理规范层),然后在评估模式下进行另一次前向传递以获取实际的预测,以便批处理规范层将基于看到的整个图像集使用均值和方差到目前为止(不仅是该批次的产品,在这种情况下还包括单个图像):
optimizer.zero_grad()
model.train()
with torch.no_grad():
output_train = model(inputs)
model.eval()
output_eval = model(inputs)
loss = criterion(output_eval, targets)
我的想法是仅通过将批处理规范层更新为新的目标分布来进行域自适应。
然后说完之后,我得到了60%的精度。
现在,如果我再加上另外两行,我就能达到80%的精度:
loss.backward()
optimizer.step()
因此,我的问题是,如果我在评估模式下执行back()和step()会发生什么?因为我知道训练模式和评估模式之间批处理规范层和退出层的不同行为,并且我知道torch.no_grad()以及如何计算梯度以及然后由优化程序更新参数的方法,但是我找不到任何信息关于我的具体问题。
我认为既然将模型设置为评估模式,那么这两行应该是无用的,但是显然会发生某些事情,这与批处理规范层的仿射参数有关吗?
更新:好的,我误会了一些情况:评估模式不会阻止要更新的参数,它只会更改前向传递过程中某些层(批处理规范和退出)的行为,对吗?因此,使用这两条线实际上是在训练网络,因此精度更高。无论如何,如果将批处理规范仿射设置为true,这会有所改变吗?那些参数被视为在Optimizer.step()期间要更新的“常规”参数还是不同?
最佳答案
评估模式不会阻止要更新的参数,它只会更改前向传递过程中某些层的行为(批处理规范和退出),对吗?
真正。
因此,使用这两条线实际上是在训练网络,因此精度更高。无论如何,如果将批处理规范仿射设置为true,这会有所改变吗?那些参数被视为在Optimizer.step()期间要更新的“常规”参数还是不同?
BN参数在优化程序步骤中更新。看:
if self.affine:
self.weight = Parameter(torch.Tensor(num_features))
self.bias = Parameter(torch.Tensor(num_features))
else:
self.register_parameter('weight', None)
self.register_parameter('bias', None)