引言

首先用下面一张图简单回顾CNN的结构,CNN的最大特性就是局部连接参数共享

# 2D-CNN 首先看一下最一般的二维空间Feature-Map CNN。输入的是一个矩阵,输出的也是一个矩阵,中间卷积核与图像不同区域进行卷积运算,就是实现了**局部连接**的过程,在每层的Feature-Map中都是参数共享的。

TextCNN

那么一维文本数据是否可以使用CNN呢,Text-CNN提出解决了我们的疑惑。我们具体剖析一下TextCNN,看最左边的蓝色矩形,假设句子长度为20, 每一个单词的embedding为50, 那么对于任何一个句子他就可以映射为20x50的矩阵,这样我们就将文本可以说在某种意义上说是映射成了图像。 我们就可以用图像的CNN操作来处理文本特征,

但是这里卷积核有一个特征,为了不破坏单词信息,我们这里的卷积核是一个宽卷积,使用的维度是3x50,而不是3x3, 因为词向量进行分隔开是不合理的。另外Text-cnn是采用不同size的卷积核来提取不用Scale的信息。然后通过Max-pool进一步降维拼接(可以视为采样过程),最后softmax进行0-1分类,这样就完成了一个序列->一个二维特征图->一个向量信息->一个数值分类的过程。

最后对于分类任务,选择的损失函数是序列交叉熵。此外在Loss中还添加了正则化损失进一步约束。

Channel CNN

我们前面的任务都是输入单通道,没有多通道。但大多数图片任务RGB都是多通道,那么多通道的卷积应该是怎么计算的,那么我们每个卷积核都要和多个通路的二维特征图进行计算。对于每一个通道,采用不同的二维卷卷积核进行卷积。我们这里需要考虑输入通道和输出通道,我们从输入通道的角度来看,这个过程有点像全连接过程,下面这个图将计算过程描述的很清楚。

## Group Convolution 接下来看一下分组卷积。其实我们的卷积操作在通道数变多的时候会计算变慢,那么分组卷积就是为了减小参数,其中分组卷积这个思想一直贯穿于CNN的进化史。下面图片左侧显示了传统CNN的卷积计算,如果把每个通道看成一个点的话,其实是像一个全连接的操作。他每一张图都和输入的通道进行全连接,这不符合CNN减少参数的目的。那么分组卷积就是在通道上进行了参数缩减,如右侧。

我们令输入的维度是 C ∗ H ∗ W C*H*W CHW,输出的通道数是 N N N,对于传统操作的参数大小是 N ∗ C ∗ K ∗ K N*C*K*K NCKK,对于通道局部连接的参数大小是 N ∗ ( C / G ) ∗ K ∗ K N*(C/G)*K*K N(C/G)KK,参数变为原来的 1 / G 1/G 1/G,由此可见,分的组越多参数减小的越多。CNN最开始的设计是二维特征图中进行局部连接,分组卷积是在通道之间局部连接。

AlexNet

AlexNet的提出是基于分组卷积这种思想。

下两个并行的网络结构只有在部分层中才有信息交互,而且网络结构一模一样,这就是Group convolution最早的应用。该模型用了5层卷积,首先这幅图分为上下两个部分的网络,论文中提到这两部分网络是分别对应两个GPU,只有到了特定的网络层后才需要两块GPU进行交互。

分组卷积影响比较深远,当前一些轻量级的SOTA网络,都用到了分组卷积的操作来缓解对单个处理器的压力。

VGG(小卷积核的思想)

AlexNet中用到了一些非常大的卷积核,比如11×11、5×5卷积核,之前人们的观念是,卷积核越大,receptive field(感受野)越大,获取到的图片信息越多,因此获得的特征越好。虽说如此,但是大的卷积核会导致计算量的暴增,不利于模型深度的增加,计算性能也会降低。

于是在VGG(最早使用)网络中,利用2个3×3卷积核的组合比1个5×5卷积核的效果更佳,同时参数量(3×3×2 VS 5×5×1)被降低,因此后来3×3卷积核被广泛应用在各种模型中。

VGG优点
VGGNet的结构非常简洁,整个网络都使用了同样大小的卷积核尺寸(3x3)和最大池化尺寸(2x2)。
几个小滤波器(3x3)卷积层的组合比一个大滤波器(5x5或7x7)卷积层好:
验证了通过不断加深网络结构可以提升性能。

Group Convolution special case

Deepwise Convolution

