机器学习与Tensorflow(4)——卷积神经网络与tensorflow实现

1.标准卷积神经网络

标准的卷积神经网络由输入层、卷积层(convolutional layer)、下采样层(downsampling layer)、全链接层(fully—connected layer)和输出层构成。git

  • 卷积层也称为检测层
  • 下采样层也称为池化层(pooling layer)

2.卷积神经网络的优点:

第一个特色和优点就是:局部感知网络

  • 在传统神经网络中每一个神经元都要与图片上每一个像素相链接,
  • 这样的话就会形成权重的数量巨大形成网络难以训练。
  • 而在含有卷积层的神经网络中每一个神经元的权重个数都时卷积核的大小,
  • 这样就至关于神经元只与对应图片部分的像素相链接。
  • 这样就极大的减小了权重的数量。同时咱们能够设置卷积操做的步长,
  • 可是步长的设置并没有定值须要使用者本身尝试


第二个特色和优点就是:参数共享ide

  • 卷积核的权重是通过学习获得的,而且在卷积过程当中卷积核的权重是不会改变的,这就是参数共享的思想。
  • 经过一个卷积核的操做提取了原图的不一样位置的一样特征。
  • 简单来讲就是在一幅图片中的不一样位置的相同目标,它们的特征是基本相同的

第三个特色和优点就是:多卷积核函数

  • 咱们用一个卷积核操做只能获得一部分特征可能获取不到所有特征,
  • 因此为了可以获得图像更多的特征信息咱们引入了多核卷积。
  • 用多个卷积核来学习图像更多的不一样的特征(每一个卷积核学习到不一样的权重)。
  • 主要注意的是在多核卷积的过程当中每一层的多个卷积核的大小应该是相同的。


3.关于卷积

先了解卷积运算:内卷积和外卷积(具体以下图)学习

内卷积:优化

外卷积:spa

 

卷积层的做用:code

  • 卷积层的每个卷积滤波器做用于整个感觉野中,对输入图像进行卷积,
  • 卷积的结果构成了输入图像的特征图,从而通过卷积层后就提取出了图像的局部特征。
  • 因此卷积层的主要做用就是能够利用不一样的卷积核(也叫滤波器)来提取图像不一样的特征。
  • 它是识别图像最核心的部分。

 

4.关于池化

池化方式:(最大池化、平均池化)orm

  • 池化层的具体操做与卷基层的操做基本相同,只不过池化层的卷积核为只取对应位置的最大值或平均值(最大池化、平均池化),
  • 而且不会随着反向传播发生变化。通常池化层的filter取2*2,最大取3*3,stride取2,特征信息压缩为原来的1/4。

最大池化方式(每一个小块中的最大值):blog

 

平均池化方式(每一个小块中的平均值):

 


池化层的做用:

  • 池化层可对提取到的特征信息进行降维,
  • 一方面使特征图变小,简化网络计算复杂度并在必定程度上避免过拟合的出现;一方面进行特征压缩,提取主要特征。
  • 最大池采样在计算机视觉中的价值体如今两个方面:(1)、它减少了来自上层隐藏层的计算复杂度;(2)、这些池化单元具备平移不变性,即便图像有小的位移,提取到的特征依然会保持不变。因为加强了对位移的鲁棒性,这样能够忽略目标的倾斜、旋转之类的相对位置的变化,以此提升精度,最大池采样方法是一个高效的下降数据维度的采样方法。
  • 须要注意的是:这里的pooling操做是特征图缩小,有可能影响网络的准确度。


5.Tensorflow实现

def conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None,data_format=None, name=None)

除去name参数用以指定该操做的name,与方法有关的一共五个参数:

第一个参数input:

  • 指须要作卷积的输入图像,它要求是一个Tensor,具备[batch, in_height, in_width, in_channels]这样的shape,
  • 具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数],
  • 注意这是一个4维的Tensor,要求类型为float32和float64其中之一

第二个参数filter:

  • 至关于CNN中的卷积核,它要求是一个Tensor,具备[filter_height, filter_width, in_channels, out_channels]这样的shape,
  • 具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],
  • 要求类型与参数input相同,
  • 有一个地方须要注意,第三维in_channels,就是参数input的第四维

第三个参数strides:

  • 卷积时在图像每一维的步长,这是一个一维的向量,长度4
  • strides[0] = strides[3] = 1
  • strides[1]表明x方向的步长,strides[2]表明y方向的步长


第四个参数padding:

  • string类型的量,只能是"SAME","VALID"其中之一,这个值决定了不一样的卷积方式
  • 对于卷积操做:
    • SAME PADDING表明给平面外部补0,卷积窗口采样后获得一个跟原来平面大小相同的平面
    • VALID PADDING表明不会超出平面外部,卷积窗口采样后获得比原来平面小的平面。
  • 对于池化操做:
    • SAME PADDING表明可能会给平面外部补0
    • VALID PADDING表明不会超出平面外部

举例理解:
假若有一个28*28的平面,用2*2而且步长为2的窗口对其进行pooling操做

使用SAME PADDING的方式,获得14*14的平面
使用VALID PADDING的方式,获得14*14的平面


假若有一个2*3的平面,用2*2而且步长为2的窗口对其进行pooling操做

使用SAME PADDING的方式,获得1*2的平面
使用VALID PADDING的方式,获得1*1的平面

 



