卷积神经网络原理与实例

一、卷积神经网络是如何工作的?

参考链接https://www.zhihu.com/question/39022858/answer/203073911

参考链接https://www.cnblogs.com/charlotte77/p/7759802.html

1、卷积层

一个例子,现在有一个4*4的灰度图像,我们设计两个2*2的卷积核,步长为1,运用卷积核后图片变成了3*3的特征图。


再一个例子,假设我们有一个 6*6 的图像,我们定义一个3*3卷积核,用来从图像中提取一定的特征。权重矩阵与原图卷积,得到一个4*4的特征图。

到这里,我们对图片卷积有了一个大概的认识,卷积核也叫权重矩阵。

其实形象一点,卷积核可以看作一个从原始图像中提取特定信息的“过滤器”。每个卷积核与原图卷积都能得到一个特征图,每个卷积核都会给出不同的特征,比如说一个卷积核提取特定颜色,一个卷积核提取边缘信息。

当我们有多个卷积层的时候,初始层往往提取较多的一般特征,随着网络结构变得更深,卷积核提取的特征越来越复杂,并且越来越适用于眼前的问题。

还有一些特殊操作:步长(stride)和边界(padding)的概念

我们看一下卷积核步长为 2 时的情况:



你可以看见当我们增加步长值的时候,图像的规格持续变小。在输入图像四周填充 0 边界可以解决这个问题。我们也可以在高步长值的情况下在图像四周填加不只一层的 0 边界。

我们可以看见在我们给图像填加一层 0 边界后,图像的原始形状是如何被保持的。由于输出图像和输入图像是大小相同的,所以这被称为 same padding。

这就是 same padding(意味着我们仅考虑输入图像的有效像素)。中间的 4*4 像素是相同的。这里我们已经利用边界保留了更多信息,并且也已经保留了图像的原大小。

2、池化层

有时图像太大,我们需要减少训练参数的数量,它被要求在随后的卷积层之间周期性地引进池化层。池化的唯一目的是减少图像的空间大小。池化在每一个纵深维度上独自完成,因此图像的纵深保持不变。池化层的最常见形式是最大池化。

在这里,我们把步幅定为 2,池化尺寸也为 2。最大化执行也应用在每个卷机输出的深度尺寸中。正如你所看到的,最大池化操作后,4*4 卷积的输出变成了 2*2。

3、全连接层

在多层卷积和填充后,我们需要以类别的形式输出。卷积和池化层只会提取特征,并减少原始图像带来的参数。然而,为了生成最终的输出,我们需要应用全连接层来生成一个等于我们需要的类别数量的输出。

输出层具有类似分类交叉熵的损失函数,用于计算预测误差。一旦前向传播完成,反向传播就会开始更新权重与偏差,以减少误差和损失。

4、输出维度

有三个超参数可以控制输出卷的大小。

1. 卷积核数量-输出卷的深度与卷积核的数量成正比。

2. 步幅(Stride)-如果步幅是 1,那么我们处理图片的精细度就进入单像素级别了。更高的步幅意味着同时处理更多的像素,从而产生较小的输出量。

3. 零填充(zero padding)-这有助于我们保留输入图像的尺寸。如果添加了单零填充,则单步幅卷积核的运动会保持在原图尺寸。

我们可以应用一个简单的公式来计算输出尺寸。输出图像的空间尺寸可以计算为([W-F + 2P] / S)+1。在这里,W 是输入尺寸,F 是过滤器的尺寸,P 是填充数量,S 是步幅数字。假如我们有一张 32*32*3 的输入图像,我们使用 10 个尺寸为 3*3*3 的过滤器,单步幅和零填充。那么 W=32,F=3,P=0,S=1。输出深度等于应用的卷积核的数量,即 10,输出尺寸大小为 ([32-3+0]/1)+1 = 30。因此输出尺寸是 30*30*10。

5、总结

CNN 由不同的卷积层和池化层组成。让我们看看整个网络是什么样子:



  • 我们将输入图像传递到第一个卷积层中,卷积后以激活图形式输出。图片在卷积层中过滤后的特征会被输出,并传递下去。
  • 每个卷积核都会给出不同的特征,以帮助进行正确的类预测。因为我们需要保证图像大小的一致,所以我们使用同样的填充(零填充),否则填充会被使用,因为它可以帮助减少特征的数量。
  • 随后加入池化层进一步减少参数的数量。
  • 在预测最终提出前,数据会经过多个卷积和池化层的处理。卷积层会帮助提取特征,越深的卷积神经网络会提取越具体的特征,越浅的网络提取越浅显的特征。
  • 如前所述,CNN 中的输出层是全连接层,其中来自其他层的输入在这里被平化和发送,以便将输出转换为网络所需的参数。
  • 随后输出层会产生输出,这些信息会互相比较排除错误。损失函数是全连接输出层计算的均方根损失。随后我们会计算梯度错误。
  • 错误会进行反向传播,以不断改进卷积核(权重)和偏差值。
  • 一个训练周期由单次正向和反向传递完成。