不同于常规卷积操作,Depthwise Convolution的一个卷积核负责一个通道,一个通道只被一个卷积核卷积。上面所提到的常规卷积每个卷积核是同时操作输入图片的每个通道。同样是对于一张5×5像素、三通道彩色输入图片(shape为5×5×3),Depthwise Convolution首先经过第一次卷积运算,不同于上面的常规卷积,DW完全是在二维平面内进行。卷积核的数量与上一层的通道数相同(通道和卷积核一一对应)。所以一个三通道的图像经过运算后生成了3个Feature map(如果有same padding则尺寸与输入层相同为5×5),如下图所示:

Depthwise Convolution完成后的Feature map数量与输入层的通道数相同,无法扩展Feature map。而且这种运算对输入层的每个通道独立进行卷积运算,没有有效的利用不同通道在相同空间位置上的feature信息。因此需要Pointwise Convolution来将这些Feature map进行组合生成新的Feature map。

Pointwise Convolution

Pointwise Convolution的运算与常规卷积运算非常相似,它的卷积核的尺寸为 1×1×M,M为上一层的通道数。所以这里的卷积运算会将上一步的map在深度方向上进行加权组合,生成新的Feature map。有几个卷积核就有几个输出Feature map。如下图所示。

Global Depthwise Convolution

在 DW卷积的基础上,类似加入了Global Average Pooling,如下图所示:

GoogleNet(多尺寸卷积)

传统的层叠式网络,基本上都是一个个卷积层的堆叠,每层只用一个尺寸的卷积核,例如VGG结构中使用了大量的3×3卷积层。事实上,同一层feature map可以分别使用多个不同尺寸的卷积核,以获得不同尺度的特征,再把这些特征结合起来,得到的特征往往比使用单一卷积核的要好,谷歌的GoogleNet,或者说Inception系列的网络,就使用了多个卷积核的结构:

1 . 采用不同大小的卷积核意味着不同大小的感受野,最后拼接意味着不同尺度特征的融合;
2 . 之所以卷积核大小采用1、3和5,主要是为了方便对齐。设定卷积步长stride=1之后,只要分别设定pad那么卷积之后便可以得到相同维度的特征,然后这些特征就可以直接拼接在一起了;
3 . 文章说很多地方都表明pooling挺有效,所以Inception里面也嵌入了。
4 . 网络越到后面,特征越抽象,而且每个特征所涉及的感受野也更大了,因此随着层数的增加,3x3和5x5卷积的比例也要增加。

这个模型最大的优点是:一个输入的feature map分别同时经过1×1、3×3、5×5的卷积核的处理,得出的特征再组合起来,获得更佳的特征;但这个结构会存在一个严重的问题:参数量比单种卷积核要多很多,如此庞大的计算量会使得模型效率低下。

Bottleneck

发明GoogleNet的团队发现,如果仅仅引入多个尺寸的卷积核,会带来大量的额外的参数,受到Network In Network中1×1卷积核的启发,为了解决这个问题,他们往Inception结构中加入了一些1×1的卷积核,如图所示:

那么如何减少参数量的呢,我们来算一笔账:
256维的输入直接经过一个3×3×256的卷积层,输出一个256维的feature map,那么参数量为:256×3×3×256 = 589,824;256维的输入先经过一个1×1×64的卷积层,再经过一个3×3×64的卷积层,最后经过一个1×1×256的卷积层,输出256维,参数量为:256×1×1×64 + 64×3×3×64 + 64×1×1×256 = 69,632。足足把第一种操作的参数量降低到九分之一!

1×1卷积核也被认为是影响深远的操作,往后大型的网络为了降低参数量都会应用上1×1卷积核。

ResNet

传统的卷积层层叠网络会遇到一个问题,当层数加深时,网络的表现越来越差,很大程度上的原因是因为当层数加深时,梯度消散得越来越严重,以至于反向传播很难训练到浅层的网络。

为了解决这个问题,何凯明大神想出了一个“残差网络”,使得梯度更容易地流动到浅层的网络当中去,由于多了这条捷径,来自深层的梯度能直接畅通无阻地通过,去到上一层,使得浅层的网络层参数等到有效的训练。

ShuffleNet

该模型的提出是改进了组卷积。AlexNet的Group Convolution当中,特征的通道被平均分到不同组里面,最后再通过两个全连接层来融合特征,这样一来,就只能在最后时刻才融合不同组之间的特征,对模型的泛化性是相当不利的。为了解决这个问题,ShuffleNet在每一次层叠这种Group conv层前,都进行一次channel shuffle,shuffle过的通道被分配到不同组当中。进行完一次group conv之后,再一次channel shuffle,然后分到下一层组卷积当中,以此循环。

