Faster RCNN 复现---RPN模块

faster rcnn 持续填坑
因为本人numpy, torch零基础,代码注释会比较详细

generate_anchors

参考博客:某个强者的复现
这部分主要是生成先验框

import numpy as np

def generate_anchors(base_size=16, ratios=[0.5, 1, 2], scales=2 ** np.arange(3, 6)):
    # np.arange(3,6)   [3 4 5]
    # 2 ** np.arange(3,6) -> [8, 16, 32]
    base_anchor = np.array([1, 1, base_size, base_size]) - 1  # [0, 0, 15, 15]  左上角和右下角
    ratio_anchors = _ratio_enum(base_anchor, ratios)
    anchors = np.vstack(
        [_scale_enum(ratio_anchors[i, :], scales) for i in range(ratio_anchors.shape[0])]  # 再次注意np的张量求维度是x.shape
    )
    return anchors


def _ratio_enum(anchor, ratios):
    w, h, x_ctr, y_ctr = _whctrs(anchor)
    size = w * h
    # h = ratio * w -> size = h * w = ratio * w * w
    # size_ratio = size / ratio = w * w
    size_ratios = size / ratios  # python的list可以直接和标量运算
    ws = np.round(np.sqrt(size_ratios))  # np.round 四舍五入取整
    hs = np.round(ws * ratios)
    anchors = _mkanchors(ws, hs, x_ctr, y_ctr)
    return anchors


def _scale_enum(anchor, scales):
    w, h, x_ctr, y_ctr = _whctrs(anchor)
    ws = w * scales
    hs = h * scales
    anchors = _mkanchors(ws, hs, x_ctr, y_ctr)
    return anchors

# 通过左上角右下角坐标转化为 中心长宽表示
def _whctrs(anchor):
    w = anchor[2] - anchor[0] + 1
    h = anchor[3] - anchor[1] + 1
    x_ctr = anchor[0] + 0.5 * (w - 1)  # 这里因为是像素点不是线段 如果不是奇数个格子 其实算到了 n//2的格子做中心点
    y_ctr = anchor[1] + 0.5 * (h - 1)
    return w, h, x_ctr, y_ctr


# 从wh中心点坐标转化为左上角右下角坐标
def _mkanchors(ws, hs, x_ctr, y_ctr):
    # before ws.shape = (3,)  另外注意np的矩阵要用 x.shape查看维度
    # after ws.shape = (3, 1)
    ws = ws[:, np.newaxis]  # 增加一维 规范成矩阵
    hs = hs[:, np.newaxis]
    # np.vstack 只能在 dim=1维进行拼接  等价于
    # np.hstack 只能在 dim=2维进行拼接  上述适合二维张量
    # np.stack 在最外层增加一个维度
    # np.concatenate((a,b), axis = ?) 可以指定拼接维度 拼接的要求就是目标拼接维度可以不同,其他dim必须相同
    # vstack hstack stack concatenate的区别见https://blog.youkuaiyun.com/weixin_36149892/article/details/86657314
    anchors = np.hstack(
        [
            x_ctr - 0.5 * (ws - 1),
            y_ctr - 0.5 * (hs - 1),
            x_ctr + 0.5 * (ws - 1),  # 这里直接加其实和原计算差1 当做了奇数中心 但是只要近似就没管那么多
            y_ctr + 0.5 * (hs - 1)
        ]
    )
    return anchors


if __name__ == '__main__':
    a = generate_anchors()
    print(a)
    pass```

### 实现 Voxel-RCNN 的概述 Voxel-RCNN 是一种先进的三维目标检测框架,它结合了体素化处理和区域建议网络(RPN),以及后续的细化阶段来提高检测精度。该模型通常由三个主要组件构成:体素特征编码器、区域提议网络(RPN)、以及用于边界框回归和分类的第二阶段细化模块。 #### 1. 数据预处理与加载 为了准备输入数据给 Voxel-RCNN,首先需要将原始 LiDAR 点云转换成体素网格形式。这一步骤可以通过以下 Python 代码片段完成: ```python import numpy as np from voxel_generator import VoxelGenerator def preprocess_point_cloud(points, voxel_size=(0.16, 0.16, 4)): generator = VoxelGenerator( voxel_size=voxel_size, point_cloud_range=[0,-40,-3,70.4,40,1], max_num_points_per_voxel=100 ) voxels, coordinates, num_points = generator.generate(points) return voxels, coordinates, num_points ``` 此函数接收点云坐标作为参数并返回体素化的输出[^3]。 #### 2. 构建体素特征编码器 (VFE) 接下来定义一个简单的两层卷积神经网络来进行初步特征提取: ```python import torch.nn as nn class VFELayer(nn.Module): def __init__(in_channels, out_channels): super(VFELayer, self).__init__() self.linear = nn.Linear(in_channels, out_channels) def forward(x): x_max = torch.max(x,dim=-1)[0] x_mean = torch.mean(x,dim=-1) return torch.cat([x_max,x_mean],dim=-1) ``` 这段代码实现了基本的体素特征聚合逻辑。 #### 3. 设计 RPNRCNN 阶段 对于 RPN 来说,可以采用类似于 Faster R-CNN 中的设计思路;而对于 RCNN,则更侧重于对候选区域进行精细化调整。这里给出简化版伪代码描述这两个过程: ```python # 定义RPN类 class RegionProposalNetwork(nn.Module): pass # 定义RCNN类 class RefinementStage(nn.Module): pass ``` 实际应用中还需要考虑更多细节,比如损失函数的选择、训练策略等[^1]。 #### 4. 训练流程概览 最后,在整个训练过程中,会交替执行前向传播、反向传播更新权重的操作直到收敛为止。具体来说就是不断迭代上述构建好的各个部件之间的交互直至达到预期性能指标。 ```python for epoch in range(num_epochs): model.train() for batch_idx, sample_batched in enumerate(dataloader_train): optimizer.zero_grad() loss_dict = model(sample_batched['points'],sample_batched['gt_boxes']) total_loss = sum(loss_dict.values()) total_loss.backward() optimizer.step() ``` 以上展示了如何从零开始搭建一个完整的 Voxel-RCNN 模型架构及其训练方案。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值