💻 源码
# pytorh相关的工具包
import torch
import torchvision
import torchvision.transforms as transforms
# from torchvision.io import read_image
# 读取图像的工具包
from PIL import Image
# 绘图
import matplotlib.pyplot as plt

数据加载

img = Image.open('img2.jpg')
img.size
(994, 734)
plt.imshow(img)
<matplotlib.image.AxesImage at 0x180689d6688><Figure size 432x288 with 1 Axes>
transform = transforms.Compose([transforms.ToTensor(),transforms.Resize((800,800))])
img = transform(img)
img.shape
torch.Size([3, 800, 800])
plt.imshow(img.permute(1,2,0))
<matplotlib.image.AxesImage at 0x7f97b5ce4278><Figure size 432x288 with 1 Axes>

模型加载

model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
Downloading: "https://download.pytorch.org/models/fasterrcnn_resnet50_fpn_coco-258fb6c6.pth" to C:\Users\14767/.cache\torch\hub\checkpoints\fasterrcnn_resnet50_fpn_coco-258fb6c6.pth
HBox(children=(FloatProgress(value=0.0, max=167502836.0), HTML(value='')))
model.eval()
FasterRCNN(
  (transform): GeneralizedRCNNTransform(
      Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
      Resize(min_size=(800,), max_size=1333, mode='bilinear')
  )
  (backbone): BackboneWithFPN(
    (body): IntermediateLayerGetter(
      (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
      (bn1): FrozenBatchNorm2d(64, eps=0.0)
      (relu): ReLU(inplace=True)
      (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
      (layer1): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(64, eps=0.0)
          (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(64, eps=0.0)
          (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(256, eps=0.0)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
            (1): FrozenBatchNorm2d(256, eps=0.0)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(64, eps=0.0)
          (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(64, eps=0.0)
          (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(256, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(64, eps=0.0)
          (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(64, eps=0.0)
          (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(256, eps=0.0)
          (relu): ReLU(inplace=True)
        )
      )
      (layer2): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(128, eps=0.0)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(128, eps=0.0)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(512, eps=0.0)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
            (1): FrozenBatchNorm2d(512, eps=0.0)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(128, eps=0.0)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(128, eps=0.0)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(512, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(128, eps=0.0)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(128, eps=0.0)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(512, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (3): Bottleneck(
          (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(128, eps=0.0)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(128, eps=0.0)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(512, eps=0.0)
          (relu): ReLU(inplace=True)
        )
      )
      (layer3): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=0.0)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=0.0)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=0.0)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)
            (1): FrozenBatchNorm2d(1024, eps=0.0)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=0.0)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=0.0)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=0.0)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=0.0)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (3): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=0.0)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=0.0)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (4): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=0.0)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=0.0)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (5): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=0.0)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=0.0)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=0.0)
          (relu): ReLU(inplace=True)
        )
      )
      (layer4): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(512, eps=0.0)
          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(512, eps=0.0)
          (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(2048, eps=0.0)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)
            (1): FrozenBatchNorm2d(2048, eps=0.0)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(512, eps=0.0)
          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(512, eps=0.0)
          (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(2048, eps=0.0)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(512, eps=0.0)
          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(512, eps=0.0)
          (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(2048, eps=0.0)
          (relu): ReLU(inplace=True)
        )
      )
    )
    (fpn): FeaturePyramidNetwork(
      (inner_blocks): ModuleList(
        (0): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1))
        (1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))
        (2): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1))
        (3): Conv2d(2048, 256, kernel_size=(1, 1), stride=(1, 1))
      )
      (layer_blocks): ModuleList(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      )
      (extra_blocks): LastLevelMaxPool()
    )
  )
  (rpn): RegionProposalNetwork(
    (anchor_generator): AnchorGenerator()
    (head): RPNHead(
      (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (cls_logits): Conv2d(256, 3, kernel_size=(1, 1), stride=(1, 1))
      (bbox_pred): Conv2d(256, 12, kernel_size=(1, 1), stride=(1, 1))
    )
  )
  (roi_heads): RoIHeads(
    (box_roi_pool): MultiScaleRoIAlign(featmap_names=['0', '1', '2', '3'], output_size=(7, 7), sampling_ratio=2)
    (box_head): TwoMLPHead(
      (fc6): Linear(in_features=12544, out_features=1024, bias=True)
      (fc7): Linear(in_features=1024, out_features=1024, bias=True)
    )
    (box_predictor): FastRCNNPredictor(
      (cls_score): Linear(in_features=1024, out_features=91, bias=True)
      (bbox_pred): Linear(in_features=1024, out_features=364, bias=True)
    )
  )
)