第五个参数:use_cudnn_on_gpu:bool类型,是否使用cudnn加速,默认为true

结果返回一个Tensor,这个输出,就是咱们常说的feature map

 

6.卷积神经网络对MNIST手写数据集识别优化

实现代码:

  1 import os
  2 os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
  3 import tensorflow as tf
  4 from tensorflow.examples.tutorials.mnist import input_data
  5 
  6 #载入数据集
  7 mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
  8 
  9 #每一个批次的大小
 10 batch_size = 100
 11 
 12 #计算一个有多少个批次
 13 n_batch = mnist.train.num_examples // batch_size
 14 
 15 #初始化权值
 16 def weight_variable(shape):
 17     initial = tf.truncated_normal(shape, stddev=0.1)#生成一个截断的正态分布
 18     return tf.Variable(initial)
 19 
 20 #初始化偏置
 21 def bias_variable(shape):
 22     initial = tf.constant(0.1, shape=shape)
 23     return tf.Variable(initial)
 24 
 25 #卷积层
 26 def conv2d(x,W):
 27     # x input tensor of shape `[batch, in_height, in_width, in_channels]`
 28     # W filter / kernel tensor of shape [filter_height, filter_width, in_channels, out_channels]
 29     # `strides[0] = strides[3] = 1`. strides[1]表明x方向的步长,strides[2]表明y方向的步长
 30     # padding: A `string` from: `"SAME", "VALID"`
 31     return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
 32 
 33 #池化层
 34 def max_pool_2x2(x):
 35     # ksize [1,x,y,1]
 36     return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
 37 
 38 #定义两个placeholder
 39 x = tf.placeholder(tf.float32, [None, 784]) #28*28
 40 y = tf.placeholder(tf.float32, [None,10])
 41 
 42 #改变x的格式转为4D的向量[batch,in_height,in_width,in_channels]
 43 x_image = tf.reshape(x, [-1, 28, 28, 1])
 44 
 45 #初始化第一个卷积层的权值和偏置
 46 W_conv1 = weight_variable([5, 5, 1, 32])  #5*5的采样窗口,32个卷积核从1个平面抽取特征
 47 b_conv1 = bias_variable([32]) #每个卷积核一个偏置值
 48 
 49 #把x_image和权值向量进行卷积,再加上偏置值,而后应用于relu激活函数
 50 h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
 51 h_pool1 = max_pool_2x2(h_conv1)
 52 
 53 #初始第二个卷积层的权值和偏置值
 54 W_conv2 = weight_variable([5, 5, 32, 64])#5*5的采样窗口,64个卷积核从32个平面抽取特征
 55 b_conv2 = bias_variable([64])
 56 
 57 #把h_pool1和权值向量进行卷积,再加上偏置值,而后应用于relu激活函数
 58 h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
 59 h_pool2 = max_pool_2x2(h_conv2)
 60 
 61 #28*28的图片第一次卷积后仍是28*28,第一次池化后变成14*14
 62 #第二次卷积为14*14,第二次池化后变成可7*7
 63 #通过上面的操做后获得64张7*7的平面
 64 
 65 #初始化第一个全链接层的权值
 66 W_fc1 = weight_variable([7*7*64, 1024])#上一层有7*7*64个神经元,全链接层有1024个神经元
 67 b_fc1 = bias_variable([1024])#1024个节点
 68 
 69 #把池化层2的输出扁平化为1维
 70 h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
 71 
 72 #求第一个全链接层的输出
 73 h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
 74 
 75 #keep_prob用来表示神经元的输出几率
 76 keep_prob = tf.placeholder(tf.float32)
 77 h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
 78 
 79 #初始化第二个全链接层
 80 W_fc2 = weight_variable([1024, 10])
 81 b_fc2 = bias_variable([10])
 82 
 83 #计算输出
 84 prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
 85 
 86 #交叉熵代价函数
 87 cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=prediction))
 88 
 89 #使用AdmaOptimizer进行优化
 90 train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
 91 
 92 #结果存放在一个布尔列表中
 93 correct_prediction = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1))
 94 
 95 #求准确率
 96 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
 97 
 98 #变量初始化
 99 init = tf.global_variables_initializer()
100 
101 with tf.Session() as sess:
102     sess.run(init)
103     for epoch in range(21):
104         for batch in range(n_batch):
105             batch_xs, batch_ys = mnist.train.next_batch(batch_size)
106             sess.run(train_step, feed_dict={x: batch_xs, y: batch_ys, keep_prob: 0.7})
107         acc = sess.run(accuracy, feed_dict={x: mnist.test.images[:5000], y: mnist.test.labels[:5000], keep_prob: 1.0})
108         print('Iter : ' + str(epoch) + ',Testing Accuracy = ' + str(acc))
View Code

#写在后面:

很久没有作学习总结

最近一直在给老师处理轴承数据,而后用深度学习作分类

天天就是忙忙忙

而后还要去健身

昨天是本身的生日,吃了一个超级可爱的小蛋糕

感受本身还像个孩子

永远18岁

最近烦心事有点多

不少时候没必要向别人解释本身

懂你的人天然而然就会懂

不懂得人解释也不懂

加油吧!小伙郭

加油,每个为了生活而努力向前的人!

相关文章
相关标签/搜索