复现地址

https://github.com/BBuf/ENet-Keras

ENet原文地址

https://arxiv.org/pdf/1606.02147.pdf

ENet的优势

\quad ENet实现了在移动端的实时语义分割,并且精度稍微好于SegNet,先看一下论文给出的速度测试图。

对于分辨率为640 × \times × 360的图片,ENet执行前向推理的速度也可以达到14.6fps,接近实时,我用keras提炼了ENet的网络结构,并实现了训练和预测图片,最后在我的电脑Core-i7CPU上的推理速度为0.55s一张图像,整理好代码之后会考虑开源训练,测试完整代码。

ENet的网络结构

\quad ENet网络结构如下,网络结构参考ResNet,将其结构描述为一个主分支与一个带有卷积核的附加分支,最后进行像素级的相加融合。
下面的描述转自:https://www.cnblogs.com/fourmi/p/10009691.html
\quad ENet中的每个block如下图b所示,每个block包含有三个卷积层:一个1x1的映射用于减少维度,一个主卷积层,一个1x1的扩张。将BN层与PReLU层穿插其中,将此结构组合定义为bottleneck 模型。如果bottleneck为下采样,则在主分支上添加一个最大池化层,同时,bollteneck中第一个1x1的映射被一个大小为2x2,stride为2的卷积进行替换,对激活值进行padding操作,使其与feature map的尺寸相匹配。卷积大小为3x3的,类型有普通卷积,空洞卷积,及转置卷积等,有时,用1x5或者5x1的非对称卷积对其替换。对于正则化处理,在bottleneck2.0之前使用p=0.01,其他条件下使p=0.1。
\quad ENet的初始部分包含单独的一个block。如上图a.第一阶段包含5个bottleneck部分。第二,三阶段结构相同,但第三阶段的开始处并未有下采样的过程。前三个阶段属于编码阶段。第四五阶段属于解码阶段。由于cuDNN使用分离的内核进行卷积与偏差项的计算,为了减少内核的调用与内存的占用,该网络并未使用偏差项,结果发现,准确率也并未受很大的影响。在每个卷积层与pReLU层之间添加了一层BN层。在解码网络部分,最大池化层,被最大上采样层代替,padding被无偏差项的空间卷积替换。ENet在最后一个上采样过程中并未使用最大池化的索引,因为输入图片的通道为3,而输出通道数为类别数,最终,用一个全卷积模型作为网络的最后模型,占用部分解码网络的处理时间。

Trick1:减少下采样和上采样过程的分割精度丢失

\quad 解决下采样中边缘信息丢失问题的主流方法有2种,一是FCN中的添加编码层的feature map,二是Segnet中通过保留编码网络中最大池化过程中最大值的索引,并借此在解码网络中生成稀疏的上采样feature map。ENet采用了SegNet中的方式来降低下采样和上采样过程的分割精度丢失。

Trick2:非对称的Encoder-Decoder结构,降低参数量

\quad ENet网络结构是非对称的,包含一个较大的编码层和一个小的解码网络。原因是编码层应该像原始分类网络的结构相似。用于处理较小的数据,同时进行信息的处理与滤波,解码网络对编码网络的输出进行上采样用于对细节的微调。

Trick3:激活函数使用PReLU,而非ReLU

\quad 作者实验发现去掉网络初始层中的大部分ReLU层会提升分割的效果,原因是此网络的深度不够深。然后,该文将所有ReLU替换为PReLUs,针对每张feature map增加了一个额外的参数。得到了精度的提升。

Trick4:分解卷积核

\quad Inception Net 的套路,0 一个二维的卷积可以被分解为两个维度为1的卷积核。论文使用5x1,1x5的非对称卷积,减弱了函数学习的过拟合同时增加了感受野。卷积核的分解带来的另一个好处是可以减少大量的参数。同时加上更多的非线性处理,使计算功能更加丰富。

Trick 5:使用空洞卷积

\quad 论文将bottleneck中的卷积层替换为空洞卷积并进行串联,增大了感受野,提高了分割的IOU。

Trick 6:正则化

\quad 由于分割数据集有限,因此网络的训练很容易达到过拟合。该文使用空间Dropout进行处理。

Trick 7:信息保留的维度变化

\quad 前半部分进行下采样是有必要的,但剧烈的维度衰减不利于信息的流动。为解决这个问题,该文任务在池化层后接一个卷积层增加了维度,进而增加了计算资源。为此,该文将池化操作与卷积操作进行并行操作,然后进行拼接。同时,在原始的ResNet的结构中,进行下采样时,第一个1x1的映射,在所有维度上进行的是步长为2的卷积,丢弃了75%左右的输入信息。将卷积核增加至2x2利于信息的保留。

Keras源码

可以看一下这个博主keras实现的代码:https://github.com/PavlosMelissinos/enet-keras/tree/master/src/models, 后续我如果开源自己的代码,也会更新链接上来。