💻 源码
# 1.相关依赖包导入
import torch
import torchvision
import torchvision.transforms as transforms
from torchvision.io import read_image
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
# 加载数据集
from voc_data_util import VocDataset, VOC_BBOX_LABEL_NAMES
from torch.utils.data import DataLoader

import warnings
warnings.filterwarnings("ignore")

# 2.数据集加载
dataset = VocDataset(root='datasets/VOCdevkit/VOC2007', transforms=VocDataset.get_transform())

# # 数据集绘制
# # 获取图像及对应的标注信息
img, targets = dataset[141]
img = img.permute(1, 2, 0).numpy().astype(np.uint8)
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()

# 3.模型加载及实例化
# N+1包含背景

# 3.模型实例化及参数设置
num_classes = 21
# 3.1 模型实例化:不使用预训练模型,修正类别个数,backbone使用预训练结果
# model = torchvision.models.detection.fasterrcnn_resnet50_fpn(
#     pretrained=False,
#     num_classes=num_classes,
#     pretrained_backbone=True)

model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=False,
                                                             pretrained_backbone=True,
                                                             num_classes=num_classes)


def collate_fn(batch):
    return tuple(zip(*batch))


# 3.2 参数设置
# 3.2.1 获取batch的数据,送入网络中进行训练
train_data_loader = DataLoader(
    dataset,
    batch_size=2,
    shuffle=True,
    collate_fn=collate_fn
)

# 遍历数据,获取第一个batch的数据进行展示
# for i, data in enumerate(train_data_loader):
#     inputs, labels = data
#     # batch的大小
#     print('图片个数:', len(inputs))
#     print('目标值:', labels)
#     break


# 获取所有要进行训练的参数,设置优化器
# 3.2.2 参数冻结
params = [p for p in model.parameters() if p.requires_grad]
optimizer = torch.optim.SGD(params, lr=0.00005, momentum=0.9, weight_decay=0.0005)
# 3.2.3 迭代次数
itr = 1
# 3.2.4 存放训练损失
total_train_loss = []
# 3.2.5 损失值
losses_value = 0

# 4.模型训练
# 4.1 遍历每个轮次进行训练
for epoch in range(2):
    # 4.2 训练模式
    model.train()
    train_loss = []
    # 4.3 遍历数据,获取图像,目标值和图像id
    for images, targets in train_data_loader:
        # 4.4 将数据送入网络中进行训练,获取损失值(RPN的损失+FastRCNN的损失),将信息打印出来分析
        loss_dict = model(images, targets)
        print(loss_dict)
        # 4.5 将损失求和
        losses = sum(loss for loss in loss_dict.values())
        # 4.6 获取loss值
        losses_value = losses.item()
        train_loss.append(losses_value)
        # 4.7 进行反向传播,更新参数
        optimizer.zero_grad()
        losses.backward()
        optimizer.step()
        # 4.8 日志信息
        print(f"Epoch: {epoch + 1}, Batch: {itr}, Loss: {losses_value}")
        # 4.9 迭代次数增1
        itr += 1
    # 4.10 获取当前轮次的损失
    epoch_train_loss = np.mean(train_loss)
    # 4.11 轮次损失写入到列表中
    total_train_loss.append(epoch_train_loss)

# 5.绘制损失函数变化的曲线
plt.plot(range(len(total_train_loss)), [loss.numpy() for loss in total_train_loss])
plt.grid()