模型预测

# coco数据集的class,共90个类别:人,自行车,火车,。。。
coco_names = [
    '__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus',
    'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'N/A', 'stop sign',
    'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
    'elephant', 'bear', 'zebra', 'giraffe', 'N/A', 'backpack', 'umbrella', 'N/A', 'N/A',
    'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
    'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket',
    'bottle', 'N/A', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl',
    'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
    'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'N/A', 'dining table',
    'N/A', 'N/A', 'toilet', 'N/A', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
    'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'N/A', 'book',
    'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'
]
pred = model([img])
/Users/mac/opt/anaconda3/envs/dltorch/lib/python3.7/site-packages/torch/functional.py:445: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at  ../aten/src/ATen/native/TensorShape.cpp:2157.)
  return _VF.meshgrid(tensors, **kwargs)  # type: ignore[attr-defined]
pred
[{'boxes': tensor([[ 31.7399, 328.4528, 460.8738, 793.4400],
          [  5.6514,  88.6435, 216.9703, 635.1252],
          [367.4497, 225.4498, 762.0249, 789.4284],
          [607.8991, 152.3864, 795.5750, 372.0394],
          [183.5409,  34.5758, 396.0948, 661.7242],
          [364.9885,  43.9209, 525.7601, 586.4974],
          [ 13.4759, 211.1637, 290.4755, 748.9048],
          [307.3405,   4.9721, 439.2374, 111.8531],
          [383.3587, 180.4190, 578.4739, 772.2529],
          [407.8741, 139.6278, 681.9370, 533.0029],
          [711.5732,   5.5169, 758.7169, 120.2260],
          [479.1790, 144.8082, 689.6121, 400.8835],
          [244.1306,  36.7394, 487.5280, 744.1151],
          [546.8978, 474.4509, 568.8634, 552.9698],
          [742.9993, 314.1062, 798.9455, 607.5062],
          [742.6909, 317.4082, 796.8760, 619.5782],
          [524.8398, 475.1719, 576.5832, 769.7741],
          [509.4732, 142.5110, 623.7419, 301.2690],
          [469.8165, 142.4818, 800.0000, 396.9042],
          [178.5640, 253.6984, 659.5800, 785.6712],
          [365.3784, 474.1786, 470.2338, 769.1154],
          [160.4500, 265.7687, 387.0724, 610.2078],
          [481.0141, 153.0264, 720.3257, 699.9622],
          [724.8939, 343.9777, 798.2111, 726.9193],
          [439.7558, 568.3492, 517.4477, 787.6546],
          [730.4789, 277.5797, 798.6329, 788.0072],
          [409.8385, 474.7333, 540.6846, 793.6932],
          [720.9894, 114.6369, 753.7390, 180.1143],
          [690.4725, 317.8017, 798.0597, 600.9917],
          [548.9393,  76.3451, 613.9292, 172.6772],
          [720.4436, 118.2152, 754.2703, 179.3526],
          [556.6137, 479.1154, 576.5483, 542.2100],
          [514.3457, 148.3877, 619.4744, 501.8499],
          [197.1474, 368.7211, 431.1885, 764.1635],
          [333.9739, 126.6342, 411.8326, 199.1039],
          [659.6864, 131.1151, 716.2268, 168.4116],
          [318.3166, 531.7626, 407.8087, 717.9441],
          [348.7296,   1.2086, 435.9537,  75.7988]], grad_fn=<StackBackward0>),
  'labels': tensor([ 1,  1,  1, 72,  1,  1,  1, 72,  1,  1, 86,  1,  1, 32, 63, 62, 32,  1,
          72,  1, 32,  1,  1, 63, 32, 62, 32, 44, 63, 72, 86, 32,  1,  1, 79, 85,
          32, 72]),
  'scores': tensor([0.9966, 0.9899, 0.9894, 0.9877, 0.9701, 0.9598, 0.8676, 0.7946, 0.6888,
          0.6239, 0.5967, 0.5822, 0.5759, 0.5339, 0.5014, 0.4489, 0.3447, 0.3405,
          0.2513, 0.2067, 0.1989, 0.1979, 0.1844, 0.1780, 0.1268, 0.0884, 0.0864,
          0.0813, 0.0766, 0.0748, 0.0731, 0.0704, 0.0678, 0.0637, 0.0592, 0.0554,
          0.0535, 0.0532], grad_fn=<IndexBackward0>)}]
