前言
本篇文章主要是写给自己看的,研一的时候也曾追求在数学原理上了解即将要学习的自然语言处理,勤奋的记了笔记,研三毕业后,笔记随着我在大工的7年青春岁月一起飘向了远方,所以换个方式开启新篇章。 … 近期的主要任务是丰富自己,重操旧业,在理论上先闯下一片天。意思就是,给你时间去巩固自己的基础知识,从NLP转到人工智能加速,需要了解的第一个理论知识就是卷积神经网络的底层原理,从数学层面去理解,CNN是如何操作的,他的算子是什么,了解后便于其在硬件上操作和应用,所以我开启了各种收集CNN相关资料的模式,以前我认为我对CNN有所了解,毕竟我大四的时候就用过它,但现在我发现每个人对CNN的理解都有不一样,那摆脱主观臆测,CNN的客观知识到底如何呢? … 因为在NLP领域用过一维CNN,曾经看过吴恩达老师的课程,但是看完课程和会写代码基本没什么关系,因为会用和知道底层原理是两码事。在神经网络不可解释性的驱动下和神经网络相关框架的快速发展下,利用神经网络来解决不同领域的相关问题越来越简单,直接调用甚至不用大力度调参。而其中的内部原理却很枯燥乏味,还需要一定的数学功底,我一直认为底层原理的创新才是真正的创新,应用层面的创新是在前人任务上的堆叠、组合、碰撞,但不得不承认,这种创新是大多数人正在做的事并且对于落地和应用确实有用。而我当时的情况是迫切要用,所以看完就没有然后了,现在觉着那些课程对于现在的我是有一定帮助的。 … 在查阅了一些资料后,我认为目前市面上关于神经网络的书籍没有我心目中的神(先声明,我尊重并崇拜每位书籍作者,每本书都是带着感情和能量的,感谢作者带给我们的知识与灵感),不同的书会有不同的侧重点,因为每本书籍在描述大量的客观知识时肯定会用作者的一些主观表达,而每个人的表达方式都是不同的,学术大佬也一样,都有着自己的表达方式,于是当你读书时顺道考察了我们的理解能力、学习能力、接受知识的能力等。花书是目前大家比较推崇的,描述的相对具体完整,只是读起来略微枯燥,没有顽强的意志力和专注力很难把这本书啃下来。我还读了深度学习图解(Andrew W. Trask著),这本书的风格就很美式,通过比喻拟人举例设问等方式来表述,例如把神经网络比喻成乐高积木,每块积木都是一个响亮或矩阵等。每一章开始都会有一句有意思的话,例如:人类是缓慢的、草率的、聪明的思考者;而计算机则是快速的、精确的和愚蠢的——约翰法伊弗,1961年。此书关于CNN描述的相对较少,作者声称高中数学功底就能看懂此书,所以关于卷积这里没有数学原理介绍和描述,但是可以从应用层面理解CNN,而且某些话会突然给我灵感,会加深对某些知识的理解,但是总体上不太适合我这个中式工科直女,当睡前读物吧,当教材性价比有些低。在学习过程中我还穿插看了些公众号,所以接下来我的输出是基于上述两本书、吴恩达老师公开课、李宏毅老师公开课以及某些公众号和博客,当然了还有我的一些不成熟的观点。如果有人看到这篇文章,欢迎批评指正。
CNN底层原理的浅显理解
基本概念
卷积核(kennel)= 过滤器(filter)(来自百度百科的自信,课程和相关资料基本都叫filter)
过滤器(filter):如图所示,第一个矩阵是输入图片(灰度),第二个矩阵就是filter,顾名思义,就是要从输入图片中去过滤想要的特征了,通过不断改变filter矩阵的值来关注不同的细节,提取不同的特征。本图例子应该是去过滤垂直方向的边缘特征。在神经网络里,filter矩阵会被初始化,通过梯度下降不断降低loss获得更好的权重(神经网络学习的本质都是通过GD不断降低loss,直到loss为0,学习得到的权重最佳)。第三个矩阵就是通过filter得到的最终特征图(feature map)。一个过滤器就会得到一维特征图,多个过滤器就会得到多为特征图。所以filter的数量决定输出的维度,即有多少个filter就会得到多少个feature map。 通道(channel):是由输入图像的维度决定的,输入多少维,channel数量就是多少。例如下图的输入是RGB三维,那么channel就是3。
步长(stride):filter是挨个过滤(stride=1)、还是隔一个一过滤(stride=2),也是提高速率的一种方式。
padding:对周边补0,主要是为了使输出大小和输入一致。没有padding操作,叫“vaild convolutions”,有padding操作,且卷积前后图片尺寸不变,即输入输出一致,叫“same convolutions‘。
相关运算
输入:n×n 过滤器:f×f 步长:s padding:p
o
u
t
p
u
t
=
[
n
+
2
p
?
f
s
+
1
]
?
[
n
+
2
p
?
f
s
+
1
]
output = [\frac{n+2p-f}{s} + 1] * [\frac{n+2p-f}{s} + 1]
output=[sn+2p?f?+1]?[sn+2p?f?+1] 其中[…] 表示向下取整,这是关于输入size、卷积、输出size之间关系的公式,这与卷积神经网络如何抓取特征的计算不是一回事,这里只是size维度变化的公式。filter与input之间的运算就是对应元素相乘然后求和。例如图一中的-5就是31+00+1*-1+11+50+8*-1+21+70+2*-1得到的。
pooling
卷积网络中一个典型层包含三级。在第一级中,并行计算多个卷积产生一组线性激活响应。在第二级中,每一个线性激活响应将会通过一个非线性的激活函数,也叫探测级(detector stage)。在第三级中,就是池化函数(pooling function)来进一步调整这一层的输出。池化函数使用某一位置相邻输出的总体统计特征来代替网络在该位置的输出。例如,最大池化(max pooling)函数是给出相邻矩形区域内的最大值。最大池化是较为常用的池化操作,我认为也是CNN提高效率的手段之一。其他的池化函数还包含平均池化,L2范数池化等。
不管采用什么样的池化函数,当输入作出少量平移时,池化能够帮助输入的表示近似不变。局部平移不变性是一个很有用的性质,尤其是当我们关心某个特征是否出现而不关心它出现的具体位置时。例如,当判定一张图像中是否包含人脸时,我们并不需要知道眼睛的精确像素位置,我们只需要知道有一只眼睛在脸的左边,有一只在右边就行了。但在一些其他领域,保存特征的具体位置却很重要。 总之,池化操作比较简单,就是把几个值放一起变成一个值的操作,为了快速抓取特征。
卷积网络&全连接网络
卷积其实就是全连接网络拿掉一些权重的结果,我觉着李宏毅老师的课程图非常好的解释了CNN的基本原理,把全连接变成了部分连接,参数共享体现在用相同的filter去过滤输入矩阵,图中相同颜色的线代表相同的权重值。
卷积网络的动机
卷积运算通过三个重要的思想来帮助改进机器学习系统: 稀疏交互(sparseinteractions)、参数共享(parameter sharing)、等变表示(equivariant representa-tions)。另外,卷积提供了一种处理大小可变的输入的方法。
稀疏交互(sparseinteractions):传统的神经网络使用矩阵乘法来建立输入与输出的连接关系。其中,参数矩阵中每一个单独的参数都描述了一个输入单元与一个输出单元间的交互。这意味着每一个输出单元与每一个输入单元都产生交互。然而,卷积网络具有稀疏交互(sparse interactions)(也叫做稀疏连接(sparse connectivity)或者稀疏权重(sparse weights))的特征。这是使核的大小远小于输入的大小来达到的。举个例子,当处理一张图像时,输入的图像可能包含成千上万个像素点,但是我们可以通过只占用几十到上百个像素点的核来检测一些小的有意义的特征,例如图像的边缘。这意味着我们需要存储的参数更少,不仅减少了模型的存储需求,而且提高了它的统计效率。这也意味着为了得到输出我们只需要更少的计算量。这些效率上的提高往往是很显著的。如果有m 个输入和n 个输出,那么矩阵乘法需要m×n 个参数并且相应算法的时间复杂度为O(m × n)(对于每一个例子)。如果我们限制每一个输 出拥有的连接数为k,那么稀疏的连接方法只需要k×n 个参数以及O(k×n) 的运行时间。在很多实际应用中,只需保持k 比m 小几个数量级,就能在机器学习的任务中取得好的表现。上述表达均为花书说法,其实就是上述的卷积与全连接网络的对比,全连接网络是稠密连接,卷积网络铺平后是稀疏连接。
参数共享(parameter sharing)是指在一个模型的多个函数中使用相同的参数。在传统的神经网络中,当计算一层的输出时,权重矩阵的每一个元素只使用一次,当它乘以输入的一个元素后就再也不会用到了。作为参数共享的同义词,我们可以说一个网络含有绑定的权重(tied weights),因为用于一个输入的权重也会被绑定在其他的权重上。在卷积神经网络中,核的每一个元素都作用在输入的每一位置上(是否考虑边界像素取决于对边界决策的设计)。卷积运算中的参数共享保证了我们只需要学习一个参数集合,而不是对于每一位置都需要学习一个单独的参数集合。这虽然没有改变前向传播的运行时间(仍然是O(k×n)),但它显著地把模型的存储需求降低至k 个参数,并且k 通常要比m 小很多个数量级。因为m 和n 通常有着大致相同的大小,k 在实际中相对于m×n 是很小的。因此,卷积在存储需求和统计效率方面极大地优于稠密矩阵的乘法运算。上述均为花书说法,其实就是上述的卷积与全连接网络的对比,铺平后会用相同的参数(就是相同颜色的线,对于卷积来说就是用一个filter去过滤了整个input)
对于卷积,参数共享的特殊形式使得神经网络层具有对平移等变(equivariance)的性质。如果一个函数满足输入改变,输出也以同样的方式改变这一性质,我们就说它是等变(equivariant) 的。
写在后面
读到某些文字,有更深的理解和感触,顺便记录下来,可能与底层原理关系不大。 网络结构的诀窍:当神经网络需要在多处使用相同的想法时,应试着在这些地方使用相同的权重。这样做会使那些权重有更多的样本可以学习并提高泛化能力,从而让权重更智能。
要出差… 先写到这里… 未完待续… 沉淀自己果然是个大工程…
|