sparse_block源码阅读

class SparseBasicBlock(BasicBlock, spconv.SparseModule):
	# 该类使用子流形稀疏卷积(submanifold sparse convolution)实现。
    适用于稀疏点云卷积网络的基本块。
    # 参数:
        inplanes (int): 输入的通道数。
        planes (int): 输出的通道数。
        stride (int): 第一个卷积层的步长。默认为 1。
        downsample (None | Module): 用于下采样的模块(可选)。
        conv_cfg (dict): 用于构造和配置卷积层的字典,默认为 None。
        norm_cfg (dict): 用于构造和配置归一化层的字典,默认为 {'type': 'BN'}"""Sparse basic block for PartA^2.

    Sparse basic block implemented with submanifold sparse convolution.

    Args:
        inplanes (int): inplanes of block.
        planes (int): planes of block.
        stride (int): stride of the first block. Default: 1
        downsample (None | Module): down sample module for block.
        conv_cfg (dict): dictionary to construct and config conv layer.
            Default: None
        norm_cfg (dict): dictionary to construct and config norm layer.
            Default: dict(type='BN')
    """

    expansion = 1  # 扩展倍数。该值影响输出通道数,通常为 1。

    def __init__(self, inplanes, planes, stride=1, downsample=None, conv_cfg=None, norm_cfg=None):
        spconv.SparseModule.__init__(self)   # 初始化 SparseModule(稀疏模块)的基类
        BasicBlock.__init__(   # 初始化 BasicBlock(基础卷积块)的基类,传入必要参数
            self,
            inplanes,
            planes,
            stride=stride,
            downsample=downsample,
            conv_cfg=conv_cfg,
            norm_cfg=norm_cfg,
        )

    def forward(self, x):   # x: 输入的稀疏张量(包含 features 和 coordinates 等信息)。
        identity = x.features   # 保存输入的 features 作为残差连接的 identity

        assert x.features.dim() == 2, f"x.features.dim()={x.features.dim()}"

        out = self.conv1(x)    # 第一个卷积层的前向传播
        out.features = self.norm1(out.features)   
        out.features = self.relu(out.features)

        out = self.conv2(out)   # 第二个卷积层的前向传播
        out.features = self.norm2(out.features)  

        if self.downsample is not None:    # 如果存在下采样模块,则对输入进行下采样
            identity = self.downsample(x)

        out.features += identity   # 将残差连接 (identity) 加到当前输出的特征上,实现残差连接
        out.features = self.relu(out.features)    # 对加和后的特征应用 ReLU 激活函数
        return out  

def make_sparse_convmodule(
    in_channels,
    out_channels,
    kernel_size,
    indice_key,   # 稀疏张量的索引键,用于 spconv 内部的索引管理
    stride=1,     
    padding=0,   # 输入的填充大小,可以是整数或列表
    conv_type="SubMConv3d",     # 使用的稀疏卷积类型,默认为子流形卷积 (SubMConv3d)
    norm_cfg=None,   
    order=("conv", "norm", "act"),
):
    """Make sparse convolution module.

    Args:
        in_channels (int): the number of input channels
        out_channels (int): the number of out channels
        kernel_size (int|tuple(int)): kernel size of convolution
        indice_key (str): the indice key used for sparse tensor
        stride (int|tuple(int)): the stride of convolution
        padding (int or list[int]): the padding number of input
        conv_type (str): sparse conv type in spconv
        norm_cfg (dict[str]): config of normalization layer
        order (tuple[str]): The order of conv/norm/activation layers. It is a
            sequence of "conv", "norm" and "act". Common examples are
            ("conv", "norm", "act") and ("act", "conv", "norm").

    Returns:
        spconv.SparseSequential: sparse convolution module.
    """
    assert isinstance(order, tuple) and len(order) <= 3
    assert set(order) | {"conv", "norm", "act"} == {"conv", "norm", "act"}
	# 配置卷积层的参数字典,包括卷积类型和索引键
    conv_cfg = dict(type=conv_type, indice_key=indice_key)

    layers = list()
    for layer in order:   # 根据指定的层顺序逐层构建网络
        if layer == "conv":
            if conv_type not in [
                "SparseInverseConv3d",
                "SparseInverseConv2d",
                "SparseInverseConv1d",
            ]:
                layers.append(
                    build_conv_layer(
                        conv_cfg,
                        in_channels,
                        out_channels,
                        kernel_size,
                        stride=stride,
                        padding=padding,
                        bias=False,
                    )
                )
            else:
                layers.append(
                    build_conv_layer(conv_cfg, in_channels, out_channels, kernel_size, bias=False)
                )
        elif layer == "norm":
            layers.append(build_norm_layer(norm_cfg, out_channels)[1])
        elif layer == "act":
            layers.append(nn.ReLU(inplace=True))

    layers = spconv.SparseSequential(*layers)
    return layers

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值