list(pred[0]['labels'].numpy())
[1,
 1,
 1,
 72,
 1,
 1,
 1,
 72,
 1,
 1,
 86,
 1,
 1,
 32,
 63,
 62,
 32,
 1,
 72,
 1,
 32,
 1,
 1,
 63,
 32,
 62,
 32,
 44,
 63,
 72,
 86,
 32,
 1,
 1,
 79,
 85,
 32,
 72]
pred_class = [coco_names[i] for i in list(pred[0]['labels'].numpy())]
pred_class
['person',
 'person',
 'person',
 'tv',
 'person',
 'person',
 'person',
 'tv',
 'person',
 'person',
 'vase',
 'person',
 'person',
 'tie',
 'couch',
 'chair',
 'tie',
 'person',
 'tv',
 'person',
 'tie',
 'person',
 'person',
 'couch',
 'tie',
 'chair',
 'tie',
 'bottle',
 'couch',
 'tv',
 'vase',
 'tie',
 'person',
 'person',
 'oven',
 'clock',
 'tie',
 'tv']
pred[0]['boxes'].detach().numpy()
array([[ 31.739914 , 328.45282  , 460.87378  , 793.44     ],
       [  5.65139  ,  88.64346  , 216.97028  , 635.12524  ],
       [367.4497   , 225.44983  , 762.0249   , 789.4284   ],
       [607.8991   , 152.38641  , 795.575    , 372.03937  ],
       [183.54091  ,  34.575836 , 396.09485  , 661.72424  ],
       [364.9885   ,  43.92093  , 525.76013  , 586.49744  ],
       [ 13.475891 , 211.1637   , 290.47552  , 748.90485  ],
       [307.3405   ,   4.9721336, 439.23743  , 111.85315  ],
       [383.3587   , 180.41904  , 578.47394  , 772.2529   ],
       [407.8741   , 139.62776  , 681.937    , 533.0029   ],
       [711.57324  ,   5.516918 , 758.7169   , 120.22604  ],
       [479.17905  , 144.80818  , 689.61206  , 400.88348  ],
       [244.13058  ,  36.73944  , 487.52798  , 744.1151   ],
       [546.8978   , 474.45093  , 568.8634   , 552.96985  ],
       [742.9993   , 314.10623  , 798.9455   , 607.5062   ],
       [742.6909   , 317.40823  , 796.876    , 619.57825  ],
       [524.8398   , 475.17194  , 576.5832   , 769.7741   ],
       [509.47318  , 142.51099  , 623.74194  , 301.26895  ],
       [469.81653  , 142.48177  , 800.       , 396.90424  ],
       [178.56403  , 253.69843  , 659.58     , 785.6712   ],
       [365.37836  , 474.17865  , 470.23376  , 769.1154   ],
       [160.45001  , 265.76874  , 387.07245  , 610.2078   ],
       [481.0141   , 153.0264   , 720.32574  , 699.96216  ],
       [724.8939   , 343.97772  , 798.21106  , 726.91925  ],
       [439.75577  , 568.3492   , 517.4477   , 787.6546   ],
       [730.47894  , 277.57974  , 798.6329   , 788.0072   ],
       [409.8385   , 474.73334  , 540.68463  , 793.6932   ],
       [720.98944  , 114.63695  , 753.73895  , 180.11427  ],
       [690.47253  , 317.80173  , 798.0597   , 600.9917   ],
       [548.93933  ,  76.3451   , 613.9292   , 172.67722  ],
       [720.4436   , 118.215164 , 754.27026  , 179.35258  ],
       [556.6137   , 479.11536  , 576.5483   , 542.21     ],
       [514.3457   , 148.38771  , 619.47437  , 501.8499   ],
       [197.14737  , 368.72107  , 431.1885   , 764.16345  ],
       [333.97394  , 126.63425  , 411.83258  , 199.10388  ],
       [659.6864   , 131.11514  , 716.2268   , 168.41156  ],
       [318.3166   , 531.7626   , 407.80872  , 717.9441   ],
       [348.72955  ,   1.2085876, 435.95374  ,  75.7988   ]],
      dtype=float32)
