Chapter 13. Convolutional Neural Networks
来源:互联网 发布:河北高速网络查询 编辑:程序博客网 时间:2024/06/03 23:44
本篇文章是个人翻译的,如有商业用途,请通知本人谢谢.
Convolutional Layer
CNN最重要的组成部分是卷积层:第一卷积层中的神经元不是连接到输入图像中的每一个像素(就像它们在前面的章节中那样),而是仅仅连接到它们的局部感受野中的像素(参见图13-2)。 进而,第二卷积层中的每个神经元只与位于第一层中的小矩形内的神经元连接。 这种架构允许网络专注于第一隐藏层中的低级特征,然后将其组装成下一隐藏层中的高级特征,等等。 这种层次结构在现实世界的图像中是很常见的,这也是CNN在图像识别方面效果很好的原因之一。
到目前为止,我们所看到的所有多层神经网络都有由一长串神经元组成的层,在输入到神经网络之前我们必须将输入图像压缩成1D。 现在,每个图层都以2D表示,这使得神经元与其相应的输入进行匹配变得更加容易。
位于给定层的第i行第j列的神经元连接到位于前一层中的神经元的输出的第i行到第行,第j列到第列.fh和fw是局部感受野的高度和宽度(见图13-3)。 为了使图层具有与前一图层相同的高度和宽度,通常在输入周围添加零,如图所示。 这被称为零填充.
如图13-4所示,通过将局部感受野隔开,还可以将较大的输入层连接到更小的层。 两个连续的感受野之间的距离被称为步幅。 在图中,一个5×7的输入层(加零填充)连接到一个3×4层,使用3×3的卷积核和一个步幅为2(在这个例子中,步幅在两个方向是相同的,但是它并不一定总是如此)。 位于上层第i行第j列的神经元与位于前一层中的神经元的输出连接的第至行,第列, Sh和Sw是垂直和水平的步幅。
Filters(卷积核)
神经元的权重可以表示为局部感受野大小的小图像。 例如,图13-5显示了两个可能的权重集,称为flters(或卷积核)。第一个表示为中间有一条垂直的白线的黑色正方形(除了中间一列外,这是一个充满0的7×7矩阵,除了中央垂直线是1)。 使用这些权重的神经元会忽略他们的局部感受野的一切,除了中央垂直线(因为所有的inputs将得到0乘,除位于中央垂直线的)。第二个卷积核是一个黑色的正方形,中间有一条水平的白线。 再一次,使用这些权重的神经元将忽略除了中心水平线之外的局部感受野中的一切。
现在,如果一个图层中的所有神经元都使用相同的垂直线滤波器(以及相同的偏置项),并且将网络输入到图13-5(底部图像)中所示的输入图像,则该图层将输出左上图像。 请注意,垂直的白线得到增强,其余的变得模糊。 类似地,如果所有的神经元都使用水平线滤波器,右上角的图像就是你所得到的。 注意到水平的白线得到增强,其余的则被模糊了。因此,使用相同滤波器的一个充满神经元的图层将为您提供一个特征图,该特征图突出显示图像中与滤波器最相似的区域。 在训练过程中,CNN为其任务找到最有用的过滤器,并学习将它们组合成更复杂的模式(例如,交叉是图像中垂直过滤器和水平过滤器都活动的区域)。
Stacking Multiple Feature Maps(叠加的多个特征图)
到目前为止,为了简单起见,我们已经将每个卷积层表示为一个薄的二维层,但是实际上它是由几个相同大小的特征图组成的,所以它在3D中被更精确地表示(见图13-6)。 在一个特征映射中,所有神经元共享相同的参数(权值共享)(权重和偏置),但是不同的特征映射可能具有不同的参数。 神经元的感受野与前面描述的相同,但是它延伸到所有先前的层的特征图。 简而言之,卷积层同时对其输入应用多个滤波器,使其能够检测输入中的任何位置的多个特征。
事实上,特征地图中的所有神经元共享相同的参数会显着减少模型中的参数数量,但最重要的是,一旦CNN学会识别一个位置的模式,就可以在任何其他位置识别它。 相比之下,一旦一个常规DNN学会识别一个位置的模式,它只能在该特定位置识别它。
而且,输入图像也由多个子图层组成:每个颜色通道一个。 通常有三种:红色,绿色和蓝色(RGB)。 灰度图像只有一个通道,但是一些图像可能更多 - 例如捕捉额外光频(如红外线)的卫星图像。
具体地,位于给定卷积层L中的特征映射k的i行,j列中的神经元连接到前一层(L-1)位于行,列的神经元的输出.请注意,位于同一行第i列和第j列但位于不同特征映射中的所有神经元都连接到上一层中完全相同神经元的输出。
公式13-1在一个总结前面解释的大的数学公式:它展示了如何计算卷积层中给定神经元的输出。它是计算所有投入的加权总并且加上偏置。
- 是卷积层(L层)特征映射k中位于第i行第j列的神经元的输出.
- 如前所述,和是垂直和水平的步幅,和是感受野的高度和宽度,是前一层(第l - 1层)的特征图的数量。
- 是位于层L-1,i'行,j'列,特征图k'(或者如果前一层是输入层的通道k')的神经元的输出。
- 是特征映射k的偏置项(在L层中)。 您可以将其视为调整特征映射k的整体亮度的旋钮。
- 是层L的特征映射k中的任何神经元与位于行u,列v(相对于神经元的感受野)的输入之间的连接权重,以及特征映射k'。
from sklearn.datasets import load_sample_imageimport matplotlib.pyplot as pltimport numpy as npimport tensorflow as tfif __name__ == '__main__': # Load sample images china = load_sample_image("china.jpg") flower = load_sample_image("flower.jpg") dataset = np.array([china, flower], dtype=np.float32) batch_size, height, width, channels = dataset.shape # Create 2 filters filters = np.zeros(shape=(7, 7, channels, 2), dtype=np.float32) filters[:, 3, :, 0] = 1 # vertical line filters[3, :, :, 1] = 1 # horizontal line # Create a graph with input X plus a convolutional layer applying the 2 filters X = tf.placeholder(tf.float32, shape=(None, height, width, channels)) convolution = tf.nn.conv2d(X, filters, strides=[1,2,2,1], padding="SAME") with tf.Session() as sess: output = sess.run(convolution, feed_dict={X: dataset}) plt.imshow(output[0, :, :, 1], cmap="gray") # plot 1st image's 2nd feature map plt.show()大部分代码是不言而喻的,但conv2d()行值得解释一下:
- X是输入最小批量(4D张量,如前所述)
- 卷积核是应用的一组卷积核(也是一个4D张量,如前所述)。
- 步幅是一个四元素的一维数组,其中两个中心元素是垂直和水平的步幅(sh和sw)。 第一个和最后一个元素现在必须等于1.他们可能有一天会被用来指定批量步长(跳过一些实例)和频道步幅(跳过上一层的特征映射或通道)。
- padding必须是“VALID”或“SAME”:
例如,考虑具有5×5滤波器的卷积层,输出200个尺寸为150×100的特征图,步长为1,使用SAME padding。 如果输入是150×100 RGB图像(三个通道),则参数的数量是(5×5×3 + 1)×200 = 15,200(+1对应于偏置项),这跟全连接层比较是相当小的.(具有150×100神经元的全连接层,每个连接到所有150×100×3输入,将具有150 ^ 2×100 ^ 2×3 = 675,000,000个参数!)然而,200个特征图中的每一个包含150×100个神经元,并且这些神经元中的每一个都需要计算其5×5×3 = 75个输入的权重和:总共2.25亿次浮点乘法。不像完全连接的层那么糟糕,但仍然是计算密集型的。 而且,如果使用32位浮点数来表示特征映射,则卷积层的输出将占用RAM的200×150×100×32 = 9600万位(大约11.4MB)。 这只是一个例子! 如果培训批次包含100个实例,则该层将占用超过1 GB的RAM!
一旦你理解了卷积层是如何工作的,池化层很容易掌握。 他们的目标是对输入图像进行二次抽样(即收缩)以减少计算负担,内存使用量和参数数量(从而限制过度拟合的风险)。 减少输入图像的大小也使得神经网络容忍一点点的图像移位(位置不变)。
池化层通常独立于每个输入通道工作,因此输出深度与输入深度相同。 接下来可以看到,在这种情况下,图像的空间维度(高度和宽度)保持不变,但是通道数目可以减少。
import numpy as npfrom sklearn.datasets import load_sample_imageimport tensorflow as tfimport matplotlib.pyplot as pltchina = load_sample_image("china.jpg")flower = load_sample_image("flower.jpg")dataset = np.array([china, flower], dtype=np.float32)batch_size, height, width, channels = dataset.shape# Create 2 filtersfilters = np.zeros(shape=(7, 7, channels, 2), dtype=np.float32)filters[:, 3, :, 0] = 1 # vertical linefilters[3, :, :, 1] = 1 # horizontal lineX = tf.placeholder(tf.float32, shape=(None, height, width, channels))max_pool = tf.nn.max_pool(X, ksize=[1,2,2,1], strides=[1,2,2,1],padding="VALID")with tf.Session() as sess: output = sess.run(max_pool, feed_dict={X: dataset})plt.imshow(output[0].astype(np.uint8)) # plot the output for the 1st imageplt.show()
ksize参数包含沿输入张量的所有四个维度的内核形状:[批量大小,高度,宽度,通道]。 TensorFlow目前不支持在多个实例上合并,因此ksize的第一个元素必须等于1.此外,它不支持在空间维度(高度和宽度)和深度维度上合并,因此ksize [1] 和ksize [2]都必须等于1,否则ksize [3]必须等于1。
LeNet-5架构也许是最广为人知的CNN架构。 如前所述,它是由Yann LeCun于1998年创建的,广泛用于手写数字识别(MNIST)。 它由表13-1所示的层组成。
- MNIST图像是28×28像素,但是它们被补零到32×32像素,并且在被喂到网络之前被归一化。 网络的其余部分不使用任何填充,这就是为什么随着图像在网络中的进展,大小不断缩小。
- 平均池化层比平常稍微复杂一些:每个神经元计算输入的平均值,然后将结果乘以一个可学习的系数(每个特征图一个),并添加一个可学习的偏差项(每个特征图一个),然后最后应用激活函数。
- C3地图中的大多数神经元仅在三个或四个S2地图(而不是全部六个S2地图)中连接到神经元。 有关详细信息,请参阅原始纸张中的表1。
- 输出层有点特殊:每个神经元不是计算输入和权向量的点积,而是输出其输入向量和其权向量之间的欧几里德距离的平方。 每个输出测量图像属于特定数字类别的多少。 交叉熵损失函数现在是首选,因为它更多地惩罚不好的预测,产生更大的梯度,从而更快地收敛。
- 是位于特征映射i的神经元的标准化输出,在某行u和列v(注意,在这个等式中我们只考虑位于这个行和列的神经元,所以u和v没有显示)。
- 是在ReLU步骤之后,但在归一化之前的那个神经元的激活。
- k,α,β和r是超参数。 k称为偏置,r称为深度半径。
- 是特征图的数量。
- 前两层将图像的高度和宽度除以4(使其面积除以16),以减少计算负担。
- 然后,局部响应规范化层确保前面的层学习各种各样的功能(如前所述)
- 接下来是两个卷积层,其中第一个像瓶颈层一样。 正如前面所解释的,你可以把这一对看作是一个单一的更智能的卷积层。
- 再次,局部响应标准化层确保了先前的层捕捉各种各样的模式。
- 接下来,最大池化层将图像高度和宽度减少2,再次加快计算速度。
- 然后是九个“盗梦空间”模块的高堆栈,与几个最大池层交织,以降低维度并加速网络。
- 接下来,平均池化层使用具有VALID填充的特征映射的大小的内核,输出1×1特征映射:这种令人惊讶的策略被称为全局平均共享。 它有效地强制以前的图层产生特征图,这些特征图实际上是每个目标类的置信图(因为其他类型的功能将被平均步骤破坏)。 这样就不必在CNN的顶部有几个完全连接的层(如AlexNet),大大减少了网络中的参数数量,并限制了过度拟合的风险。
- 最后一层是不言自明的:正则化drop out,然后是具有softmax激活函数的完全连接层来输出估计类的概率。
最后但并非最不重要的是,2015年ILSVRC挑战赛的赢家Kaiming He等人开发的剩余网络(或ResNet),该网络的打败前5错误率低到3.6%,它使用了一个非常深的CNN,由152层组成。 能够训练如此深的网络的关键是使用跳过连接(也称为快捷连接):喂到一个层的信号也被添加到位于比堆栈高一点的层的输出。 让我们看看为什么这是有用的.
TensorFlow还提供了一些其他类型的卷积层:
- conv1d()为1D输入创建一个卷积层。 例如,在自然语言处理中这是有用的,其中句子可以表示为一维单词阵列,并且接受场覆盖一些邻近单词。
- conv3d()创建一个3D输入的卷积层,如3D PET扫描。
- atrous_conv2d()创建了一个有趣的卷积层(“àtrous”是法语“with holes”)。 这相当于使用具有通过插入行和列(即,孔)而扩大的滤波器的规则卷积层。 例如,等于[[1,2,3]]的1×3滤波器可以以4的扩张率扩张,导致扩张的滤波器[[1,0,0,0,2,0,0,0,3]]。 这使得卷积层在没有计算价格的情况下具有更大的局部感受野,并且不使用额外的参数。
- conv2d_transpose()创建了一个转置卷积层,有时称为去卷积层,它对图像进行上采样(这个名称是非常具有误导性的,因为这个层并不执行去卷积,这是一个定义良好的数学运算(卷积的逆)) 。这是通过在输入之间插入零来实现的,所以你可以把它看作是一个使用分数步长的规则卷积层。例如,在图像分割中,上采样是有用的:在典型的CNN中,特征映射越来越小当通过网络时,所以如果你想输出一个与输入大小相同的图像,你需要一个上采样层。
- depthwise_conv2d()创建一个深度卷积层,将每个滤波器独立应用于每个单独的输入通道。 因此,如果有fn滤波器和fn'输入通道,那么这将输出fn×fn'特征映射。
- separable_conv2d()创建一个可分离的卷积层,首先像深度卷积层一样工作,然后将1×1卷积层应用于结果特征映射。 这使得可以将滤波器应用于任意的输入通道组。
- Chapter 13. Convolutional Neural Networks
- Convolutional Neural Networks
- Convolutional Neural Networks (LeNet)
- Convolutional Neural Networks Posts
- Convolutional neural networks
- Convolutional Neural Networks学习
- Convolutional Neural Networks
- Convolutional Neural Networks: Application
- Convolutional Neural Networks
- Tiled convolutional neural networks(TCNN)
- Convolutional Neural Networks卷积神经网络
- 卷积神经网络(Convolutional Neural Networks)
- Convolutional Neural Networks for Speech
- Notes on Convolutional Neural Networks
- Convolutional Neural Networks 卷积神经网络
- Convolutional Neural Networks卷积神经网络
- Convolutional Neural Networks卷积神经网络
- CNN(Convolutional Neural Networks)算法
- struts2的核心和工作原理
- Android源码编译JNI
- log4net 使用笔记(asp.netcore)
- 金蝶万能票据通旗靓版V6.0
- LightOJ 1004 Monkey Banana Problem
- Chapter 13. Convolutional Neural Networks
- python读取csv文件
- Vue项目build出的网页显示错误,css中图片引用位置错误解决办法
- 遥感基础
- C++ vector的拷贝
- Java中的Copy-On-Write容器
- [leetcode]122. Best Time to Buy and Sell Stock II
- Linux Unit18--ftp
- ubantu下sqlserver安装及使用