前面我们学习了AlexNet卷积神经网络模型,以及pytorch框架的搭建,根据对卷积神经网络的初步了解,有下列问题:
AlexNet中用到了一些非常大的卷积核,比如11x11,5x5的卷积核,从前人们的观念是,卷积核越大,receptive field(感受野)越大,看到的图片的信息就越多,因此获得的特征就越好。虽然这么说,但是大的卷积核会导致参数增加没计算量暴增,不利于模型深度的计算,计算性能也会降低。于是在VGG(最早使用)、inception网络中,利用两个3x3的卷积核的组合比一个5x5的卷积核的效果更佳,同时参数量(3x3x2+1 VS 5x5x1+1)被降低,因此后来3x3的卷积核被广泛应用在各种模型中。
下图是用一个3x3的卷积核做两次卷积示意图:
传统的层叠式网络,基本上都是一个个卷积层堆叠,每层只用一个尺寸的卷积核。例如:VGG结构中使用了大量的3x3卷积层,事实上,同一层feature map 可以分别使用多个不同尺寸的卷积核,已获得不同尺寸的特征,再把这些特征结合在一起,得到的特征往往比使用单一的卷积核要好,谷歌的GoogleNet,或者说Inception系列的网络,就使用了多个卷积核结构
最初版本的Inception结构如上图所示,一个输入的feature map 分别同时经过1x1(不改变宽高,但是改变输出通道数,达到通道的扩张或者压缩的效果),3x3 ,5x5 的卷积核处理,得到的特征在结合在一起,获得更加的特征。
但是这个结构会存在一个严重的问题:参数比单个卷积核要多很多,如此庞大的计算量会使得模型的效率地下,这就引出了一个新的结构:Bottleneck
如下图所示:加入1x1卷积核的Inception结构:
1x1的卷积核也被认为是影响深远的造作,往后大型的网络中,为了降低参数量,都会用上1x1的卷积核。
对于上面的结构
第一种:常规的,假如我们输入的图像的通道是256,卷积核大小是3x3,输出通道数 256,这个时候:输入通道数 = 卷积核的通道数,输出通道数 = 卷积核的个数。这样计算下来,最后的参数的个数为 :256 *x3x3x 256 = 589824
第二种:先对256个通道的输入做一个 1x1的卷积,输出为64通道,再做一个3x3的卷积,输出为64通道,最后做一个1x1的卷积,输出为256通道,这样计算,做后的参数个数为:256 x1x1x64 + 64x3x3x64 + 64 x1 x1 x 256 = 69632
参数个数大大降低
当卷积了几次以后,就把前边的卷积输出结果拿下来,与当前的结果进行相加,在进行激活,在进入下一层卷积
那么问题来了,前面的结果与当前的结果的通道数可能不一样,要进行相加,就要保证纬度相同,有三种方式:
第一种(H,W 不同,空间上不同):自定义一个矩阵W,与上面的结果相乘,得到变换后新的维度的结果,类似于全连接。
第二种(C 深度上不同):用1x1的矩阵卷积,得到想要的维度的输出。
第三种(C深度上不同):缺的补零
如下图,将原本的3x3x16的卷积层拓展成3x3x(16xk)的卷积。
通道信息是否也具有局部性?换句话说,在处理通道时,我们是不是可以像处理长宽一样,不把所有信息考虑在内,像下面这张图这样?在ResNet模型中,坐着提出了Cardinality这个概念,他表示了通道分成的组,假如说,我们本来有这样一段模型结构“
此时,中间的计算是经典的卷积操作,所有的通道信息合并处理,就相当于把所有的通道看成1组,如果想要将通道分成两组,那么运算过程中,在中间的层次,我们会得到两个结果,这两个结果分别计算,左后合并起来(concatenate)或者加和起来(sum)
作者提出了depth-wise separable convolution 的结构,也就是说在卷积计算的时候,每一个通道中的数据做单独计算,也就是说,如果有N维通道的输出,那么Cardinality就等于N。
两个模型的其他方面各有异同,但是思路上却十分一致,都是要对通道下手,把convolution进化group convolution
但是随之而来的一个问题是——通道毕竟不同于长和宽,两者有明确的物理意义上的局部性,而通道的局部性却是人为想象出来的,因此这种做法缺少一定的说服力,到底要怎样处理通道这一维度呢?
下图是一个正常的,没有分组卷积的结构,下面用第三维的视角展示了CNN的结构,一个Filter(卷积核)就对应了一个channel(输出通道数)。随着网络层数的加深,通道数急剧增加,而空间维度随之减少(H,W),因为卷积层的卷积核越来越多,但是随着卷积池化操作,特征图越来越小(越卷越小嘛)。所以在深层网络中,channel的重要性越来越大。
输入通道数 = filter(卷积核)通道数
输出通道数 = filter(卷积核)个数
这里:
第一个图:
filter形状 = h1 x w1 x c1
参数个数 = h1 x w1 x c1 x c2
第二个图:
分组:分g组,把原来的通道数分g组
filter现状 = h1 x w1 x (c1/g)
参数的个数 = h1 x w1 x (c1/g)x c2
两种方法对比,分组卷积所参数量仅为原来的1/g
这个时候,如果我们做的分组卷积,就要影院来的组归一化GN。进行归一化。
到目前为止,所有的变形,都在控制参数
有关group conv的解决方案也在不断探索中,其中ShuffleNet做出了一定的尝试。下图是直接从它的论文中截取的,可以从图(b)中看出,在完成一次group conv之后,通道的顺序会发生一定的变化。作者并不是让相近的几个通道一直做信息的汇集,而是不断地交换相邻的通道,从某种意义上,这样得到的通道融合会更加地均匀。
如上图,一个2x2的卷积核在卷积时,对应图像中的所有通道均被同时考虑,问题在于,为什么要同时考虑图像区域和通道?我们为什么不能把通道和空间分开来考虑
Xception网络就是基于上面的问题发明而来的,我们首先对每一个通道进行各自的卷积操作,有多少个通道,就有多少个过滤器,得到新的通道feature map之后,这时在对这批新的通道feature map进行标准的1x1跨通道卷积操作,这种操作被认为“DepthWise convolution” 缩写“DW”
我们来看一下参数变化:
假设输入通道为3,输出要求为256,
第一种做法:
3x3x256的卷积核——>参数 = 3x3x3x256 = 6912
第二种做法:
分两步完成参数量 = 3x3x3 + 3x1x1x256 = 795
参数缩减到原来的九分之一。
前面我们考虑的都是参数的问题,下面我们来考虑准确率的问题。
已经有很多工作在空间维度上来提升网络的性能,那么很自然的想到,网络是否可以从其他层面来考虑去提升性能,比如考虑特征通道之间的关系?
我们的工作就是基于这一点并提出Squeeze-and-Excitation Networks(简称SENet)。在我们提出的结构中Squeeze和Excition是两个非常关键的操作,所以我们以此来命名。
我们的机动是希望显示的建模特征通道之间的相互依赖的关系。另外,我们不打算引入一个新的空间维度来进行特征通道之间的融合,而是采用一种全新的特征重标定策略,具体的说:就是通过学习的方式来自动获取到每个特征通道的重要程度,然后通过这个重要程度取提升有用的特征并抑制对当前任务用处不大的特征
说白了就是说每一个通道的特征都有一个权值在里边。决定了通道特征的重要程度。
给定一个输入X,特征通道数为C_1,通过一系列卷积等一般变换后,得到一个特征通道数为C_2的特征,与传统的CNN不一样的是,接下来我们通过三个操作来重标定前面得到的特征。
第一步:
Squeeze操作,我们顺着空间维度来进行特征压缩,将每个二维的特征通道变成一个实数,这样,这个实数某种程度上具有全局的感受野,并且输出的维度特输入的特征通道数相匹配。他表征着在特征通道上相应的全局分布,而且使得靠近输入的层也可以获得全局的感受野,这一点在很多任务中都是非常有用的
第二步:
Excitation操作,他是一个类似于循环神经网络中门的机制,通过参数w,为每个特征通道生成权重,其中参数w被学习用来显示的建模特征通道之间的相关性
第三步:
Reweight操作,我们将Excitation的输出的权重看做是通过特征选择后
的每个特征通道的重要性,然后通过乘法逐通道加权到向前的特征上,完成在通道维度上的对原始特征的重标定。
noisystudent模型是一种半监督模型,具体方法如下
处理的对象是一些有标签数据集和一些无标签数据集