pred_box = [[(box[0],box[1]),(box[2],box[3])] for box in list(pred[0]['boxes'].detach().numpy())]
pred_box
[[(31.739914, 328.45282), (460.87378, 793.44)],
 [(5.65139, 88.64346), (216.97028, 635.12524)],
 [(367.4497, 225.44983), (762.0249, 789.4284)],
 [(607.8991, 152.38641), (795.575, 372.03937)],
 [(183.54091, 34.575836), (396.09485, 661.72424)],
 [(364.9885, 43.92093), (525.76013, 586.49744)],
 [(13.475891, 211.1637), (290.47552, 748.90485)],
 [(307.3405, 4.9721336), (439.23743, 111.85315)],
 [(383.3587, 180.41904), (578.47394, 772.2529)],
 [(407.8741, 139.62776), (681.937, 533.0029)],
 [(711.57324, 5.516918), (758.7169, 120.22604)],
 [(479.17905, 144.80818), (689.61206, 400.88348)],
 [(244.13058, 36.73944), (487.52798, 744.1151)],
 [(546.8978, 474.45093), (568.8634, 552.96985)],
 [(742.9993, 314.10623), (798.9455, 607.5062)],
 [(742.6909, 317.40823), (796.876, 619.57825)],
 [(524.8398, 475.17194), (576.5832, 769.7741)],
 [(509.47318, 142.51099), (623.74194, 301.26895)],
 [(469.81653, 142.48177), (800.0, 396.90424)],
 [(178.56403, 253.69843), (659.58, 785.6712)],
 [(365.37836, 474.17865), (470.23376, 769.1154)],
 [(160.45001, 265.76874), (387.07245, 610.2078)],
 [(481.0141, 153.0264), (720.32574, 699.96216)],
 [(724.8939, 343.97772), (798.21106, 726.91925)],
 [(439.75577, 568.3492), (517.4477, 787.6546)],
 [(730.47894, 277.57974), (798.6329, 788.0072)],
 [(409.8385, 474.73334), (540.68463, 793.6932)],
 [(720.98944, 114.63695), (753.73895, 180.11427)],
 [(690.47253, 317.80173), (798.0597, 600.9917)],
 [(548.93933, 76.3451), (613.9292, 172.67722)],
 [(720.4436, 118.215164), (754.27026, 179.35258)],
 [(556.6137, 479.11536), (576.5483, 542.21)],
 [(514.3457, 148.38771), (619.47437, 501.8499)],
 [(197.14737, 368.72107), (431.1885, 764.16345)],
 [(333.97394, 126.63425), (411.83258, 199.10388)],
 [(659.6864, 131.11514), (716.2268, 168.41156)],
 [(318.3166, 531.7626), (407.80872, 717.9441)],
 [(348.72955, 1.2085876), (435.95374, 75.7988)]]
# 图像读取
img = Image.open('img2.jpg').resize((800,800))
# 图像展示
fig = plt.imshow(img)
# 将框绘制在图像上
for index, boxes in enumerate(pred_box):
    fig.axes.add_patch(plt.Rectangle(
    xy=(boxes[0]), width=boxes[1][0]-boxes[0][0], height=boxes[1][1]-boxes[0][1],
    fill=False, edgecolor="blue", linewidth=1))
plt.show()
<Figure size 432x288 with 1 Axes>
the = 0.7
pred_score = list(pred[0]['scores'].detach().numpy())
pred_score
[0.99662447,
 0.98991066,
 0.9894002,
 0.9877265,
 0.9700843,
 0.95981795,
 0.86762965,
 0.79457456,
 0.6888022,
 0.6238965,
 0.5967382,
 0.5821962,
 0.5758556,
 0.53390706,
 0.50142986,
 0.4489189,
 0.3446656,
 0.34053934,
 0.25132728,
 0.20674044,
 0.19888856,
 0.19792202,
 0.18443534,
 0.17802832,
 0.12675783,
 0.08840103,
 0.08642756,
 0.08125935,
 0.07662633,
 0.0747837,
 0.07308833,
 0.07040265,
 0.06783704,
 0.063683495,
 0.0592302,
 0.055396155,
 0.053475436,
 0.053160064]
