YOLOX-BaseConv

class BaseConv(nn.Module):
    """A Conv2d -> Batchnorm -> silu/leaky relu block"""

    def __init__(
        self, in_channels, out_channels, ksize, stride, groups=1, bias=False, act="silu"    
    ):
        super().__init__()
        # same padding
        pad = (ksize - 1) // 2  # 计算padding的大小,如果ksize为奇数,则pad=(ksize-1)//2,如果ksize为偶数,则pad=ksize//2-1
        self.conv = nn.Conv2d(
            in_channels,        # 输入通道数
            out_channels,       # 输出通道数
            kernel_size=ksize,  # 卷积核大小
            stride=stride,      # 步长
            padding=pad,        # padding
            groups=groups,      # 分组卷积,当groups=1时,表示不使用分组卷积,当groups=in_channels时,表示使用深度可分离卷积
                                # 分组卷积的作用是将输入的通道数分成groups组,每组的通道数为in_channels//groups,然后对每组通道数进行卷积,最后将每组卷积后的特征图进行拼接
            bias=bias,          # 是否使用偏置,如果使用偏置,则在卷积后加上偏置,如果不使用偏置,则不加偏置
                                # 偏置的作用是使得卷积后的特征图的每个通道的均值为0,方差为1,这样可以使得卷积后的特征图更加稳定
        )
        self.bn = nn.BatchNorm2d(out_channels)          # BN层,将卷积后的特征图进行归一化,使得每个通道的均值为0,方差为1
        self.act = get_activation(act, inplace=True)    # 激活函数,这里使用的是silu激活函数,silu激活函数的计算公式为x*sigmoid(x),这里的sigmoid是指logistic函数,即1/(1+exp(-x))

    def forward(self, x):
        return self.act(self.bn(self.conv(x)))

    def fuseforward(self, x):   # fuseforward函数用于融合BN和激活函数,将BN和激活函数融合成一个卷积层,这样可以减少计算量
        return self.act(self.conv(x))   # Q: 这里没有使用BN层,是因为BN层的参数已经融合到了卷积层中吗?在哪里融合的? A: 在utils/model_utils.py中的fuse_model函数中,将BN层的参数融合到了卷积层中


已发布

分类

,

来自

标签:

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注