tensorflow之卷积神经网络

卷积神经网络CNN(convolutional neural networks,CNN)是一种类似于人工神经网络的深度学习模型或多层感知机,常用在图像分类、目标检测、图像语义分割等领域,随着大规模图像数据的产生以及计算机硬件(特别是GPU)的飞速发展,其强大的特征学习与分类能力引起了广泛的关注,具有重要的分析与研究价值。

一、what is CNN?

工欲善其事必先利其器,为了更好理解卷积神经网络,需要研究其基本原理。推荐阅读斯坦福的CS231n

1. 视觉感知

人类视觉对于不同物体识别是通过逐层分级来进行认知的,如下图所示。在最底层特征基本上是类似的,就是各种边缘,越往上,越能提取出此类物体的一些特征(*、眼睛、躯干等),到最上层,不同的高级特征最终组合成相应的图像,从而能够让人类准确的区分不同的物体。

tensorflow之卷积神经网络

而卷积神经网络的灵感源正是来源于此,其中神经元之间的联结模式和动物视觉皮层组织非常相似。每个皮层神经元只对视野(也常称为感受野)的限定区域内的刺激物做出反应。不同神经元的感受野会出现部分重叠,这样它们覆盖了整个视野。

2. CNN结构

卷积神经网络模型通常建立在前馈神经网络模型基础上,只是隐藏层换成了卷积层、池化层、全连接层,如下图所示。

tensorflow之卷积神经网络

  • 输入层:用于数据的输入
  • 卷积层:使用卷积核进行特征提取和特征映射
  • 激励层:由于卷积也是一种线性运算,因此需要增加非线性映射
  • 池化层:进行下采样,对特征图稀疏处理,减少数据运算量。
  • 全连接层:通常在CNN的尾部进行重新拟合,减少特征信息的损失
  • 输出层:用于输出结果

2.1 输入层

图像在计算机中是一堆按顺序排列的数字,数值为0到255。0表示最暗,255表示最亮。 可以把这堆数字向量来表示,也就是tensorflow进阶的784(24*24)维向量,如下图所示。

tensorflow之卷积神经网络

而对于更常见的RGB颜色模型,单个矩阵就扩展成了有序排列的三个矩阵,也可以用三维张量去理解,其中的每一个矩阵又叫这个图片的一个channel。画面识别的输入是shape为(width, height, depth)的三维张量,如下图所示。

tensorflow之卷积神经网络

2.2 卷积层

这一层也是卷积神经网络最重要一层,有两个关键操作:局部关联和权值共享。

2.2.1 局部关联

在卷积神经网络中,我们先选择一个局部区域,用这个局部区域去扫描整张图片。 局部区域所圈起来的所有节点会被连接到下一层的一个节点上。因此,隐藏层中的神经元的感受视野比较小,只能看到上一次的部分特征,上一层的其他特征可以通过平移感受视野来得到同一层的其他神经元。而在全连接神经网络中,隐藏层中的神经元的感受视野足够大乃至可以看到上一层的所有特征。

tensorflow之卷积神经网络

在上图中,黄色的方框就叫做卷积核( filter )。 而filter的范围叫做filter size,这里所展示的是3x3的filter size。

tensorflow之卷积神经网络

tensorflow之卷积神经网络

2.2.2 权值共享

在卷积层中每个神经元连接数据窗的权重是固定的,每个神经元只关注一个特性。神经元就是图像处理中的滤波器,比如边缘检测专用的Sobel滤波器,即卷积层的每个滤波器都会有自己所关注一个图像特征,比如垂直边缘,水平边缘,颜色,纹理等等,这些所有神经元加起来就好比就是整张图像的特征提取器集合。 

下面这张动态图(推荐动态图,不支持脚本插入)展示了当filter扫过不同区域时,节点的链接方式,可以看出一组固定的权重和不同窗口内数据做内积。明显的:

  • 参数大大减小,数量与Filter大小相关;
  • Filter在图片上的移动就相当于相同的weight在输入向量不同的元素上的移动,这个就是weight共享 动态图的最后一帧则显示了所有连接 