pred_t = [pred_score.index(score) for score in pred_score if score > the]
index = pred_t[-1]
pred_box = pred_box[:index+1]
pred_box
[[(31.739914, 328.45282), (460.87378, 793.44)],
 [(5.65139, 88.64346), (216.97028, 635.12524)],
 [(367.4497, 225.44983), (762.0249, 789.4284)],
 [(607.8991, 152.38641), (795.575, 372.03937)],
 [(183.54091, 34.575836), (396.09485, 661.72424)],
 [(364.9885, 43.92093), (525.76013, 586.49744)],
 [(13.475891, 211.1637), (290.47552, 748.90485)],
 [(307.3405, 4.9721336), (439.23743, 111.85315)]]
# 图像读取
img = Image.open('img2.jpg').resize((800,800))
# 图像展示
fig = plt.imshow(img)
# 将框绘制在图像上
for index, boxes in enumerate(pred_box):
    fig.axes.add_patch(plt.Rectangle(
    xy=(boxes[0]), width=boxes[1][0]-boxes[0][0], height=boxes[1][1]-boxes[0][1],
    fill=False, edgecolor="blue", linewidth=1))
plt.show()
<Figure size 432x288 with 1 Axes>
pred_class[:index+1]
['person', 'person', 'person', 'tv', 'person', 'person', 'person', 'tv']

模型结构详解

backbone

transform = transforms.Compose([transforms.ToTensor(),transforms.Resize((800,800))])
img = transform(img)
img.shape
torch.Size([3, 800, 800])
imgs,targets= model.transform([img],targets=None)
imgs
<torchvision.models.detection.image_list.ImageList at 0x7f97769e3908>
feature_body= model.backbone.body(imgs.tensors)
C2,C3,C4,C5 = feature_body.values()
C2.size()
torch.Size([1, 256, 200, 200])
C3.size()
torch.Size([1, 512, 100, 100])
C4.size()
torch.Size([1, 1024, 50, 50])
C5.size()
torch.Size([1, 2048, 25, 25])
feature_fpn=model.backbone.fpn(feature_body)
P2,P3,P4,P5,P6=feature_fpn.values()
P2.size()
torch.Size([1, 256, 200, 200])
P3.size()
torch.Size([1, 256, 100, 100])
P4.size()
torch.Size([1, 256, 50, 50])
P5.size()
torch.Size([1, 256, 25, 25])
P6.size()
torch.Size([1, 256, 13, 13])

RPN

anchors = model.rpn.anchor_generator(imgs,[P2,P3,P4,P5,P6])
anchors
[tensor([[ -23.,  -11.,   23.,   11.],
         [ -16.,  -16.,   16.,   16.],
         [ -11.,  -23.,   11.,   23.],
         ...,
         [ 370.,  551., 1094.,  913.],
         [ 476.,  476.,  988.,  988.],
         [ 551.,  370.,  913., 1094.]])]
anchors[0].size()
torch.Size([159882, 4])
# 将生成的anchor绘制在图像上
img_anchor = Image.open('img2.jpg').resize((800,800))
# 绘制图像
fig = plt.imshow(img_anchor)
# 将框绘制在图像上
for index, boxes in enumerate(anchors[0]):
    if index <300:
        fig.axes.add_patch(plt.Rectangle(
            xy=(boxes[0],boxes[1]), width=boxes[2]-boxes[0], height=boxes[3]-boxes[1],
            fill=False, edgecolor="red", linewidth=1))
plt.show()
<Figure size 432x288 with 1 Axes>
cls_logits = model.rpn.head.cls_logits(P3)
cls_logits.size()
torch.Size([1, 3, 100, 100])
bbox_pred = model.rpn.head.bbox_pred(P4)
bbox_pred.size()
torch.Size([1, 12, 50, 50])
proposal = model.rpn(imgs,feature_fpn)
proposal
([tensor([[162.3166,  82.6454, 390.0235, 638.2616],
          [  0.0000,  45.9522, 237.6339, 632.3745],
          [170.6081,  36.5363, 371.3253, 548.1898],
          ...,
          [373.4832, 426.8497, 396.0713, 497.3481],
          [317.5831,   7.1501, 417.4209,  70.2656],
          [395.1561, 506.0393, 427.8982, 546.8923]])],
 {})
proposal[0][0].size()
torch.Size([1000, 4])
# 候选区域的绘制
img = Image.open('img2.jpg').resize((800,800))
# 显示图像
fig = plt.imshow(img)
# 将候选区域显示在图像上
for index, boxes in enumerate(proposal[0][0]):
    if index <3:
        fig.axes.add_patch(plt.Rectangle(
        xy=(boxes[0],boxes[1]), width=boxes[2]-boxes[0], height=boxes[3]-boxes[1],
        fill=False, edgecolor="blue", linewidth=0.5))
