class FasterRCNNBase(nn.Module):
广义R-CNN的主要类。参数:支柱(nn.Module):项(nn.Module):roi_heads (n . module):从RPN获取特性+建议并计算探测/遮罩。转换(n . module):执行从输入到feed的数据转换该模型
def __init__(self, backbone, rpn, roi_heads, transform):-》参数重新赋值給变量
super(FasterRCNNBase, self).__init__()
self.transform = transform
self.backbone = backbone
self.rpn = rpn
self.roi_heads = roi_heads
self._has_warned = False-》仅在torchscript模式下使用
@torch.jit.unused
def eager_outputs(self, losses, detections):-》训练时返回损失值测试时返回检测值
# type: (Dict[str, Tensor], List[Dict[str, Tensor]]) -> Tuple[Dict[str, Tensor], List[Dict[str, Tensor]]]
if self.training:
return losses
return detections
def forward(self, images, targets=None):-》前向传播,参数:图像(列表[张量]):待处理的图像目标(list[Dict[张量]]):图像中出现的地面真值盒(可选)返回:结果(list[BoxList]或dict[张量]):模型的输出。在训练期间,它返回一个包含损失的dict[张量]。在测试期间,它返回包含其他字段的list[BoxList]比如“分数”、“标签”和“mask”(用于mask R-CNN模型)。
if self.training and targets is None:-》传值为空报错
raise ValueError("In training mode, targets should be passed")
if self.training:
assert targets is not None
for target in targets: # 进一步判断传入的target的boxes参数是否符合规定
boxes = target["boxes"]-》取boxes值
if isinstance(boxes, torch.Tensor):
if len(boxes.shape) != 2 or boxes.shape[-1] != 4:
raise ValueError("Expected target boxes to be a tensor"-》报错期望目标框是一个张量
"of shape [N, 4], got {:}.".format(
boxes.shape))
else:
raise ValueError("Expected target boxes to be of type "-》报错预期的目标框是类型的
"Tensor, got {:}.".format(type(boxes)))
original_image_sizes = torch.jit.annotate(List[Tuple[int, int]], [])-》获取图像数据集大小
for img in images:-》遍历图像
val = img.shape[-2:]
assert len(val) == 2 # 防止输入的是个一维向量
original_image_sizes.append((val[0], val[1]))-》获取图像大小
# original_image_sizes = [img.shape[-2:] for img in images]
images, targets = self.transform(images, targets) # 对图像进行预处理
# print(images.tensors.shape)
features = self.backbone(images.tensors) # 将图像输入backbone得到特征图
if isinstance(features, torch.Tensor): # 若只在一层特征层上预测,将feature放入有序字典中,并编号为‘0’
features = OrderedDict([('0', features)]) # 若在多层特征层上预测,传入的就是一个有序字典
# 将特征层以及标注target信息传入rpn中
proposals, proposal_losses = self.rpn(images, features, targets)
# 将rpn生成的数据以及标注target信息传入fast rcnn后半部分
detections, detector_losses = self.roi_heads(features, proposals, images.image_sizes, targets)
# 对网络的预测结果进行后处理(主要将bboxes还原到原图像尺度上)
detections = self.transform.postprocess(detections, images.image_sizes, original_image_sizes)
losses = {}
losses.update(detector_losses)-》更新检测损失值
losses.update(proposal_losses)-》更新标签损失值
if torch.jit.is_scripting():
if not self._has_warned:
warnings.warn("RCNN always returns a (Losses, Detections) tuple in scripting")-》输出警告信息
self._has_warned = True
return losses, detections
else:
return self.eager_outputs(losses, detections)
class TwoMLPHead(nn.Module):-》基于fpga的模型的标准头参数:in_channels (int):输入通道的数目representation_size (int):中间表示的大小
def __init__(self, in_channels, representation_size):
super(TwoMLPHead, self).__init__()
self.fc6 = nn.Linear(in_channels, representation_size)
self.fc7 = nn.Linear(representation_size, representation_size)
def forward(self, x):
x = x.flatten(start_dim=1)-》降维
x = F.relu(self.fc6(x))-》降维
x = F.relu(self.fc7(x))-》降维
return x
class FastRCNNPredictor(nn.Module):-》标准分类+边界框回归层R-CNN为快。参数:in_channels (int):输入通道的数目
num_classes (int):输出类的数量(包括后台)
def __init__(self, in_channels, num_classes):
super(FastRCNNPredictor, self).__init__()
self.cls_score = nn.Linear(in_channels, num_classes)
self.bbox_pred = nn.Linear(in_channels, num_classes * 4)
def forward(self, x):
if x.dim() == 4:
assert list(x.shape[2:]) == [1, 1]
x = x.flatten(start_dim=1)
scores = self.cls_score(x)-》全连接神经网络输出分类预测值
bbox_deltas = self.bbox_pred(x)-》全连接神经网络输出目标框预测
return scores, bbox_deltas
class FasterRCNN(FasterRCNNBase):
def __init__(self, backbone, num_classes=None,
#转换参数
min_size=800, max_size=1000, # 预处理resize时限制的最小尺寸与最大尺寸
image_mean=None, image_std=None, # 预处理normalize时使用的均值和方差