图中显示的是一步一步的移动filter来扫描全图,一次移动多少叫做步长(stride)

tensorflow之卷积神经网络

有没有想过这样一个问题:卷积图像的大小会随着卷积操作而不断缩小?同时图像的左上角的元素只被一个输出所使用,所以在图像边缘的像素在输出中采用较少,也就意味着你丢掉了很多图像边缘的信息。为了解决这两个问题,就引入了填充(padding)操作,也就是在图像卷积操作之前,沿着图像边缘用0进行图像填充。对于3*3的过滤器,我们填充宽度为1时,就可以保证输出图像和输入图像一样大。 

对于一个tensorflow之卷积神经网络图像,卷积核尺寸为tensorflow之卷积神经网络,移动步长为tensorflow之卷积神经网络,padding大小为tensorflow之卷积神经网络,那么经过卷积后输出大小为tensorflow之卷积神经网络

2.3 激励层

激励层主要对卷积层的输出进行一个非线性映射,如下图所示。使用的激励函数一般为ReLu函数:

tensorflow之卷积神经网络

tensorflow之卷积神经网络

ReLU**函数会为输入图像中的每个负值返回 0,每个正值则返回同样的值,如下所示。

tensorflow之卷积神经网络

2.4 池化层

 池化层夹在连续的卷积层中间, 用于压缩数据和参数的量,减小过拟合。简单说就是采样,用于压缩图像。在实际应用中,池化根据下采样的方法,分为最大值下采样(Max-Pooling)与平均值下采样(Mean-Pooling),下图所示最大值采样。

tensorflow之卷积神经网络

2.5 全连接层

当抓取到足以用来识别图片的特征后,接下来的就是如何进行分类。 全连接层(也叫前馈层)就可以用来将最后的输出映射到线性可分空间。通常卷积网络的最后会将末端得到的长方体平摊(flatten)成一个长长的向量,并送入全连接层配合输出层进行分类。其实全连接层就是一个分类器(可以是softmax、BP等),他可以将特征进行分类,并通过反向传播将误差回传调整整个网络的权值。如下图所示。

tensorflow之卷积神经网络

 二、why is CNN?

用Deep Learning来做图片识别最简单的办法就是用一个全连接的神经网络做模型,然后训练和优化,如下图所示。

tensorflow之卷积神经网络

 假设图中的输入图片猫大小为100x100,转化为一个输入向量则有30000维(彩色图片RGB表示3个channel),假设第一层Hidden Layer有1000个neural,则第一层Hidden Layer的总参数为3千多万个,而实际上稍微高清点的图片远大于100x100,同时Hidden Layer的层数也比较多,所以用全连接的神经网络做模型最大的问题就参数数量太多,对参数训练来说太困难。

其次,相同的识别目标可能位于相同大小图片中的不同位置,如下图所示。全连接的神经网络将图片展开为向量会丢失空间信息,对于图像不变性的目标识别很糟糕。

tensorflow之卷积神经网络

 假如对图片做sub-sampling后,调整后图片要远小于整张图片的大小,而图片中识别目标不会变化,如下所示。这会给全连接的神经网络带来很大挑战。

tensorflow之卷积神经网络

CNN在处理以上问题,具有比全连接神经网络天然优势,这就是为什么我们选择CNN。

三、CNN model

1. LeNet

第一个成功的卷积神经网络应用。

2. AlexNet

2012 ILSVRC比赛远超第2名的CNN,类似LeNet,但更深更大。使用了层叠的卷积层(多层小卷积层叠加替换单大卷积层)来抓取特征(通常是一个卷积层马上一个max pooling层)。

3. ZF Net

2013 ILSVRC比赛冠军,增加了中间卷积层的尺寸,让第一层的stride和filter size更小。

4. GoogLeNet

2014 ILSVRC比赛冠军,减少parameters数量,最后一层用max pooling层代替了全连接层,更重要的是Inception-v4模块的使用。

5. VGGNet