plt.show()
<Figure size 432x288 with 1 Axes>
pool_region_list= model.roi_heads.box_roi_pool(feature_fpn,proposal[0],imgs.image_sizes)
pool_region_list.size()
torch.Size([1000, 256, 7, 7])
detection = model.roi_heads(feature_fpn,proposal[0],imgs.image_sizes)
detection_boxes = detection[0][0]['boxes'].detach().numpy()
img = Image.open('img2.jpg').resize((800,800))
# 显示图像
fig = plt.imshow(img)
# 将检测结果绘制在图像上
for index, boxes in enumerate(detection_boxes):
    fig.axes.add_patch(plt.Rectangle(
    xy=(boxes[0],boxes[1]), width=boxes[2]-boxes[0], height=boxes[3]-boxes[1],
    fill=False, edgecolor="purple", linewidth=1))
plt.show()
<Figure size 432x288 with 1 Axes>

模型训练

数据加载

from voc_data_util import VocDataset,VOC_BBOX_LABEL_NAMES
dataset = VocDataset(
    root='datasets/VOCdevkit/VOC2007/',
    transforms=VocDataset.get_transform())
img,targets = dataset[3]
img.size()
torch.Size([3, 800, 800])
import numpy as np
img = img.permute(1,2,0).numpy().astype(np.uint8)
plt.imshow(img)
<matplotlib.image.AxesImage at 0x7f9753d7b518><Figure size 432x288 with 1 Axes>
targets
{'boxes': tensor([[238.4000, 233.0330, 550.4000, 648.6486]], dtype=torch.float64),
 'labels': tensor([7]),
 'image_id': tensor([3]),
 'area': tensor([33735.]),
 'iscrowd': tensor([0])}
fig = plt.imshow(img)
# 将标注信息绘制在图像上
for index, boxes in enumerate(targets['boxes'].numpy()):
    fig.axes.add_patch(
        plt.Rectangle(xy=(boxes[0], boxes[1]),
                      width=boxes[2] - boxes[0],
                      height=boxes[3] - boxes[1],
                      fill=False,
                      edgecolor="green",
                      linewidth=1))
plt.show()
<Figure size 432x288 with 1 Axes>

模型加载

model = torchvision.models.detection.fasterrcnn_resnet50_fpn(
    pretrained=False, num_classes=21, pretrained_backbone=True)
