pytorch Faster-RCNN 的验证损失

mar*_*ruf 7 python machine-learning object-detection computer-vision pytorch

我目前正在使用来自 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)
Run Code Online (Sandbox Code Playgroud)

但我不认为,这是验证的“正确”方式(因为某些特殊层,如 dropout 和 batch norm 在 eval/train 模式下的工作方式不同)。在 eval 模式下,模型返回预测的 bbox(如预期)。我可以为此使用一些内置函数吗?

谢谢。

mki*_*tal 6

这里对这个问题进行了一些讨论。结论是,在训练模式下计算验证损失是绝对有效的。val损失的数值本身没有意义,只有趋势对于防止过拟合很重要。因此,虽然训练模式确实改变了损失的数值,但它仍然可以有效使用。


然而,这里还存在另一个效率问题,如果您在验证过程中还需要模型输出(用于计算 IoU、准确性等,通常是这种情况)。现在,torchvision 中的 RCNN 可以为您提供损失或输出,具体取决于训练/评估模式。

更新: 不幸的是,我意识到这个修复不起作用。所有子模块都必须进行修补才能计算损失和输出。太糟糕了。

我的肮脏解决方案是修补继承GeneralizedRCNN的类 FasterRCNN。问题出在 这一 行,在eager_outputs(). 解决方法:

    return losses, detections

model = fasterrcnn_resnet50_fpn() model.eager_outputs =
eager_outputs_patch

Run Code Online (Sandbox Code Playgroud)

现在,您可以在一次推理运行后获得两个输出:model.train() with torch.no_grad(): loss_dict, outputs = model(images, targets). # yaay, now we have both!请注意,您仍然需要将模型置于训练模式才能获得损失。在 eval 模式GeneralizedRCNN的子模块(rpn、roi_heads)中不计算任何损失,并且loss_dict 为空。