2014 ILSVRC比赛中的模型,只使用3x3 卷积层和2x2 pooling层从头到尾堆叠,图像识别略差于GoogLeNet,但是在很多图像转化学习问题(比如object detection)上效果奇好。

6. ResNet

引入了跨层连接和batch normalization。

7. DenseNet

将跨层连接从头进行到尾。

四、CNN的常用框架

Caffe
  • 源于Berkeley的主流CV工具包,支持C++,python,matlab
  • Model Zoo中有大量预训练好的模型供使用
Torch
  • Facebook用的卷积神经网络工具包
  • 通过时域卷积的本地接口,使用非常直观
  • 定义新网络层简单
TensorFlow
  • Google的深度学习框架
  • TensorBoard可视化很方便
  • 数据和模型并行化好,速度快

五、 MNIST手写识别Demo

初识tensorflow已经介绍MNIST数据集和softmax分类,在这里引入CNN提高识别精度。

1. 卷积函数

tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)

参数说明:

  • data_format:表示输入的格式,有两种分别为:“NHWC”和“NCHW”,默认为“NHWC”
  • input:输入是一个4维格式的(图像)数据,数据的 shape 由 data_format 决定:当 data_format 为“NHWC”输入数据的shape表示为[batch, in_height, in_width, in_channels],分别表示训练时一个batch的图片数量、图片高度、 图片宽度、 图像通道数。当 data_format 为“NHWC”输入数据的shape表示为[batch, in_channels, in_height, in_width]
  • filter:卷积核是一个4维格式的数据:shape表示为:[height,width,in_channels, out_channels],分别表示卷积核的高、宽、深度(与输入的in_channels应相同)、输出 feature map的个数(即卷积核的个数)。
  • strides:表示步长:一个长度为4的一维列表,每个元素跟data_format互相对应,表示在data_format每一维上的移动步长。当输入的默认格式为:“NHWC”,则 strides = [batch , in_height , in_width, in_channels]。其中 batch 和 in_channels 要求一定为1,即只能在一个样本的一个通道上的特征图上进行移动,in_height , in_width表示卷积核在特征图的高度和宽度上移动的布长。
  • padding:表示填充方式:“SAME”表示采用填充的方式,简单地理解为以0填充边缘,当stride为1时,输入和输出的维度相同;“VALID”表示采用不填充的方式,多余地进行丢弃。

2.池化函数 

tf.nn.max_pool( value, ksize,strides,padding,data_format=’NHWC’,name=None) 
或者 
tf.nn.avg_pool(…)

参数说明:

  • value:表示池化的输入:一个4维格式的数据,数据的 shape 由 data_format 决定,默认情况下shape 为[batch, height, width, channels]
  • 其他参数与 tf.nn.cov2d 类型
  • ksize:表示池化窗口的大小:一个长度为4的一维列表,一般为[1, height, width, 1],因不想在batch和channels上做池化,则将其值设为1。

3. 完整代码


#!/usr/bin/env python
# load MNIST data
import input_data
mnist = input_data.read_data_sets("Mnist_data/", one_hot=True)

# start tensorflow interactiveSession
import tensorflow as tf
sess = tf.InteractiveSession()

# weight initialization
def weight_variable(shape):
	initial = tf.truncated_normal(shape, stddev=0.1)
	return tf.Variable(initial)

def bias_variable(shape):
	initial = tf.constant(0.1, shape = shape)
	return tf.Variable(initial)

# convolution
def conv2d(x, W):
	return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
# pooling
def max_pool_2x2(x):
	return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

# Create the model
# placeholder
x = tf.placeholder("float", [None, 784])
y_ = tf.placeholder("float", [None, 10])
# variables
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))

y = tf.nn.softmax(tf.matmul(x,W) + b)

# first convolutinal layer
w_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])

x_image = tf.reshape(x, [-1, 28, 28, 1])

h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

# second convolutional layer
w_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])

h_conv2 = tf.nn.relu(conv2d(h_pool1, w_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

# densely connected layer
w_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, w_fc1) + b_fc1)

# dropout
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

# readout layer
w_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])

