动手学深度学习(Pytorch版)代码实践 -计算机视觉-44目标检测算法综述:R-CNN、SSD和YOLO

41~44目标检测算法综述:R-CNNSSDYOLO

1. 区域卷积神经网络 (R-CNN 系列)
1.1 R-CNN
  • 使用启发式搜索算法来选择锚框。
  • 使用预训练模型对每个锚框提取特征(每个锚框视为一张图片,使用 CNN 提取特征)。
  • 训练 SVM 进行类别分类(在神经网络之前进行)。
  • 训练线性回归模型预测边界框偏移(bounding box prediction)。
  • 利用兴趣区域(RoI)池化层:
    • 给定一个锚框,均匀分割成 n x m 块,输出每块的最大值(max pooling)。
    • 无论锚框大小,总是输出 n x m 个值。
    • 目的是将每个锚框转换为固定形状。
python 复制代码
# 提取特征
def extract_features(image, boxes, model):
    features = []
    for box in boxes:
        cropped_image = image[box[1]:box[3], box[0]:box[2]]
        resized_image = cv2.resize(cropped_image, (224, 224)) # 假设使用的是 224x224 的输入尺寸
        feature = model.predict(resized_image)
        features.append(feature)
    return features

# 训练 SVM 分类器
svm = SVM()
svm.fit(features, labels)
1.2 Fast R-CNN
  • R-CNN 需要对每个锚框进行 CNN 运算,这些特征提取计算存在重复且计算量大。
  • Fast R-CNN 改进了这种计算量大的问题:
    • 使用 CNN 对整张图片提取特征(关键在于提高速度)。
    • 使用 RoI 池化层对每个锚框(将在原图片中搜索到的锚框映射到 CNN 结果上)生成固定长度的特征。
python 复制代码
# 使用整图进行特征提取
feature_map = cnn_model(image)

# RoI 池化层
roi_pooling = RoIPoolingLayer(pool_size=(7, 7), num_rois=num_rois)
pooled_features = roi_pooling([feature_map, rois])
1.3 Faster R-CNN
  • 在 Fast R-CNN 的基础上进一步提速。
  • 使用区域提议网络 (RPN) 取代启发式搜索以获得更好的锚框:
    • 将 CNN 结果输入到卷积层,然后用锚框圈定区域,这些锚框很多有好有坏,然后进行预测。二元预测用于预测锚框的好坏,即是否有效圈住物体。bounding box prediction 用于对锚框进行改进,最后使用 NMS(非极大值抑制)对锚框进行合并。

具体步骤如下:

1. 使用 3x3 卷积层变换 CNN 输出,并将输出通道数记为 c。这样,CNN 为图像抽取的特征图中的每个单元均得到一个长度为 c 的新特征。
2. 以特征图的每个像素为中心,生成多个不同大小和宽高比的锚框并标注它们。
3. 使用锚框中心单元长度为 c 的特征,分别预测该锚框的二元类别(含目标或背景)和边界框。
4. 使用非极大值抑制,从预测类别为目标的预测边界框中移除相似结果。最终输出的预测边界框即是兴趣区域汇聚层所需的提议区域。
python 复制代码
# RPN 网络
rpn_conv = Conv2D(512, (3, 3), padding='same', activation='relu')(base_layers)
rpn_class = Conv2D(num_anchors * 2, (1, 1), activation='softmax')(rpn_conv)
rpn_bbox = Conv2D(num_anchors * 4, (1, 1))(rpn_conv)

# 非极大值抑制
proposals = proposal_layer([rpn_class, rpn_bbox, anchors], num_proposals)
1.4 Mask R-CNN
  • 如果有像素级别的标注,使用全卷积网络 (FCN) 利用这些信息可以提升性能。
  • RoI 对齐 (RoI align):避免 RoI 池化中的取整误差,使用 RoI align 对每个像素值进行按比例分配。具体来说,Mask R-CNN 将兴趣区域汇聚层替换为兴趣区域对齐层,使用双线性插值保留特征图上的空间信息,适用于像素级预测。输出包含所有与兴趣区域形状相同的特征图,用于预测每个兴趣区域的类别和边界框,并通过额外的全卷积网络预测目标的像素级位置。
python 复制代码
# RoI align
roi_align = RoiAlignLayer(pool_size=(14, 14), num_rois=num_rois)
aligned_features = roi_align([feature_map, rois])

