专栏首页智能算法深度学习三人行(第9期)----卷积神经网络实战进阶(附代码)

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

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

深度学习三人行(第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),最后画出一个特征图。如下:

 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,然后应用到所有图像上。

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的知识。在学习的路上,我们共同进步,多谢有你。

本文分享自微信公众号 - 智能算法(AI_Algorithm)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-11-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Matlab编程之——卷积神经网络CNN代码解析

    deepLearnToolbox-master是一个深度学习matlab包,里面含有很多机器学习算法,如卷积神经网络CNN,深度信念网络DBN,自动编码Auto...

    智能算法
  • 技术 | 变形卷积核、可分离卷积?CNN中十大拍案叫绝的操作

    CNN从2012年的AlexNet发展至今,科学家们发明出各种各样的CNN模型,一个比一个深,一个比一个准确,一个比一个轻量。我下面会对近几年一些具有变革性的工...

    智能算法
  • 机器视觉算法(第12期)----图像处理中的卷积操作真的是在做卷积吗?

    上期我们一起学习来了OpenCV中的绘图与注释, 机器视觉算法(第11期)----OpenCV中的绘图与注释

    智能算法
  • 深度学习中的参数梯度推导(三)下篇

    在深度学习中的参数梯度推导(三)中篇里,我们总结了CNN的BP推导第一步:BP通过池化层时梯度的计算公式。本篇(下篇)则继续推导CNN相关的其他梯度计算公式。

    灯塔大数据
  • Matlab编程之——卷积神经网络CNN代码解析

    这这是之前我共享的一个深度学习工具包,这是解释代码的一部分,具体的一些细节还还望大家根据自己的能力去做,慢慢去理解。不急昂! 源代码我公布出来希望大家学习交流,...

    量化投资与机器学习微信公众号
  • Matlab编程之——卷积神经网络CNN代码解析

    deepLearnToolbox-master是一个深度学习matlab包,里面含有很多机器学习算法,如卷积神经网络CNN,深度信念网络DBN,自动编码Auto...

    智能算法
  • 10分钟看懂全卷积神经网络( FCN ):语义分割深度模型先驱

    今天是10月24日,既是程序员节,也是程序员感恩节。这一天,大家纷纷向那些无私奉献、一心为民的好人们,送出“好人一生平安”的美好祝愿。而“1024”,既是这一句...

    用户1737318
  • 卷积神经网络学习路线(二)| 卷积层有哪些参数及常用卷积核类型盘点?

    上一篇推文介绍了卷积神经网络的组成层以及卷积层是如何在图像中起作用的,推文地址为:https://mp.weixin.qq.com/s/MxYjW02rWfRK...

    BBuf
  • 卷积神经网络学习路线(四)| 如何减少卷积层计算量,使用宽卷积的好处及转置卷积中的棋盘效应?

    这是卷积神经网络的学习路线的第四篇文章,这篇文章主要为大家介绍一下如何减少卷积层的计算量,使用宽卷积的好处以及转置卷积中的棋盘效应。

    BBuf
  • 【论文笔记】Pyramidal Convolution: Rethinking Convolutional Neural Networks for Visual Recognition

    目前的卷积神经网络普遍使用3×3的卷积神经网络,通过堆叠3×3的卷积核和下采样层,会在减少图像的大小的同时增加感受野,使用小尺度的卷积核存在两个问题:

    绝命生

扫码关注云+社区

领取腾讯云代金券