MobileNetV2: 反向残差和线性瓶颈

被称为MobileNet的架构围绕着使用深度可分卷积的想法,其中包括深度和逐点卷积。

反向残差(Inverted Residuals)

残余块将卷积块的开始和结尾连接到跳过连接。通过添加这两个状态,网络有机会访问在卷积块中未修改的早期激活。这种方法对于建立深度网络非常重要。

MobileNetV2: 反向残差和线性瓶颈

残余块将宽层与跳跃连接相连,而层之间的层较窄

当我们稍微靠近跳过连接时, 我们会注意到, 原始的残余块会跟随一个宽 >> 窄 >> 宽的方法来处理通道的数量。输入信道数量很多,并用廉价的1x1卷积进行压缩。这样下面的3x3卷积的参数就少得多了。为了最终增加输入和输出,使用另一个1x1卷积再次增加通道的数量。

def residual_block(x,squeeze = 16,expand = 64):

m = conv2D(squeeze,(1,1),activation ='relu')(x)

m = Conv2D(squeeze,(3,3),activation =' (m)

= Conv2D(expand,(1,1),activation ='relu')(m)

return Add()([m,x])

另一方面,MobileNetV2遵循窄 - 宽 - 窄的方法。第一步使用1x1卷积来扩展网络,因为以下3x3深度卷积已经大大减少了参数的数量。之后,另一个1x1卷积挤压网络以匹配最初的通道数量。

MobileNetV2: 反向残差和线性瓶颈

一个反向的残余块将狭窄的层与跳跃连接相连,而层之间的层较宽

在Keras看起来像这样:

def inverted_residual_block(x,expand = 64,squeeze = 16):

m = Conv2D(expand,(1,1),activation ='relu')(x)

m = DepthwiseConv2D((3,3),activation ='relu' )(m)

m = Conv2D(squeeze,(1,1),activation ='relu')(m)

return Add()([m,x])

作者将此想法描述为反向残差块,因为在网络的狭窄部分之间存在跳过连接,这与原始剩余连接的工作方式相反。当您运行上面的两个片段时,您会注意到反转块的参数少得多。

线性瓶颈

我们在神经网络中使用非线性激活函数的原因是多个矩阵乘法不能简化为单个数值运算。它允许我们建立具有多层的神经网络。同时,在神经网络中常用的激活函数ReLU丢弃小于0的值。可以通过增加信道数量来增加网络容量来解决这种信息丢失问题。

对于倒置的残留块,我们做相反的处理,并挤压连接跳跃连接的层。这伤害了网络的性能。作者介绍了线性瓶颈的概念,其中残余块的最后卷积在添加到初始激活之前具有线性输出。把它放到代码中是非常简单的,因为我们只是放弃了卷积块的最后一个激活函数:

def inverted_linear_residual_block(x, expand=64, squeeze=16):

m = Conv2D(expand, (1,1), activation='relu')(x)

m = DepthwiseConv2D((3,3), activation='relu')(m)

m = Conv2D(squeeze, (1,1))(m)

return Add()([m, x])

ReLU6

上面的代码段显示了包含反向残差和线性瓶颈的卷积块的结构。如果你想尽可能地匹配 MobileNetV2, 还有另外两件你需要的。第一个方面只是在每个卷积层后面添加批处理正常化,第二个添加不太常见。作者使用ReLU6而不是ReLU,这将激活的价值限制在最大值......呃... 6。只要在0和6之间,激活就是线性的。

def relu(x):

return max(0,x)

def relu6(x):

return min(max(0,x),6)

这在处理定点推断时很有用。它将小数点左侧的信息限制为3位,这意味着我们有保证小数点精度的权利。这也被用于原始的MobileNet文件。最后的构建块如下所示:

def bottleneck_block(x, expand=64, squeeze=16):

m = Conv2D(expand, (1,1))(x)

m = BatchNormalization()(m)

m = Activation('relu6')(m)

m = DepthwiseConv2D((3,3))(m)

m = BatchNormalization()(m)

m = Activation('relu6')(m)

m = Conv2D(squeeze, (1,1))(m)

m = BatchNormalization()(m)

return Add()([m, x])

架构

MobileNetV2: 反向残差和线性瓶颈

MobileNetV2架构

现在我们了解了MobileNetV2的构建块,我们可以看看整个架构。在表格中您可以看到瓶颈块如何排列。t代表渠道的扩张速度。正如你所看到的,他们在我们的例子中使用了与4相反的因子。c表示输入通道的数量,n表示块重复的频率。最后s告诉我们一个块的第一次重复是否使用了2倍的下降采样过程。总而言之,这是一个非常简单和常见的卷积块装配。

MobileNetV2: 反向残差和线性瓶颈

MobileNetV2和其他架构在ImageNet上的性能

总结性思考

MobileNetV2提供了一个类似的参数效率的事实NASNet。NASNet是目前几项图像识别任务的最新技术。它的构建块非常复杂,这使得它的工作原理非常不直观。NASNet的构建块不是由人类设计的,而是由另一个神经网络设计的。引入像MobileNetV2这样简单的体系结构,显示出相当的效率。

相关推荐