python - pytorch Faster-RCNN 的验证损失
问题描述
我目前正在使用从 pytorch 预训练的 Faster-RCNN 模型(如 torchvision教程)中的迁移学习对自定义数据集进行对象检测。我想在每个时期结束时计算验证损失字典(如在训练模式下)。我可以在训练模式下运行模型进行验证,如下所示:
model.train()
for images, targets in data_loader_val:
images = [image.to(device) for image in images]
targets = [{k: v.to(device) for k, v in t.items()} for t in targets]
with torch.no_grad():
val_loss_dict = model(images, targets)
print(val_loss_dict)
但我不认为这是“正确”的验证方式(导致一些特殊层,如 dropout 和 batch norm 在 eval/train 模式下的工作方式不同)。并且在 eval 模式下,模型返回预测的 bbox(如预期的那样)。我可以为此使用一些内置功能吗?
谢谢。
解决方案
这里有一些关于这个问题的讨论。结论是在训练模式下计算验证损失是绝对有效的。val loss的数值本身没有意义,只有趋势对防止过拟合很重要。因此,虽然训练模式确实改变了损失的数值,但它仍然可以使用。
然而,这里还有另一个效率问题,如果您在验证过程中还需要模型输出(通常用于计算 IoU、准确性等)。现在,torchvision 中的 RCNN 会根据训练/评估模式为您提供损失或输出。
更新: 不幸的是,我意识到此修复程序不起作用。必须修补所有子模块以计算损失和输出。太糟糕了。
我的肮脏解决方案是修补继承的
GeneralizedRCNN
类FasterRCNN
。问题出在 这一 行,在eager_outputs()
. 解决方法:return losses, detections model = fasterrcnn_resnet50_fpn() model.eager_outputs = eager_outputs_patch
现在您可以在一次推理运行后获得两个输出:
model.train() with torch.no_grad(): loss_dict, outputs = model(images, targets). # yaay, now we have both!
请注意,您仍然需要将模型置于训练模式才能获得损失。在 eval modeGeneralizedRCNN
的子模块 (rpn, roi_heads) 不计算任何损失,并且loss_dict
是空的。
推荐阅读
- c++ - 如何使用 std::vector 使用参数化构造函数动态实例化一个类?
- c# - 具有会话时间跨度的单例类(对于每个浏览客户端).NET CORE
- postgresql - 带有 postgres 驱动程序的 JPA 流
- python - 在 python 中使用多线程时 GPU 内存使用量不会增加
- c# - 用C#在azure函数的body中读取一个4MB的json文件,在body读取部分进程挂起
- laravel - 如何使belongsToMany关系尊重枢轴模型中定义的全局范围
- javascript - textarea下的空白默认是什么?
- google-sheets - 使用公式在 Google 表格中进行日期标准化
- python - 如何使用 python docx 将 html 转换为 docx
- javascript - 从数组中获取元素,其加起来的值大于给定值 JavaScript