y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, w_fc2) + b_fc2)

# train and evaluate the model
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
train_step = tf.train.GradientDescentOptimizer(1e-3).minimize(cross_entropy)
#train_step = tf.train.AdagradOptimizer(1e-5).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
sess.run(tf.global_variables_initializer())
for i in range(20000):
	batch = mnist.train.next_batch(50)
	if i%100 == 0:
		train_accuracy = accuracy.eval(feed_dict={x:batch[0], y_:batch[1], keep_prob:1.0})
		print("step %d, train accuracy %g" %(i, train_accuracy))
	train_step.run(feed_dict={x:batch[0], y_:batch[1], keep_prob:0.5})

4.运行结果

/opt/modules/anaconda3/envs/mnist/bin/python /home/lee/PycharmProjects/mnist/mnist_deep.py
Extracting Mnist_data/train-images-idx3-ubyte.gz
Extracting Mnist_data/train-labels-idx1-ubyte.gz
Extracting Mnist_data/t10k-images-idx3-ubyte.gz
Extracting Mnist_data/t10k-labels-idx1-ubyte.gz
step 0, train accuracy 0.06
step 100, train accuracy 0.9
step 200, train accuracy 1
step 300, train accuracy 0.9
step 400, train accuracy 0.98
step 500, train accuracy 0.96
step 600, train accuracy 1
step 700, train accuracy 0.94
step 800, train accuracy 1
step 900, train accuracy 1
step 1000, train accuracy 1
step 1100, train accuracy 0.96
step 1200, train accuracy 0.98
step 1300, train accuracy 1
step 1400, train accuracy 1
step 1500, train accuracy 1
step 1600, train accuracy 0.98
step 1700, train accuracy 0.94
step 1800, train accuracy 0.94
step 1900, train accuracy 1
step 2000, train accuracy 0.98
step 2100, train accuracy 0.98
step 2200, train accuracy 0.98
step 2300, train accuracy 1
step 2400, train accuracy 0.98
step 2500, train accuracy 1
step 2600, train accuracy 0.98
step 2700, train accuracy 1
step 2800, train accuracy 0.94
step 2900, train accuracy 1
step 3000, train accuracy 0.98
step 3100, train accuracy 1
step 3200, train accuracy 0.96
step 3300, train accuracy 0.96
step 3400, train accuracy 0.96
step 3500, train accuracy 0.98
step 3600, train accuracy 0.96
step 3700, train accuracy 1
step 3800, train accuracy 1
step 3900, train accuracy 0.98
step 4000, train accuracy 0.98
step 4100, train accuracy 0.98
step 4200, train accuracy 1
step 4300, train accuracy 1
step 4400, train accuracy 0.98
step 4500, train accuracy 0.98
step 4600, train accuracy 1
step 4700, train accuracy 0.98
step 4800, train accuracy 1
step 4900, train accuracy 0.96
step 5000, train accuracy 1
step 5100, train accuracy 0.98
step 5200, train accuracy 0.96
step 5300, train accuracy 0.98
step 5400, train accuracy 0.98
step 5500, train accuracy 1
step 5600, train accuracy 1
step 5700, train accuracy 1
step 5800, train accuracy 1
step 5900, train accuracy 1
step 6000, train accuracy 0.96
step 6100, train accuracy 0.98
step 6200, train accuracy 1
step 6300, train accuracy 1
step 6400, train accuracy 1
step 6500, train accuracy 1
step 6600, train accuracy 1
step 6700, train accuracy 0.98
step 6800, train accuracy 0.98
step 6900, train accuracy 1
step 7000, train accuracy 1
step 7100, train accuracy 1
step 7200, train accuracy 1
step 7300, train accuracy 1
step 7400, train accuracy 1
step 7500, train accuracy 1
step 7600, train accuracy 1
step 7700, train accuracy 0.98
step 7800, train accuracy 1
step 7900, train accuracy 1
step 8000, train accuracy 1
step 8100, train accuracy 1
step 8200, train accuracy 1
step 8300, train accuracy 1
step 8400, train accuracy 1
step 8500, train accuracy 1
step 8600, train accuracy 1
step 8700, train accuracy 1
step 8800, train accuracy 0.98
step 8900, train accuracy 1
step 9000, train accuracy 1
step 9100, train accuracy 1
step 9200, train accuracy 1
step 9300, train accuracy 1
step 9400, train accuracy 0.98
step 9500, train accuracy 0.98
step 9600, train accuracy 0.98
step 9700, train accuracy 1
step 9800, train accuracy 1
step 9900, train accuracy 1
step 10000, train accuracy 1
step 10100, train accuracy 1
step 10200, train accuracy 1
step 10300, train accuracy 0.98
step 10400, train accuracy 1
step 10500, train accuracy 1
step 10600, train accuracy 1
step 10700, train accuracy 1
step 10800, train accuracy 1
step 10900, train accuracy 1
step 11000, train accuracy 1
step 11100, train accuracy 1
step 11200, train accuracy 1
step 11300, train accuracy 1
step 11400, train accuracy 1
step 11500, train accuracy 1
step 11600, train accuracy 1
step 11700, train accuracy 1
step 11800, train accuracy 1
step 11900, train accuracy 1
step 12000, train accuracy 1
step 12100, train accuracy 1
step 12200, train accuracy 1
step 12300, train accuracy 1
step 12400, train accuracy 1
step 12500, train accuracy 1
step 12600, train accuracy 1
step 12700, train accuracy 0.96
step 12800, train accuracy 1
step 12900, train accuracy 1
step 13000, train accuracy 0.98
step 13100, train accuracy 1
step 13200, train accuracy 1
step 13300, train accuracy 1
step 13400, train accuracy 1
step 13500, train accuracy 1
step 13600, train accuracy 1
step 13700, train accuracy 1
step 13800, train accuracy 1
step 13900, train accuracy 1
step 14000, train accuracy 1
step 14100, train accuracy 1
step 14200, train accuracy 1
step 14300, train accuracy 1
step 14400, train accuracy 1
step 14500, train accuracy 0.98
step 14600, train accuracy 1
step 14700, train accuracy 1
step 14800, train accuracy 1
step 14900, train accuracy 1
step 15000, train accuracy 1
step 15100, train accuracy 1
step 15200, train accuracy 1
step 15300, train accuracy 1
step 15400, train accuracy 1
step 15500, train accuracy 1
step 15600, train accuracy 1
step 15700, train accuracy 0.98
step 15800, train accuracy 0.98
step 15900, train accuracy 1
step 16000, train accuracy 1
step 16100, train accuracy 1
step 16200, train accuracy 1
step 16300, train accuracy 1
step 16400, train accuracy 1
step 16500, train accuracy 0.98
step 16600, train accuracy 1
step 16700, train accuracy 1
step 16800, train accuracy 1
step 16900, train accuracy 1
step 17000, train accuracy 1
step 17100, train accuracy 1
step 17200, train accuracy 1
step 17300, train accuracy 1
step 17400, train accuracy 1
step 17500, train accuracy 1
step 17600, train accuracy 1
step 17700, train accuracy 1
step 17800, train accuracy 1
step 17900, train accuracy 1
step 18000, train accuracy 1
step 18100, train accuracy 1
step 18200, train accuracy 1
step 18300, train accuracy 0.96
step 18400, train accuracy 1
step 18500, train accuracy 1
step 18600, train accuracy 1
step 18700, train accuracy 1
step 18800, train accuracy 1
step 18900, train accuracy 1
step 19000, train accuracy 1
step 19100, train accuracy 1
step 19200, train accuracy 1
step 19300, train accuracy 1
step 19400, train accuracy 0.98
step 19500, train accuracy 1
step 19600, train accuracy 1
step 19700, train accuracy 1
step 19800, train accuracy 1
step 19900, train accuracy 1

参考资料

https://cs231n.github.io/convolutional-networks/

https://www.cnblogs.com/skyfsm/p/6790245.html

https://blog.csdn.net/cxmscb/article/details/71023576