model.train()
FasterRCNN(
  (transform): GeneralizedRCNNTransform(
      Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
      Resize(min_size=(800,), max_size=1333, mode='bilinear')
  )
  (backbone): BackboneWithFPN(
    (body): IntermediateLayerGetter(
      (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
      (bn1): FrozenBatchNorm2d(64, eps=1e-05)
      (relu): ReLU(inplace=True)
      (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
      (layer1): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(64, eps=1e-05)
          (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(64, eps=1e-05)
          (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(256, eps=1e-05)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
            (1): FrozenBatchNorm2d(256, eps=1e-05)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(64, eps=1e-05)
          (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(64, eps=1e-05)
          (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(256, eps=1e-05)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(64, eps=1e-05)
          (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(64, eps=1e-05)
          (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(256, eps=1e-05)
          (relu): ReLU(inplace=True)
        )
      )
      (layer2): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(128, eps=1e-05)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(128, eps=1e-05)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(512, eps=1e-05)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
            (1): FrozenBatchNorm2d(512, eps=1e-05)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(128, eps=1e-05)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(128, eps=1e-05)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(512, eps=1e-05)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(128, eps=1e-05)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(128, eps=1e-05)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(512, eps=1e-05)
          (relu): ReLU(inplace=True)
        )
        (3): Bottleneck(
          (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(128, eps=1e-05)
          (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(128, eps=1e-05)
          (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(512, eps=1e-05)
          (relu): ReLU(inplace=True)
        )
      )
      (layer3): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=1e-05)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=1e-05)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=1e-05)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)
            (1): FrozenBatchNorm2d(1024, eps=1e-05)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=1e-05)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=1e-05)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=1e-05)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=1e-05)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=1e-05)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=1e-05)
          (relu): ReLU(inplace=True)
        )
        (3): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=1e-05)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=1e-05)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=1e-05)
          (relu): ReLU(inplace=True)
        )
        (4): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=1e-05)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=1e-05)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=1e-05)
          (relu): ReLU(inplace=True)
        )
        (5): Bottleneck(
          (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(256, eps=1e-05)
          (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(256, eps=1e-05)
          (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(1024, eps=1e-05)
          (relu): ReLU(inplace=True)
        )
      )
      (layer4): Sequential(
        (0): Bottleneck(
          (conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(512, eps=1e-05)
          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(512, eps=1e-05)
          (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(2048, eps=1e-05)
          (relu): ReLU(inplace=True)
          (downsample): Sequential(
            (0): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)
            (1): FrozenBatchNorm2d(2048, eps=1e-05)
          )
        )
        (1): Bottleneck(
          (conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(512, eps=1e-05)
          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(512, eps=1e-05)
          (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(2048, eps=1e-05)
          (relu): ReLU(inplace=True)
        )
        (2): Bottleneck(
          (conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn1): FrozenBatchNorm2d(512, eps=1e-05)
          (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
          (bn2): FrozenBatchNorm2d(512, eps=1e-05)
          (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
          (bn3): FrozenBatchNorm2d(2048, eps=1e-05)
          (relu): ReLU(inplace=True)
        )
      )
    )
    (fpn): FeaturePyramidNetwork(
      (inner_blocks): ModuleList(
        (0): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1))
        (1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))
        (2): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1))
        (3): Conv2d(2048, 256, kernel_size=(1, 1), stride=(1, 1))
      )
      (layer_blocks): ModuleList(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      )
      (extra_blocks): LastLevelMaxPool()
    )
  )
  (rpn): RegionProposalNetwork(
    (anchor_generator): AnchorGenerator()
    (head): RPNHead(
      (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (cls_logits): Conv2d(256, 3, kernel_size=(1, 1), stride=(1, 1))
      (bbox_pred): Conv2d(256, 12, kernel_size=(1, 1), stride=(1, 1))
    )
  )
  (roi_heads): RoIHeads(
    (box_roi_pool): MultiScaleRoIAlign(featmap_names=['0', '1', '2', '3'], output_size=(7, 7), sampling_ratio=2)
    (box_head): TwoMLPHead(
      (fc6): Linear(in_features=12544, out_features=1024, bias=True)
      (fc7): Linear(in_features=1024, out_features=1024, bias=True)
    )
    (box_predictor): FastRCNNPredictor(
      (cls_score): Linear(in_features=1024, out_features=21, bias=True)
      (bbox_pred): Linear(in_features=1024, out_features=84, bias=True)
    )
  )
)

RPN正负样本

rpn_label_matchs,rpn_target_deltas= model.rpn.assign_targets_to_anchors(anchors,[targets])
rpn_label_matchs
[tensor([0., 0., 0.,  ..., 0., 0., 0.])]
rpn_target_deltas
[tensor([[238.4000, 233.0330, 550.4000, 648.6486],
         [238.4000, 233.0330, 550.4000, 648.6486],
         [238.4000, 233.0330, 550.4000, 648.6486],
         ...,
         [238.4000, 233.0330, 550.4000, 648.6486],
         [238.4000, 233.0330, 550.4000, 648.6486],
         [238.4000, 233.0330, 550.4000, 648.6486]], dtype=torch.float64)]
positive_anchor_id= torch.where(torch.eq(rpn_label_matchs[0],1))[0].numpy()
positive_anchor_id.shape
(8,)
anchors[0].size()
torch.Size([159882, 4])
fig = plt.imshow(img)
# 遍历所有的正样本的anchor,绘制在图像上
for idx in positive_anchor_id:
    print(idx)
    if idx == 158513:
        boxes = anchors[0][idx]
        fig.axes.add_patch(plt.Rectangle(
        xy=(boxes[0],boxes[1]), width=boxes[2]-boxes[0], height=boxes[3]-boxes[1],
        fill=False, edgecolor="red", linewidth=1))
plt.show()
158510
158513
158516
158519
158585
158588
158591
158594
<Figure size 432x288 with 1 Axes>
negative_anchor_id= torch.where(torch.eq(rpn_label_matchs[0],-1))[0].numpy()
negative_anchor_id.shape
(249,)
fig = plt.imshow(img)
# 遍历所有的正样本的anchor,绘制在图像上
for idx in negative_anchor_id:
   # print(idx)
    # 负样本的anchor
    boxes = anchors[0][idx]
    # 取余20为0的负样本进行展示
    fig.axes.add_patch(
        plt.Rectangle(xy=(boxes[0], boxes[1]),
                      width=boxes[2] - boxes[0],
                      height=boxes[3] - boxes[1],
                      fill=False,
                      edgecolor="white",
                      linewidth=1))