在小型网络中,昂贵的逐点卷积造成有限的通道之间充满约束,这会显著的损失精度。为了解决这个问题,一个直接的方法是应用通道稀疏连接,例如组卷积(group convolutions)。通过确保每个卷积操作仅在对应的输入通道组上,组卷积可以显著的降低计算损失。然而,如果多个组卷积堆叠在一起,会有一个副作用: 某个通道输出仅从一小部分输入通道中导出,如下图(a)所示,这样的属性降低了通道组之间的信息流通,降低了信息表示能力。如果我们允许组卷积能够得到不同组的输入数据,即上图(b)所示效果,那么输入和输出通道会是全关联的。具体来说,对于上一层输出的通道,我们可做一个混洗(Shuffle)操作,如上图©所示,再分成几个组,feed到下一层。

1.有 g × n g×n g×n个输出通道
2.reshape为 ( g , n ) (g,n) (g,n)
3.再转置为 ( n , g ) (n,g) (n,g)
4.平坦化,再分回 g g g组作为下一层的输入

SENET

无论是在Inception、DenseNet或者ShuffleNet里面,我们对所有通道产生的特征都是不分权重直接结合的,那为什么要认为所有通道的特征对模型的作用就是相等的呢?而SENet网络的创新点在于关注channel之间的关系,希望模型可以自动学习到不同channel特征的重要程度。为此,SENet提出了Squeeze-and-Excitation (SE)模块,如下图所示:


SE模块首先对卷积得到的特征图进行Squeeze操作,得到channel级的全局特征,然后对全局特征进行Excitation操作,学习各个channel间的关系,也得到不同channel的权重,最后乘以原来的特征图得到最终特征。本质上,SE模块是在channel维度上做attention或者gating操作,这种注意力机制让模型可以更加关注信息量最大的channel特征,而抑制那些不重要的channel特征。另外一点是SE模块是通用的,这意味着其可以嵌入到现有的网络架构中。

Dilated Convolution

在图像分割领域,图像输入到CNN(典型的网络比如FCN)中,图像分割FCN中有两个关键,一个是pooling减小图像尺寸增大感受野,另一个是upsampling扩大图像尺寸。在先减小再增大尺寸的过程中,肯定有一些信息损失掉了,那么能不能设计一种新的操作,不通过pooling也能有较大的感受野看到更多的信息呢?

dilated convolution的好处是不做pooling损失信息的情况下,加大了感受野,让每个卷积输出都包含较大范围的信息,在图像需要全局信息或者语音文本需要较长的sequence信息依赖的问题中,都能很好的应用dilated conv。

Deformable Convolution

在现有的卷积网络架构中,图像中任何位置的感受野大小都是相同的,其取决于事先设定的网络参数(卷积核的大小、步长和网络深度等),无法根据图像内容自适应调整,从而限制了识别精度。

追根溯源,上述局限来自于卷积网络的基本构成单元,即卷积操作。该操作在输入图像的每个位置时会进行基于规则格点位置的采样,然后对于采样到的图像值做卷积并作为该位置的输出。通过端到端的梯度反向传播学习,系统将会得到一个用矩阵表示的卷积核的权重。这就是自卷积网络诞生之初,已使用二十多年的基本单元结构。

微软亚洲研究院的研究员们发现,标准卷积中的规则格点采样是导致网络难以适应几何形变的“罪魁祸首”。为了削弱这个限制,研究员们对卷积核中每个采样点的位置都增加了一个偏移的变量。通过这些变量,卷积核就可以在当前位置附近随意的采样,而不再局限于之前的规则格点。这样扩展后的卷积操作被称为可变形卷积(deformable convolution)。标准卷积和可变形卷积在图1中有简要的展示。

MSRA提出了一个相当反直觉的见解,认为卷积核的形状可以是变化的,变形的卷积核能让它只看感兴趣的图像区域 ,这样识别出来的特征更佳。

总结

现在越来越多的CNN模型从巨型网络到轻量化网络一步步演变,模型准确率也越来越高。现在工业界追求的重点已经不是准确率的提升(因为都已经很高了),都聚焦于速度与准确率的trade off,都希望模型又快又准。

卷积核方面:

  • 大卷积核用多个小卷积核代替;
  • 单一尺寸卷积核用多尺寸卷积核代替;
  • 固定形状卷积核趋于使用可变形卷积核;
  • 使用1×1卷积核(bottleneck结构)。

卷积层通道方面:

  • 标准卷积用depthwise卷积代替;
  • 使用分组卷积;
  • 分组卷积前使用channel shuffle;
  • 通道加权计算。

卷积层连接方面:

  • 使用skip connection,让模型更深;
  • densely connection,使每一层都融合上其它层的特征输出(DenseNet)

