pytorch Mask-RCNN的哪些参数控制面罩召回?

rryofs0p  于 2022-12-26  发布在  其他
关注(0)|答案(1)|浏览(150)

我对微调我正在使用的Mask-RCNN模型很感兴趣,例如分割。目前我已经训练了6个时期的模型,各种Mask-RCNN损失如下:

我停下来的原因是COCO评估指标似乎在上一个时期有所下降:

我知道这是一个影响深远的问题,但我希望获得一些直觉,了解如何理解哪些参数对改进评估指标最有影响。我知道有三个方面需要考虑:
1.我是否应该查看批量大小、学习率和动量,这使用了学习率为1 e-4、批量大小为2的SGD优化器?
1.我应该考虑使用更多的训练数据或添加增强(我目前没有使用任何),我的数据集是目前相当大的40 K图像?
1.我是否应该查看特定的MaskRCNN参数?
我想我可能会被问到我想要改进什么,所以让我说,我想提高个别面具的回忆。该模型表现良好,但没有完全捕捉到我想要它的全部扩展。我还省略了具体学习问题的细节,因为我想获得如何处理这个问题的一般直觉。

bd1hkmkf

bd1hkmkf1#

几点注意事项:

  • 6个历元对于网络收敛来说太小了,即使你使用一个预先训练的网络-特别是像resnet50这样的大网络。我认为你至少需要50个历元。在一个预先训练的resnet18上,我在30个历元之后开始得到好的结果,resnet34需要+10 -20个历元,而你的resnet50 + 40k火车集图像-肯定需要比6更多的历元;
  • 明确使用预先训练的网络;
  • 根据我的经验,我没有得到我喜欢的结果与SGD。我开始使用AdamW + ReduceLROnPlateau调度器。网络收敛相当快,像50 - 60% AP在epoch 7或8,但然后它来了80 - 85后,50 - 60 epoch使用非常小的改进从epoch到epoch,只要LR足够小,你们一定很熟悉梯度下降的概念,我曾经认为它就像你有更多的增强,你的"山"被"巨石"覆盖,你必须能够绕过,这只有在你控制LR的情况下才有可能。另外,AdamW可以帮助解决过度拟合问题。这就是我的做法。对于具有较高输入分辨率的网络(输入图像由网络本身缩放),我使用较高的LR。

init_lr = 0.00005 weight_decay = init_lr * 100 optimizer = torch.optim.AdamW(params, lr=init_lr, weight_decay=weight_decay) scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, verbose=True, patience=3, factor=0.75)
对于范围内的时段(时段):#训练一个时期,每10次迭代打印metric_logger =训练一个时期(模型、优化器、训练加载器、定标器、设备、时期、打印频率= 10)

scheduler.step(metric_logger.loss.global_avg)
  optimizer.param_groups[0]["weight_decay"] = optimizer.param_groups[0]["lr"] * 100

  # scheduler.step()

  # evaluate on the test dataset
  evaluate(model, test_loader, device=device)

  print("[INFO] serializing model to '{}' ...".format(args["model"]))
  save_and_print_size_of_model(model, args["model"], script=False)

找到这样一个LR和权重衰减,使得训练在训练结束时将LR耗尽到一个非常小的值,比如初始LR的1/10。如果你经常有一个平台期,调度器会很快将它带到非常小的值,网络在剩下的时间里什么也学不到。
你的图表显示你的LR在训练中的某个点太高了,网络停止训练,然后AP下降。你需要不断的改进,即使是很小的改进。网络训练越多,它对你的域了解的细节就越微妙,学习率就越小。恕我直言,恒定的LR不允许正确地做到这一点。

  • 锚发电机设置。2这是我如何初始化网络。
def get_maskrcnn_resnet_model(name, num_classes, pretrained, res='normal'):
      print('Using maskrcnn with {} backbone...'.format(name))

      backbone = resnet_fpn_backbone(name, pretrained=pretrained, trainable_layers=5)

      sizes = ((4,), (8,), (16,), (32,), (64,))
      aspect_ratios = ((0.25, 0.5, 1.0, 2.0, 4.0),) * len(sizes)
      anchor_generator = AnchorGenerator(
          sizes=sizes, aspect_ratios=aspect_ratios
      )

      roi_pooler = torchvision.ops.MultiScaleRoIAlign(featmap_names=['0', '1', '2', '3'],
                                                      output_size=7, sampling_ratio=2)

      default_min_size = 800
      default_max_size = 1333

      if res == 'low':
          min_size = int(default_min_size / 1.25)
          max_size = int(default_max_size / 1.25)
      elif res == 'normal':
          min_size = default_min_size
          max_size = default_max_size
      elif res == 'high':
          min_size = int(default_min_size * 1.25)
          max_size = int(default_max_size * 1.25)
      else:
          raise ValueError('Invalid res={} param'.format(res))

      model = MaskRCNN(backbone, min_size=min_size, max_size=max_size, num_classes=num_classes,
                       rpn_anchor_generator=anchor_generator, box_roi_pool=roi_pooler)

      model.roi_heads.detections_per_img = 512
      return model

我需要在这里找到小对象,为什么我使用这样的锚参数。

  • 类平衡问题。如果你只有你的对象和背景-没有问题。如果你有更多的类,然后确保你的训练分裂(作为80%的训练和20%的测试)是或多或少精确地适用于所有类使用在您的特定训练。

祝你好运!

相关问题