大家好,我是禅师的助理兼人工智能排版住手助手条子。
虽然很不愿意提起这件伤心事,但国庆假期确实结束了。在这说长不长说短也不算短的7天里,不知道大家有没有吃好喝好玩好pia学好呢?
我确实不想上班,但你满世界嚷嚷就能改变现实改变命运吗?不能。能改变命运的,除了考父母,就只有靠自己的能力了。
今天给大家带来的这篇文章,是国外一个非科班出身的哥们,半路开始研究卷积神经网络结构的心路历程。因为没有系统的指导,中间也走过不少弯路。
条子觉得,他的处境,也是国内很多刚开始学习人工智能的开发者、学生面临的情况。所以这篇文章,很有现实意义。
本文由译智社的小伙伴翻译。这是一群来自全国多所顶级高校、很有理想的年轻人,因为热爱人工智能,组成了一个社团(字面意义的社团),努力推进人工智能的普及。
全文大约3500字。请大家把这段语音转发出去。转发这段语音的操作步骤:转发这篇文章
文 | DISHASHREE GUPTA
翻译 | FontTian
编辑 | strongnine
译者注:
https://www.analyticsvidhya.com/blog/2017/06/architecture-of-convolutional-neural-networks-simplified-demystified/
原作者的文章其实更利于读者对卷积本身的理解,但是实际上作者对卷积的现实意义的理解并没有解释的十分清楚,甚至可能不利于读者的理解,也正因为如此我在翻译过程中可能对原文部分内容进行了比较大的改动或增删,希望这对你有帮助。
实际上卷积神经网络的灵感是来自神经学的研究,其计算过程实际上模拟了视觉神经系统的运算过程。这一部分内容请翻阅其他文章。
TensorFlow中该部分的内容可以参考我的博客:
卷积函数:
https://link.zhihu.com/?target=http%3A//blog.csdn.net/fontthrone/article/details/76652753
池化函数:
https://link.zhihu.com/?target=http%3A//blog.csdn.net/fontthrone/article/details/76652762
介绍
我曾经很懊悔过去一段时间没时间真正去理解深度学习。 过去一段时间通过话题上的研究论文和文章,感觉这是一个非常复杂的话题。 我试着理解神经网络及其各种类型,但它似乎很困难。
然后有一天,我决定要一步一个脚印,从头构建基础。 我决定要打破这些技术应用的步骤,做手工(计算)的步骤,直到我理解它们是如何工作的。 是时候采取如此大的努力了,但收获同样是惊人的。
现在,我不仅可以了解深度学习的范围,甚至我想出更好的方法,毕竟我的基础已经达到了。
今天,我要与你分享我的学习心得。 我将向您展示如何理解卷积神经网络。我将带您亲历的我曾经的旅程,并通过这使你深刻的理解cnn是如何工作的。
在这篇文章中我将讨论卷积神经网络背后的架构,这是为了解决图像识别和分类问题。
本文假设你对经网络是如何工作的有一个基本的了解。 如果你不确定你的知识储备足够阅读这篇文章,那么或许另外一篇文章对你会有帮助。
英文原文:
https://link.zhihu.com/?target=https%3A//www.analyticsvidhya.com/blog/2017/05/neural-network-from-scratch-in-python-and-r/
1. 机器如何「看到」一个图像?
人类的大脑是一个非常强大的机器。 我们看到每秒钟(捕捉)多个图像并处理处理它们,却又从未意识到这其中其实已经进行了极其复杂的运算,而对于机器而言显然没有这么容易。 其中图像处理的第一步是理解:如何表示一幅图像使得机器也可以读图。
其表示方法为,每一个图像点(像素)的以矩阵的形式进行存储。 如果你改变订单或颜色的像素,图像也会改变。 让我们举一个例子。 让我们说,你想要存储和读取一幅写有数字4的图片。
机器会打「阅读」图像像素的矩阵和存储每个像素的颜色代码代表的位置。 在下面的描述中,1号是白色的,256是最黑暗的阴影绿色(实际上应该是黑色,但是为了便于表示每个像素的编号都以一种颜色,绿色的深浅程度进行表示)。
图片的数字化展示
一旦确定了图像的存储格式,下一个挑战是我们的神经网络理解的安排和模式。
2. 我们如何帮助一个神经网络来识别图像?
一个号码是由像素排列的不同组合表示。
首先,假设我们尝试使用一个传统的完全连接网络来识别它吗,效果会怎样呢?
完全连接网络:全连接神经网络,fully connected network.
完全连接网络将这张照片作为数组通过压缩和考虑像素值作为特征来预测数字图像。 结果如下:
这是一个表示数字4。 我们已经完全失去了像素的空间排列,其结果好像是人类无法理解的。
而实际上我们应该做些什么呢?我们应该做的是从图像中提取特征,并保存其空间分布,这样才算是使机器学会了「看懂」图像。那么我们到底应该怎么做呢?或许下面的案例可以帮助我们理解机器「看懂」图像的方法。
案例 1:
这里我们使用了一个权重乘以最初的像素值。
它为肉眼识别变得容易,这是一个4。 但再次发送这张照片到完全连接网络,其就会变一维数组。 这种方法无法保存图像的空间排列。
看来这种方式并不能帮助机器学习「看懂」图像。
案例 2:
通过上面的案例我们可以看到,一维化的图像完全破坏了它的空间排列。我们需要设计一种方法,将图像发送到一个网络,而不需要将图像拉平,并保留其空间布局。
让我们尝试一次获取图像的两个像素值,而不是只计算一个。这将为网络提供一个很好的视角来了解相邻的两个像素是怎样的。现在我们每次取两个像素,同样的我们也要取两个权重值来进行计算。
我希望你们注意到,图像现在从4列排列开始变成了一个3列排列。因为我们每次移动两个像素(像素在每个移动中得到共享),所有图像变得更小了。另外,要意识到的一个重要事实是,因此这里只考虑水平排列,我们要连续使用两个连续的水平像素,而当我们考虑垂直元素时,我们将会使用两个在垂直方向上连续的权值(译者加)。
这是一种从图像中提取特征的方法。 我们观察图像处理后的不同部分,其中右边不像原来那样清晰了。 这是由两个原因造成的:
左边和右边的角落图像像素只乘了权重一次。
左侧部分颜色仍然很深,因为权重值较高,而右侧部分颜色由于较低的权重而略有下降。
现在我们有两个问题,我们有两个解决方案来解决这些问题。
案例 3:
遇到的问题是图像的左和右角落正在通过的权重只有一次。 解决方案使左右边缘像素和图片中的其它像素一样能够与权重进行多次相乘。
我们有一个简单的解决方案来解决这个问题:图像两边加上数值全部为零的列。
如图所示,通过添加数值为零的列,边缘信息得以保留,图像的大小也随之变大。 当我们不想要图像大小减小时,我们可以使用上面这种方法。
同样的我们也可以通过在图片周围提前增加数值为零的列来使输入输出的图像大小一致,这种两种不同的卷积方式,在TensorFlow中都可以通过简单的参数控制来实现,输入输出图像的大小计算方法,在下文中会提及。(译者加)
案例 4:
我们在这里要解决的问题是,右侧角落的较小权重值会降低像素值,从而使我们难以识别。我们能做的是,我们在一个回合中采用多个重量值并将它们组合在一起。
权重(1, 0.3)给了我们一个输出的形式:
然后权重(0.1, 5)会给我们另外一个输出的形式:
这两个图像的组合版本将给我们一个非常清晰的图片。因此,我们所做的是简单地使用多个权重,而不是只使用一个权重来尝试保留关于图像的更多信息。而本例子中的最终输出将是上述两个图像的组合版本。
案例 5:
直到现在我们使用的权重一起处理水平像素。 但在大多数情况下,我们需要在水平和垂直方向保留图像的空间排列。 我们可以用权重的二维矩阵在水平和垂直方向与像素同时相乘。 同时,请记住,因为我们两个水平和垂直运动的权重,输出是一个像素在水平和垂直方向维度都更低的图像,也就是输出的图像比输入图像小了。
特别感谢杰里米·霍华德的鼓舞我创建这些视觉效果。
上面的案例中,我们到底做了什么呢?
上面我们所做的是,试图从图像中提取特征,并保留图像的空间排列。 理解图像的极其重要一点就是的了解像素排列。 而上面我们所做的其实就是卷积神经网络所做的事情。 我们可以把输入图像用我们定义的权值矩阵(卷积核)进行卷积操作,从而获取我们想要的结果。
这种方法有另一个好处是,它减少了参数的数量。
3. 定义一个卷积神经网络
我们需要三个基本组件来定义一个基本卷积网络。
卷积的层
池层(可选)
输出层
让我们看看这些详细:
3.1 卷积层
在这一层,就是我们看到的在案例五即之后之后的例子。 假设我们有一个图像的大小6 * 6。 我们定义了一个权重矩阵中提取图像的某些特性:
我们已经初始化了体重3 * 3矩阵。 这个权重应当对每个像素都进行运算,给一个卷积的输出:
6 * 6的图像现在转换成一个4 * 4的形象。 把权重矩阵像画笔画一堵墙。想象一下重量矩阵就像油漆刷画墙一样。画笔首先水平地画出墙壁中的一行,然后向下,在水平地画下第二行,然后向下画出第三行,直到整面墙壁都被粉刷完毕。而当权重矩阵沿着图像移动时,像素值再次被使用。 再次当权重矩阵沿着图像像素才一次被使用。 这个特性允许在卷积神经网络中进行参数共享。
让我们看看真实的效果。
权重矩阵的行为像一个过滤器的图像从原始图像中提取特定的信息矩阵。重量组合可能是提取边缘,而另一个可能是量化一个特定的颜色,而另一个可能只是提取模糊不需要的噪声。通过不同的卷积核操作,我们通过计算机实现了对图像不同特征的提取或者其他操作(译者加)
权重是这样学习的:最小化类似于一个MLP的损失函数。因此,从原来的图像中提取出一些特征来帮助网络进行正确的预测。当我们有多个卷积层时,初始层会提取更多的泛型特征,而随着网络的深入,权重矩阵提取的特征变得越来越复杂,同时也更适合于图像的识别与处理。
步长和填充(补零)的概念
在我们之前的案例中,过滤器或权重矩阵,在整个图像移动的一次只移动 一个像素。 其移动的像素数量,我们称之为步长,下图是步长为2的例子:
正如你所看到的图像大小的继续减少当我们增加步长的值。 而在图像中增加为零的维度则帮助我们解决了这个问题。 如下:
我们可以看到图像的初始形状是如何保留在我们用零填充图像。 这就是所谓的 相同的填充 由于输出图像具有相同的大小作为输入。
通过这种方式,我们保留了更多的来自图像边界的信息,并保留了图片的大小。
多个过滤器和激活映射
要记住的一件事是,深度尺寸的权重和输入图像的深度尺寸一样。 权重延伸到整个输入图像的深度。 因此,与单个权重卷积矩阵与一个输出卷积结果的深度维度。 同时因为在大多数情况下我们有相同的多个卷积核一起应用,那么我们将会获取的图像数量也会随着卷积核数量的增加而增加。
每个过滤器的输出是堆叠在一起形成的深度尺寸卷积图像。 假设我们有一个输入图像的大小32 * 32 * 3。 我们应用10个大小为5 * 5 * 3的卷积核对其进行卷积(方式为不填充数值为的维度)。那么卷积层的输出会维度将会是28 * 28 * 10。
你可以想象这是:
3.2 池化层
有时候图片太大,我们需要减少可训练的参数。这时候我们可以在不同的卷积层之间添加池层。 池化的唯一目的是减少图像的空间大小。 池化是独立在每个深度尺寸,因此图像的深度保持不变。 最常见的池化层一般采用最大池化(另外一种方式为平均池化)。
同时池化层也强化了神经网络的鲁棒性(抗干扰性),使得目标图像在图像位置中的轻微形变对神经网络最终预测的影响变小(译者加)
这里我们已经大步,而池大小也是2。 最大池化操作应用于每个深度维度的卷积的输出。 正如你所看到的,4 * 4卷积后输出已成为2 * 2马克斯池操作。
让我们看看最大池化的实际应用。
正如你所看到的我已经复杂的图像,应用最大池化。 最大池化后的图像仍然保留信息,这是一个汽车在一条街上。 如果你仔细看,其尺寸图像已经减半。 这可以在很大程度上减少运算。
类似的其他形式的池化比如平均池化或L2范数池化。
输出尺寸
上面的内容可能会使你混淆每一层的输出尺寸。 所以我决定使用下面的内容让你能够识别输出尺寸。 在卷积层中,有三个关键控制着输出尺寸的大小:
过滤器的数量—— 输出音量的深度就等于滤波器应用的数量。 每个滤波器(卷积核)可以输出一个图片,卷积核增加,输出图片的数量增加;
步长—— 控制着卷积核向下移动的像素值。 高步值长时我们跨过的像素值,因此产生较小的输出量;
补零—— 这有助于我们保持输入图像的大小。 如果只在原始图像周围添加一个补零的层数,并且步长为一,那么输出将保留原始图像的大小。
我们可以应用一个简单的公式来计算输出尺寸。 输出图像的空间大小可以计算(W - F + 2 p / S) + 1。 这里,W是输入图片大小,F是卷积核的大小,P是填充应用的数量和S是步长的数量。 假设我们有一个输入图像的大小32 * 32 * 3,我们应用10过滤器的大小3 * 3 * 3,与单步和补零。
W = 32,F = 3,P = 0和S = 1。 输出深度等于过滤器应用的数量即10。
输出音量的大小将( 32 - 3 + 0 ) / 1 + 1 = 30。 因此,输出音量将30 * 30 * 10。
3.3 输出层
以图像识别为例,多层的卷积和池化之后,我们需要输出一个类别的形式。 卷积和池化层只是从原始图像中提取了特征,然而想要生成最终的输出,我们需要在卷积层之后加入一个全连接层,并使全连接层的输出等于我们的实际的图像分类的类别。对于卷积层最后的图像我们只需要输出其是否属于一个特定的类。 输出层有一个像分类交叉熵那样的损失函数,来计算预测中的误差。一旦分类完成,反向传播就开始更新权重和偏差的错误和减少损失。
4. 把它们放在一起,整个网络如何看起来像什么?
CNN现在可以看到由各种卷积和池化层。 让我们来看看网络的样子。
我们首先通过一个输入图像卷积层。 获得复杂的输出作为一个激活地图。 卷积过滤器应用于层从输入图像中提取相关特征进一步通过;
每个过滤器应当给予不同的特性来帮助预测正确的类。 以防我们需要保留图像的大小,我们使用相同的填充(补零),其他明智有效填充,因为它有助于减少使用的数量特征;
池层然后进一步减少参数的数量;
几个卷积和池层添加之前的预测。卷积层帮助提取特征。 网络中我们更深更具体的特性提取相比浅网络特征提取更通用;
CNN 如前所述的输出层是一个完全连接层,其他层的输入在这里被变成一维数据,发送输出转换成类的数量,所期望的网络;
然后生成的输出通过输出层和输出层的误差比较。 其中定义的一个损失函数是完全连接输出层计算均方损失。 然后计算误差的梯度;
错误然后backpropagated更新过滤器(权重)和偏差值;
一个训练周期完成在一个向前和向后传递。
5. 在 KERAS 中使用 CNN 分类图像
让我们尝试以一个例子,我们输入一些猫和狗的图片,我们试着对这些图像进行分类成各自的动物种类。 这是一个典型的图像识别和分类的问题。 这台机器需要做什么是看到图片并理解的各种特性,从而判断其是否一只猫或狗。
下面是一些图像数据集的例子。
我们首先需要调整这些图像的大小以使它们全部处于相同的形状。这是我们在处理图像时通常需要做的事情,因为在捕获图像时,不可能捕获相同大小的所有图像。
为了简化您的理解,我刚刚使用了单个卷积层和单个池化层来进行讲解,而通常我们是不会定义这种简单的神经网络结构的。下面代码示例中使用的数据集可以从原文提供的地址下载:
https://link.zhihu.com/?target=http%3A//files.fast.ai/data/dogscats.zip
在这个模型中,我只使用了一个卷积层和池层,可训练的参数是219, 801。如果我在这种情况下使用了一个MLP,我将会有多少输出结果呢?您可以通过添加更多的卷积和池层来进一步减少参数的数量。我们添加的更多的卷积层网络结构和训练将会更复杂,但是同样的结果也会更好。
幸福
无非就是
我 & 你
我 AI 你
领取专属 10元无门槛券
私享最新 技术干货