卷积神经网络(CNN)的进化史以及常用的CNN框架相关推荐

  1. DL之CNN:关于CNN(卷积神经网络)经典论文原文(1950~2018)简介总结框架结构图(非常有价值)之持续更新(吐血整理)

    DL之CNN:关于CNN(卷积神经网络)经典论文原文(1950~2018)简介总结框架结构图(非常有价值)之持续更新(吐血整理) 导读       关于CNN,迄今为止已经提出了各种网络结构.其中特别 ...

  2. 深度学习之卷积神经网络CNN 常用的几个模型

    LeNet5 论文:http://yann.lecun.com/exdb/publis/pdf/lecun-01a.pdf LeNet-5:是Yann LeCun在1998年设计的用于手写数字识别的卷 ...

  3. 卷积神经网络、比较MLPS和CNNS、滤波器、CNN各层的作用、在Pytorch可视化CNN

    1.33.卷积神经网络 1.33.1.卷积 和 神经网络 1.33.1.1.比较MLPS和CNNS 1.33.1.2.计算机如何看图像? 1.33.1.3.建立自己的滤波器 1.33.2.完整的卷积神 ...

  4. CNN(卷积神经网络)概述

    过去几年,深度学习(Deep learning)在解决诸如视觉识别(visual recognition).语音识别(speech recognition)和自然语言处理(natural langua ...

  5. 深度学习 CNN卷积神经网络 LeNet-5详解

    卷积神经网络( Convolutional Neural Network, CNN): 是一种常见的深度学习架构,受生物自然视觉认知机制(动物视觉皮层细胞负责检测光学信号)启发而来,是一种特殊的多层前 ...

  6. 卷积神经网络(CNN)介绍与实践

    七月 上海 | 高性能计算之GPU CUDA培训 7月27-29日三天密集式学习  快速带你入门阅读全文> 正文共4499个字,26张图,预计阅读时间18分钟. CNN的前世今世 1.1.大脑 ...

  7. 卷积神经网络(CNN)图像识别知识总结

    最近研究了一些卷积神经网络方面的知识,研究了CNN算法实现图像识别,做一些总结. 图像识别技术是人工智能的一个重要领域,它是对图像中的对象进行识别,以识别各种不同模式的目标和对象的技术.近几年,图像识 ...

  8. 神经网络—卷积神经网络CNN

    定义 卷积神经网络(convolutional neural network)简称CNN,主要用于处理图像数据,但仍然可以处理其他形式的数据,像语音数据等.其最擅长的就是图片的处理,它具有人工神经元, ...

  9. CNN卷积神经网络之SENet及代码

    CNN卷积神经网络之SENet 个人成果,禁止以任何形式转载或抄袭! 一.前言 二.SE block细节 SE block的运用实例 模型的复杂度 三.消融实验 1.降维系数r 2.Squeeze操作 ...

最新文章

  1. java聊天程序源代码_java聊天程序源代码
  2. Delphi 写服务程序
  3. aboboo 上一句 快捷键_Word快捷键大全
  4. vs2019 编译 WRK 踩坑记录
  5. C#反射调用 异常信息:Ambiguous match found.
  6. ie11 不能调试 因为 ie的bug
  7. C++ STL : 模拟实现STL中的list类
  8. 桩筏有限元中的弹性板计算_永清县打桩机租赁钢板桩租赁怎么联系?
  9. 看完这篇垃圾回收,和面试官扯皮没问题了
  10. 同林多域共用一台Exchange
  11. 【软件项目管理】用例分析方法采用一种面向对象的情景分析方法
  12. 重构之以委托取代继承
  13. 约束最优化方法 (一) 最优性条件
  14. 所有win7机器都必须要做的一个优化!作用:让系统流畅,减少卡顿
  15. python信息安全书籍_2018年信息安全从业者书单推荐
  16. leetcode复原IP地址
  17. Python下载视频
  18. JVM StackOverFlowError
  19. Amazon DynamoDB详解
  20. 前端页面 原生php+H5 视频播放一 专辑列表页(专辑页list)

热门文章

  1. VB.NET视频总结——基础篇
  2. Java面向对象三大特征:封装、继承、多态
  3. js调用windows.Print打印去掉页眉页脚
  4. OFD是什么格式,如何打开
  5. 2021年Java开发爆款推荐!javapdf模板循环表格
  6. 用Python实现选股票(Pandas,Matplotlib)
  7. UEFI的一点点概识
  8. 小知识·BitTorrent 简介
  9. 基于51系列单片机的(循迹、避障、蓝牙)智能小车(2)源代码
  10. 【Linux】浅谈线程