基于卷积神经网络实现图片风格的迁移
卷积神经网络详解
一、实验介绍
1.1 实验内容
Prisma 是最*很火的一款APP,它能够将一张普通的图像转换成各种艺术风格的图像。本课程基于卷积神经网络,使用Caffe框架,探讨图片风格迁移背后的算法原理,手把手教你实现和Prisma一样的功能,让电脑学习梵高作画。
本节课我们将学习CNN
(卷积神经网络)的相关知识,学习本门课程之前,你需要先去学习814 使用python实现深度神经网络,也许你已经学过820 使用卷积神经网络进行图片分类中的卷积神经网络,对CNN
有了一定的了解,但我依然强烈建议你学习本节课,本节课所讲解的卷积神经网络对于图像风格迁移算法原理的理解至关重要。
1.2 实验知识点
- 为什么要引入CNN
- 卷积神经网络的层次结构
1.3 实验环境
- Xfce终端
1.4 先修课程
二、卷积神经网络
2.1 CNN的引入
在人工的全连接神经网络中,每相邻两层之间的每个神经元之间都是有边相连的。当输入层的特征维度变得很高时,这时全连接网络需要训练的参数就会增大很多,计算速度就会变得很慢,例如一张黑白的 28×28
的手写数字图片,输入层的神经元就有784
(28×28
)个,如下图所示:
若在中间只使用一层隐藏层,参数 w
就有 784×15=11760
多个;若输入的是 28×28
带有颜色的RGB格式的手写数字图片,输入神经元就有28×28×3=2352
(RGB有3
个颜色通道)个。这很容易看出使用全连接神经网络处理图像中的需要训练参数过多的问题。
而在卷积神经网络(Convolutional Neural Network,CNN)中,卷积层的神经元只与前一层的部分神经元节点相连,即它的神经元间的连接是非全连接的,且同一层中某些神经元之间的连接的权重 w
和偏移 b
是共享的(即相同的),这样大量地减少了需要训练参数的数量。
卷积神经网络CNN的结构一般包含这几个层:
- 输入层:用于数据的输入
- 卷积层:使用卷积核进行特征提取和特征映射
- 激励层:由于卷积也是一种线性运算,因此需要增加非线性映射
- 池化层:进行下采样,对特征图稀疏处理,减少数据运算量。
- 全连接层:通常在CNN的尾部进行重新拟合,减少特征信息的损失
- 输出层:用于输出结果
当然中间还可以使用一些其他的功能层:
- 归一化层(
Batch Normalization
):在CNN中对特征的归一化 - 切分层:对某些(图片)数据的进行分区域的单独学习
- 融合层:对独立进行特征学习的分支进行融合
2.2 CNN的层次结构
2.2.1 输入层 Input Layer
在CNN的输入层中,图片
数据输入的格式与全连接神经网络的输入格式一维向量
不太一样。CNN的输入层的输入格式保留了图片本身的结构。
对于黑白的 28×28
的图片,CNN的输入是一个 28×28
的的二维神经元,如下图所示:
而对于RGB格式的28×28
图片,CNN的输入则是一个3×28×28
的三维神经元(RGB中的每一个颜色通道都有一个28×28
的矩阵),如下图所示:
2.2.2 卷积层 Convolutional Layers
在卷积层中有几个重要的概念:
- 感知视野 (
local receptive fields
) - 共享权值 (
shared weights
)
假设输入的是一个 28×28
的二维神经元,我们定义 5×5
的一个 local receptive fields
(感知视野),即隐藏层的神经元与输入层的 5×5
个神经元相连,这个 5×5
的区域就称之为 Local Receptive Fields
,如下图所示:
可类似看作:隐藏层中的神经元具有一个固定大小的感知视野去感受上一层的部分特征。在全连接神经网络中,隐藏层中的神经元的感知视野足够大乃至可以看到上一层的所有特征。
而在卷积神经网络中,隐藏层中的神经元的感受视野比较小,只能看到上一次的部分特征,上一层的其他特征可以通过*移感知视野来得到同一层的其他神经元,由同一层其他神经元来看:
设移动的步长为 1
:从左到右扫描,每次移动 1
格,扫描完之后,再向下移动一格,再次从左到右扫描。
具体过程如动图所示:
可看出卷积层的神经元是只与前一层的部分神经元节点相连,每一条相连的线对应一个权重 w
。
一个感知视野带有一个 卷积核
(或滤波器 filter
),我们将感知视野中的权重 w
矩阵称为卷积核;将感受视野对输入的扫描间隔称为步长(stride
,步长在长和宽上的移动保持一致);当步长比较大时(stride>1
),为了扫描到边缘的一些特征,感受视野可能会“出界”,这时需要对边界扩充(pad),边界扩充可以设为 0
或其他值。步长和边界扩充值的大小由用户来定义。
卷积核
的大小由用户来定义,即定义的感知视野的大小;卷积核的权重矩阵的值,便是卷积神经网络的参数,为了有一个偏移项,卷积核可附带一个偏移项 b
,它们的初值可以随机来生成,可通过训练进行变化。 在神经网络中,我们经常加入偏移项来引入非线性因素,如果这里你不理解什么是非线性因素,后文中介绍激励层时将具体叙述。
动图演示的是 3*3
卷积核对图像卷积的过程,步长为 1
,偏移项0
。因此,当我们使用 5*5
卷积核操作时,感知视野扫描后可以计算出下一层神经元的值为:
对下一层的所有神经元来说,它们从不同的位置去探测了上一层神经元的特征。
我们将通过一个带有卷积核的感知视野扫描生成的下一层神经元矩阵称为一个 feature map
(特征映射图),如下图的右边便是一个 feature map
:
因此在同一个 feature map
上的神经元使用的卷积核是相同的,因此这些神经元共享权值 shared weights
,共享卷积核中的权值和附带的偏移。一个 feature map
对应一个卷积核,若我们使用 3
个不同的卷积核,可以输出3个 feature map
:(感知视野: 5×5
,布长stride:1
)
因此在CNN的卷积层,我们需要训练的参数大大地减少到了 (5×5+1)×3=78
(一个卷积核中包括5*5=25个未定参数,随机偏移项1个参数)个。
假设输入的是 28×28
的RGB图片,即输入的是一个 3×28×28
的的二维神经元,这时卷积核的大小不只用长和宽来表示,还有深度,感知视野也对应的有了深度,如下图所示:
由图可知,感知视野: 3×2×2
; 卷积核: 3×2×2
,深度为 3
;下一层的神经元的值为:
卷积核的深度和感知视野的深度相同,都由输入数据来决定,长宽可由自己来设定,数目也可以由自己来设定,一个卷积核依然对应一个 feature map
。
2.2.3 激励层 Activiation Layers
关于神经网络激励函数的作用,常听到的解释是:不使用激励函数的话,神经网络的每层都只是做线性变换,多层输入叠加后也还是线性变换。因为线性模型的表达能力不够,激励函数可以引入非线性因素。 其实很多时候我们更想直观的了解激励函数的是如何引入非线性因素的。
我们使用神经网络来分割*面空间作为例子:
图的上半部分是没有激励函数的神经网络,其输出实际是线性方程,然后用复杂的线性组合来逼*曲线,得到最终的 Positive Region A
;
加入非线性激励函数后,神经网络就有可能学习到*滑的曲线来分割*面,而不是用复杂的线性组合逼**滑曲线来分割*面,如图的下半部分所示,这就是为什么我们要有非线性的激活函数的原因。
常见的激活函数包括Sigmoid函数、Softmax函数、ReLu函数,深度神经网络使用的激励函数一般为 ReLu(Rectified Linear Units)函数
(计算量小,效果显著):
卷积层和激励层通常合并在一起称为“卷积层”。
2.2.4 池化层 Pooling Layers
当输入经过卷积层时,若感受视野比较小,布长 stride
比较小,得到的 feature map
(特征图)还是比较大,可以通过池化层来对每一个 feature map
进行降维操作,输出的深度还是不变的,依然为 feature map
的个数。
池化层也有一个“池化视野( pooling filter
)”来对 feature map
矩阵进行扫描,对“池化视野”中的矩阵值进行计算,一般有两种计算方式:
- Max pooling:取“池化视野”矩阵中的最大值
- Average pooling:取“池化视野”矩阵中的*均值
扫描的过程中同样地会涉及的扫描布长stride,扫描方式同卷积层一样,先从左到右扫描,结束则向下移动布长大小,再从左到右。如下图示例所示:
其中 池化卷积核
: 2×2
,布长stride:2
。
最后可将 3
个 24×24
的 feature map
下采样得到 3
个 24×24
的特征矩阵:
2.2.5 全连接层 Fully Connected Layers,FC
其实卷积层也可以看作是全连接的一种简化形式:不全连接+参数共享,但是卷积层还保留了空间位置信息,大大减少了参数并且使得训练变得可控。不同channel同一位置上的全连接等价与1x1的卷积核的卷积操作。N个节点的全连接可*似为N个模板卷积后的 均值池化(GAP)
。
全连接本质是矩阵的乘法,相当于一个特征空间变换,可以把有用的信息提取整合。再加上激活函数的非线性映射,多层全连接层理论上可以模拟任何非线性变换;但缺点也很明显:无法保持空间结构,全连接的一个作用是维度变换,尤其是可以把高维变到低维,同时把有用的信息保留下来。全连接另一个作用是隐含语义的表达(embedding),把原始特征映射到各个隐语义节点(hidden node)。对于最后一层全连接而言,就是分类的显示表达。
一般卷积神经网络模型中只有最后1~2层是全连接层,对于这一层一个不严谨的理解就是,经过卷积、池化等处理,我们可以得到了一系列高度抽象过的 feature map
,将特征图输入全连接层,全连接的过程可以对这些特征进行投票,1,2,3
特征更像是猫的特征,2,4,5
更像是狗的特征,从而最终得到每个类别的概率。
但是需要注意的是,全连接层并不是必须的,由于全连接层输入参数过多,以及会丢失一些特征位置信息的缺点,现在FCN(Fully Convolutional Networks 全卷积网络
)逐渐火了起来,但这不是本文的重点,不再详述。
三、实验总结
本节课我们学习了卷积神经网络的知识,概括为:
- 为什么要引入CNN
- 卷积神经网络的层次结构
下节课我们将学习经典卷积神经网络模型VGG,并用caffe提供的draw_net.py对网络模型进行可视化操作,之后我们还将讲解图像迁移算法原理。
四、课后习题
[可选]请学习教程820 使用卷积神经网络进行图片分类。