谈谈1×1的卷积核

谈谈1×1卷积核的作用

最近在看yolo3,发现对于1×1的卷积核的理解有些遗忘,借此强化一下记忆。
最早我对此有些疑惑,1×1卷积核不会改变高(Height)和宽(Width)(在stride和padding等其他参数为默认状态时), 但**通道数(Channel)**可以随意变化,例如在pytorch中:

情况1,不变,加入了非线性的因素

nn. Conv2d(256, 256, kernel_size=1)

情况2,通道数增加(升维)

nn. Conv2d(256, 512, kernel_size=1)

情况3,通道数下降(降维)

nn. Conv2d(256, 128, kernel_size=1)

总结

可以理解为加入了非线性的一些因素,对通道进行非线性重组,使得不同通道内的信息能够交互(例如从64层缩小到32层),因为卷积运算不同于普通运算。

一般1×1都是用来做bottleneck的,先做1×1缩小,再做3×3放大。经过bottleneck可以有效缩小参数的规模,从而减少计算量,且在降维之后对数据的训练和特征提取将更加有效。

在yolo3中是这样出现的:

def conv2d(filter_in, filter_out, kernel_size): #该函数与本文主要内容无关
    pad = (kernel_size - 1) // 2 if kernel_size else 0
    return nn.Sequential(OrderedDict([
        ("conv", nn.Conv2d(filter_in, filter_out, kernel_size=kernel_size, stride=1, padding=pad, bias=False)),
        ("bn", nn.BatchNorm2d(filter_out)),
        ("relu", nn.LeakyReLU(0.1)),
    ]))
    
# 例如:in_filters = 1024, filters_list = [512, 1024], out_filters = 75
def make_last_layers(filters_list, in_filters, out_filter):
    m = nn.ModuleList([
        # 通过来来回回的自定义conv2d函数缩小参数规模
        conv2d(in_filters, filters_list[0], 1),      #先缩小,1*1的卷积核
        conv2d(filters_list[0], filters_list[1], 3), #再放大,3*3的卷积核
        conv2d(filters_list[1], filters_list[0], 1), #先缩小,1*1的卷积核
        conv2d(filters_list[0], filters_list[1], 3), #再放大,3*3的卷积核
        conv2d(filters_list[1], filters_list[0], 1), #最后缩小,1*1的卷积核(达到通道数为512的目标)
        
        conv2d(filters_list[0], filters_list[1], 3), 
        nn.Conv2d(filters_list[1], out_filter, kernel_size=1,
                                        stride=1, padding=0, bias=True)
    ])
    return m

(yolo3代码引用自https://blog.csdn.net/weixin_44791964/article/details/105310627)

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值