# 全卷积网络
mask_conv1 = Conv2D(256, (3, 3), padding='same', activation='relu')(aligned_features)
mask_output = Conv2D(num_classes, (1, 1), activation='sigmoid')(mask_conv1)
1.5 总结
  • R-CNN 是最早也是最有名的一类基于锚框和 CNN 的目标检测算法。
  • Fast R-CNN 和 Faster R-CNN 持续提升性能。
  • Faster R-CNN 和 Mask R-CNN 常用于高精度要求的场景,但速度相对较慢。
2. 单发多框检测 (SSD)
  • 生成锚框:
    • 对每个像素生成多个以其为中心的锚框。
    • 给定 n 个大小 s 1 , . . . , s n s_1,...,s_n s1,...,sn和m个高宽比,生成n+m-1个锚框,其大小和高宽比分别为: ( s 1 , r 1 ) , ( s 2 , r 1 ) . . . , ( s n , r 1 ) , ( s 1 , r 2 ) , . . . , ( s 1 , r m ) (s_1,r_1),(s_2,r_1)...,(s_n,r_1),(s_1,r_2),...,(s_1,r_m) (s1,r1),(s2,r1)...,(sn,r1),(s1,r2),...,(s1,rm)
  • SSD 模型:
    • 对多个分辨率下的卷积特征生成锚框并进行预测。
    • 使用一个基础网络提取特征,然后用多个卷积层来减半高宽。
    • 在每个层生成锚框:
      • 底部层拟合小物体。
      • 顶部层拟合大物体。
    • 对每个锚框预测类别和边界框。
python 复制代码
# 锚框生成
def generate_anchors(feature_map_shape, scales, ratios):
    anchors = []
    for scale in scales:
        for ratio in ratios:
            width = scale * np.sqrt(ratio)
            height = scale / np.sqrt(ratio)
            for i in range(feature_map_shape[0]):
                for j in range(feature_map_shape[1]):
                    center_x = (j + 0.5) / feature_map_shape[1]
                    center_y = (i + 0.5) / feature_map_shape[0]
                    anchors.append([center_x, center_y, width, height])
    return np.array(anchors)

# SSD 网络
base_model = SSDBaseNetwork(input_shape=(300, 300, 3))
feature_maps = base_model.extract_features(image)

for feature_map in feature_maps:
    anchors = generate_anchors(feature_map.shape, scales, ratios)
    predictions = predict_bboxes_and_classes(feature_map, anchors)
总结
  • 速度快但精度较低。虽然作者没有持续提升,但 SSD 启发了一系列后续工作,实现上相对简单。
  • SSD 通过单神经网络进行检测(single shot)。
  • 以像素为中心产生多个锚框,在多个层的输出上进行多尺度检测。
3. YOLO (You Only Look Once)
  • SSD 中锚框大量重复,浪费计算资源。
  • YOLO 将图片均分为 S x S 个网格。
  • 每个网格预测 B 个边界框(防止多个物体出现在一个网格内)。
  • 后续版本 YOLOv2、YOLOv3 和 YOLOv4 持续改进,非锚框算法。
python 复制代码
# YOLO 网络
def yolo_model(input_shape, num_classes, num_bboxes):
    inputs = Input(shape=input_shape)
    x = Conv2D(32, (3, 3), padding='same', activation='relu')(inputs)
    x = MaxPooling2D(pool_size=(2, 2))(x)
    # 添加更多卷积和池化层
    x = Flatten()(x)
    x = Dense(4096, activation='relu')(x)
    outputs = Dense(S * S * (num_classes + 5 * num_bboxes), activation='sigmoid')(x)
    model = Model(inputs, outputs)
    return model

# 预测
yolo = yolo_model((448, 448, 3), num_classes, num_bboxes)
predictions = yolo
相关推荐
深度学习实战训练营1 小时前
基于CNN-RNN的影像报告生成
人工智能·深度学习
浮生如梦_3 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
深度学习lover3 小时前
<项目代码>YOLOv8 苹果腐烂识别<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·苹果腐烂识别
孙同学要努力8 小时前
全连接神经网络案例——手写数字识别
人工智能·深度学习·神经网络
Eric.Lee20218 小时前
yolo v5 开源项目
人工智能·yolo·目标检测·计算机视觉
其实吧39 小时前
基于Matlab的图像融合研究设计
人工智能·计算机视觉·matlab
丕羽9 小时前
【Pytorch】基本语法
人工智能·pytorch·python
绕灵儿10 小时前
OpenCV通过指针裁剪图像
人工智能·opencv·计算机视觉
sniper_fandc10 小时前
深度学习基础—循环神经网络的梯度消失与解决
人工智能·rnn·深度学习
weixin_5182850510 小时前
深度学习笔记10-多分类
人工智能·笔记·深度学习