二、在mnist代码中看CNN

参考博文http://blog.csdn.net/xukaiwen_2016/article/details/70880694

1、读取数据

import tensorflow as tf  
from tensorflow.examples.tutorials.mnist import input_data  
mnist = input_data.read_data_sets('input_data', one_hot=True)  

one_hot表示用非零即1的数组保存图片表示的数值。比如一个图片上写的是0,内存中不是直接存一个0,而是存一个数组[1,0,0,0,0,0,0,0,0,0]。一个图片上面写的是1,那么保存的就是[0,1,0,0,0,0,0,0,0,0]。

2、函数声明部分

# 生成结构为shape的权重矩阵,或者看作一个滤波器,正态分布,标准差为0.1,默认最大为1,最小为-1,均值为0  。

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

# 这是偏置函数,创建一个结构为shape的矩阵/数组,声明其行列,初始化所有值为0.1 。

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

# 这是卷积(遍历相乘 )操作,卷积遍历各方向步数为1,SAME:边缘外自动补0。

def conv2d(x, W):  
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')  

# 最大池化,池化层采用kernel大小为2*2,步数也为2,周围补0,取最大值。

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

3、定义输入输出占位符

x :输入。None表示输入图片数量不定,图片尺寸为28*28=784。

y_:标签。一共0-9十个类别,对应输出分类结果。

x_image :把输入reshape成28*28*1的灰度图片,-1表示图片数量不定。

x = tf.placeholder(tf.float32, [None, 784])  
y_ = tf.placeholder(tf.float32, [None, 10])  
x_image = tf.reshape(x, [-1, 28, 28, 1]) 

4、搭建网络,定义算法公式

# 第一层卷积+最大池化

  [5, 5, 1, 32]:四维张量, 5,5是卷积核尺寸大小,1是图像通道数,32是卷积核的数目。

  将权重变量与原始图片进行卷积、偏置、激活,得到 第一层卷积输出h_conv1:28x28x32  (尺寸28*28,深度32)

  将第一层输出下采样,得到 h_pool1:14x14x32

  W_conv1 = weight_variable([5, 5, 1, 32])  
  b_conv1 = bias_variable([32]) 
  h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)  
  h_pool1 = max_pool_2x2(h_conv1)  

# 第二层卷积+最大池化

  5*5的卷积核,32个图像通道,64个卷积核。

  卷积结果h_conv2 :14x14x64

  下采样,得到h_pool2 :7x7x64

  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) 

# 全连接层

  [7 * 7 * 64, 1024]:二维张量,7*7*64的卷积核,也可以认为是只有一行7*7*64个数据的卷积,第二个参数代表卷积核个数共  1024个  。

  h_pool2图像7x7,共有64张,将其reshape为行向量[-1, 7*7*64] h_pool2_flat

  卷积操作,结果是h_fc1: 1*1*1024,行乘列等于1*1矩阵,matmul实现最基本的矩阵相乘,不同于conv2d的遍历相乘,自动 认为是前行后列 。

  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操作

  减少过拟合,其实就是降低上一层某些输入的权重scale,甚至置为0,升高某些输入的权值,甚至置为2,防止评测曲线出现震荡,个人觉得样本较少时很必要  。
  使用占位符,由dropout自动确定scale,也可以自定义,比如0.5,根据tensorflow文档可知,程序中真实使用的值为1/0.5=2,也就是某些输入乘以2,同时某些输入乘以0  。

  keep_prob = tf.placeholder(tf.float32)  
  h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

# 输出操作

 [1024, 10]:二维张量,1*1024矩阵卷积,共10个卷积,对应我们开始的y_长度为10 。

 最后的分类y_conv ,结果为1*1*10 ,softmax和sigmoid都是基于logistic分类算法,一个是多分类一个是二分类  。

  W_fc2 = weight_variable([1024, 10])  
  b_fc2 = bias_variable([10])  
  y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2 

5、定义loss

用交叉熵作为loss函数:

y_是标签,y_conv是预测类别。

在train时,用Adam优化器进行优化,使cross_entropy最小。

cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv))  
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) 

6、开始训练及评测

correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))  
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))  
  
with tf.Session() as sess:  
  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, training accuracy %g' % (i, train_accuracy))  
    train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})  
  
  print('test accuracy %g' % accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))  






  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值