前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度学习三人行(第9期)----卷积神经网络实战进阶(附代码)

深度学习三人行(第9期)----卷积神经网络实战进阶(附代码)

作者头像
智能算法
发布2018-12-17 11:30:19
3480
发布2018-12-17 11:30:19
举报
文章被收录于专栏:智能算法智能算法

上一期,我们一起学习了深度学习中卷积神经网络的通俗原理,

深度学习三人行(第8期)----卷积神经网络通俗原理

接下来我们一起学习下关于CNN的代码实现,内存计算和池化层等相关知识,我们多多交流,共同进步。本期主要内容如下:

  • CNN实现(TensorFlow)
  • CNN之内存计算
  • CNN之池化层
  • 小结

公众号内回复关键字,即可下载代码,关键字见文末!


一. CNN实现(TensorFlow)

在TensorFlow中,每一个图像都有一个3D的tensor,shape为[height, width, channels]。每一个mini-batch是以一个shape为[min-batch size, height, width, channels]的4Dtensor来表示的。卷积层的权重是以shape为[f_h, f_w, f_n, f_n'],其中偏置项是以1D tensor[f_n]表示。接下来,我们一起看下,在TensorFlow中是怎么实现的:首先,代码中用sklearn中的load_sample_images()来加载图片。然后手工创建了两个7x7的卷积核,一个为水平直线,一个为竖直直线。接着让图像通过一个卷积层conv2d()(边界扩充0,stride = 2),最后画出一个特征图。如下:

代码语言:javascript
复制
 1import numpy as np
 2from sklearn.datasets import load_sample_images
 3# Load sample images
 4dataset = np.array(load_sample_images().images, dtype=np.float32)
 5batch_size, height, width, channels = dataset.shape
 6# Create 2 filters
 7filters_test = np.zeros(shape=(7, 7, channels, 2), dtype=np.float32)
 8filters_test[:, 3, :, 0] = 1 # vertical line
 9filters_test[3, :, :, 1] = 1 # horizontal line
10# Create a graph with input X plus a convolutional layer applying the 2 filters
11X = tf.placeholder(tf.float32, shape=(None, height, width, channels))
12convolution = tf.nn.conv2d(X, filters, strides=[1,2,2,1], padding="SAME")
13with tf.Session() as sess:
14    output = sess.run(convolution, feed_dict={X: dataset})
15plt.imshow(output[0, :, :, 1]) # plot 1st image's 2nd feature map
16plt.show()

其中X是一个mini-batch(4D的tensor),filters也是一个4D的tensor,stride是一个有4个元素的1D tensor其中中间连个值为竖直和水平的stride,第一个元素和第四个元素必须是1,这个是备用的,以后可能会用在batch和channel上。padding必须设置为“VALID”或“SAME”,当设为“VALID”的时候,卷积层不进行边界扩充,但是可能会根据stride来忽略图像下面的某些行或右侧的某些列。如果设置为“SAME”,卷积层会进行对边界扩充0.这种情况下,输出神经元个数等于输入神经元个数除以stride,在下面的例子中输出层神经元为3,其中stride为5.如下:

所以,卷积层有一些参数要设置,比如:卷积核的个数,卷积核的高,卷积核的宽,以及stride,padding的类型。有时候,可以通过交叉验证来找最优的参数组合,但是这样往往是比较耗时的。后面我们会介绍一些通用的网络结构,可能会给我们一些启发,在实践中什么样的参数组合通常会得出最优的性能。


二. CNN之内存计算

卷积神经网络的一个问题就是需要大量的内存来处理数据,特别是在training阶段,因为反向传输需要保留前向传输的数据。举个例子,比方一个卷积层,其中卷积核为5x5,输出200个特征图,每一个特征图大小为150x100, stride为1,padding为"SAME",如果输入为一个150x100的RGB(3通道)图像的话,那么权重参数的个数为:

(5x5x3+1)x200 = 15200

其中+1为考虑到偏置项,相对来说,参数比全连接层要少。然而,每一个特征图包括150x100个神经元,每一个神经元需要计算5x5x3=75个权重,那么总共就有225million个浮点型数据相乘,虽然没有比全连接更糟,但是仍然是一个巨大的计算。如果特征图用32位float表示的话,那么一个卷积层将会占用:

200x150x100x32 = 96million bits

约11.4M内存,然而这只是一个样本,如果每个batch有100张图的话,那么单单这一层卷积层就要耗费超过一个G的内存。

在预测的时候,当一个卷积层计算的时候,就会将上一层所占用的内存释放掉,所以仅仅需要两个连续卷积层所占的内存即可。但是在计算的时候,每一次向前传输的数据都要为向后传输而保留,所以所需要的内存至少为全部层所占用的内存总和。

如果在training的时候,由于内存的问题导致crash,那么可以通过减少mini-batch的size来进行降低内存占有。当然也可以通过stride降维,或者减少一些层,甚至可以用16bit的float代替32bit的float或者多个设备来跑。

接下来,我们一起看一下CNN的另一个重要的构成:池化层。


三. CNN之池化层

一旦我们理解了卷积层的工作原理之后,池化层就相对来说比较简单了,池化层的目标就是为了降低计算负载,内存使用,参数数量,也可以降低过拟合的风险,而对输入进行的下采样。原理和卷积层一样,池化层的每一个神经元和上一层中有限区域(一个矩形的感受野)的神经元相连接。我们也必须定义感受野的size, stride,以及padding类型。然而不同的是,池化层的神经元没有权重,它的输出仅仅是输入区域的最大值或均值,下图显示了一个最大值的池化层,也是最常用的池化层,这个例子中用了一个2x2的池化核,stride=2,没有padding,也就是说,仅仅输出上一层中池化核位置的最大值到下一层。其他的输入都丢掉。

一般池化层在每一个输入通道上单独工作,所以经过池化层后,输入输出通道数不变。

在TensorFlow中实现池化还是蛮简单的,下面的代码创建一个2x2的池化核的池化层,stride为2,没有padding,然后应用到所有图像上。

代码语言:javascript
复制
1[...] # load the image dataset, just like above
2# Create a graph with input X plus a max pooling layer
3X = tf.placeholder(tf.float32, shape=(None, height, width, channels))
4max_pool = tf.nn.max_pool(X, ksize=[1,2,2,1], strides=[1,2,2,1],padding="VALID")
5with tf.Session() as sess:
6    output = sess.run(max_pool, feed_dict={X: dataset})
7plt.imshow(output[0].astype(np.uint8)) # plot the output for the 1st image
8plt.show()

上面参数ksize包括了池化核的4D参数[batch size, height, width, channels].TensorFlow目前暂时不支持跨样本池化,所以第一个数据必须是1,由于目前也不支持跨通道池化,所以最后一个参数也得是1.当然,想创建一个均值的池化层的话,仅仅将上面的max_pool替换为avg_pool即可。


四. 小结

今天,我们从TensorFlow上实现卷积层,以及卷积层的内存计算和池化层的相关原理知识等方面,更进一步的了解了CNN的知识。在学习的路上,我们共同进步,多谢有你。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-11-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 智能算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档