plt.show()
<Figure size 432x288 with 1 Axes>
regression_targets = model.rpn.box_coder.encode(rpn_target_deltas,anchors)
regression_targets[0].size()
torch.Size([159882, 4])
proposals,matched_idx,labels,regression_targets= model.roi_heads.select_training_samples(proposal[0],[targets])
proposals[0].size()
torch.Size([512, 4])
regression_targets[0].size()
torch.Size([512, 4])
labels
[tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 7, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 7])]
positive_proposal_id=torch.where(torch.gt(labels[0],0))[0].numpy()
# 绘制部分候选区域的负样本
fig = plt.imshow(img)
# 遍历所有的正样本的候选区域,绘制在图像上
for idx in positive_proposal_id:
    # 正样本的proposals
    boxes = proposals[0][idx]
    # 取余10为0的负样本进行展示
    fig.axes.add_patch(
        plt.Rectangle(xy=(boxes[0], boxes[1]),
                      width=boxes[2] - boxes[0],
                      height=boxes[3] - boxes[1],
                      fill=False,
                      edgecolor="white",
                      linewidth=1))
plt.show()
<Figure size 432x288 with 1 Axes>
negitivate_proposal_id = torch.where(torch.eq(labels[0],0))[0].numpy()
# 绘制部分候选区域的负样本
fig = plt.imshow(img)
# 遍历所有的负样本的候选区域,绘制在图像上
for idx in negitivate_proposal_id:
    # 负样本的proposals
    boxes = proposals[0][idx]
    # 取余10为0的负样本进行展示
    if idx % 10 == 0:
        fig.axes.add_patch(
            plt.Rectangle(xy=(boxes[0], boxes[1]),
                          width=boxes[2] - boxes[0],
                          height=boxes[3] - boxes[1],
                          fill=False,
                          edgecolor="white",
                          linewidth=1))
plt.show()
<Figure size 432x288 with 1 Axes>

模型训练

from torch.utils.data import DataLoader
def collate_fn(batch):
    return tuple(zip(*batch))
train_data_loader = DataLoader(dataset,batch_size=2,shuffle = True,collate_fn = collate_fn)
for i,data in enumerate(train_data_loader):
    image,targets = data
    print(len(image))
    print(targets)
    break
2
({'boxes': tensor([[224.0000, 140.8000, 425.6000, 522.6666]], dtype=torch.float64), 'labels': tensor([8]), 'image_id': tensor([3183]), 'area': tensor([22554.]), 'iscrowd': tensor([0])}, {'boxes': tensor([[230.4000, 256.0000, 696.0000, 605.8667]], dtype=torch.float64), 'labels': tensor([3]), 'image_id': tensor([2603]), 'area': tensor([47724.]), 'iscrowd': tensor([0])})
# 优化器
params = [p for p in model.parameters() if p.requires_grad]
optimizer = torch.optim.SGD(params,lr= 0.0001,momentum=0.9,weight_decay=0.0001)
# 遍历每个轮次进行训练

# 1.参数的初始化
iters = 0
loss_value = 0
total_train_loss = []
# 2.遍历每个轮次进行训练
for epoch in range(2):
    train_loss = []
    # 3.每个轮次中遍历每个batch
    for images, targets in train_data_loader:
        # 4.把batch数据送入网络中进行预测:损失
        loss_dict = model(images, targets)
        print(loss_dict)
        loss = sum(loss for loss in loss_dict.values())
        loss_value = loss.item()
        train_loss.append(loss_value)
        # 5.进行反向传播:
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        print(f"Epoch:{epoch},Batch:{iters},loss:{loss_value}")
        iters+=1
        break
    # 6.保存一此列的参数
    epoch_loss = np.mean(train_loss)
    total_train_loss.append(epoch_loss)
    break
{'loss_classifier': tensor(110.5280, grad_fn=<NllLossBackward0>), 'loss_box_reg': tensor(22.8108, grad_fn=<DivBackward0>), 'loss_objectness': tensor(7.9993, grad_fn=<BinaryCrossEntropyWithLogitsBackward0>), 'loss_rpn_box_reg': tensor(7.4245, dtype=torch.float64, grad_fn=<DivBackward0>)}
Epoch:0,Batch:0,loss:148.76265928275987