从数学开始
先从字面意思开始吧。
何谓卷积:卷积是两个变量在某范围内相乘后求和的结果。如果卷积的变量是序列x(n)和h(n),则卷积的结果:
如果卷积的变量是函数x(t)和h(t),则卷积的计算变为:
我猜叫卷积神经网络大概是在构建神经网络过程中会用到卷积操作。
我懂你的特别
传统神经网络中,一般采取 全连接 的方式,下面就是这样一个4层神经网络,输入和第一个隐层的每个神经元都相连接。这样神经网络参数量巨大,很难训练。
而在CNN中采取 局部连接 和 权值共享 的方式来避免这个问题。
假设有一个有1000×1000的输入图像的神经网络,并且隐层有10^6个神经元。
- 那么采取 全连接 的方式,就需要1000×1000×10^6即10^12个权值参数。
- 如果采用 局部连接,将隐层神经元和输入图像eg.10×10的局部图像相连,那么需要权值:10×10×10^6即10^8个权值。
- 如果在采用局部连接的基础上,再进行 权值共享,即10^6个隐层神经元共享一组10×10的权值,那么只需要10×10个权值参数。在这种情况下,10×10就是卷积核的大小。
但是这样仅提取了图像的 一种特征,想要多提取几个特征,就需要 多个卷积核。不同的卷积核能够得到图像的不同映射下的特征,称之为Feature Map。
(哪里不会点哪里~(≧∀≦)ゞ送上卷积核)
卷积核:卷积时使用到的权用一个矩阵表示,该矩阵与使用的图像区域大小相同,其行、列都是奇数,是一个权矩阵。
CNN中两种网络层
- 卷积层:用于提取图像的各种特征。将卷积层在上一层输入层逐一 滑动窗口 得到,在滑动过程中将 卷积核中的参数 与 局部像素 对应相乘之和。通常还会加上偏置。
- 池化/采样层(pooling):对原始特征信号进行抽象,大幅度减少训练参数,减轻过拟合。通常有两种方式:
- Max-Pooling:将Pooling窗口最大值作为采样值;
- Mean-Pooling:Pooling窗口的平均值作为采样值。
示例:
从上图中我们可以看到有一个5×5的图像(绿色),一个3×3的卷积核(黄色),一个3×3的的特征图(右边)。
图像上面的黄色区域表示正在进行卷积操作。
即(1×1+1×0+1×1)+(0×0+1×1+1×0)+(0×1+0×0+1×1)=4
卷积核的滑动过程见下图:
再理解MINIST进阶代码
看这里构建神经网络代码的时候看懵了,然后就跑去了解卷积神经网络到底是什么,到这时候就大概能够看懂这些代码到底在干嘛,为什么要这么做,对于卷积神经网络的结构也有一个大致的了解。
# -*- coding: utf-8 -*-
"""
Created on Mon Mar 6 10:56:46 2017
@author: Administrator
"""
#minist存储训练、校验和测试数据集。
#并提供函数,用于在迭代中获得minibatch
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
import tensorflow as tf
#创建交互式会话
sess = tf.InteractiveSession()
#为输入图像和目标输出类创建节点
x = tf.placeholder("float", shape=[None, 784])
y_ = tf.placeholder("float", shape=[None, 10])
#模型参数:权重和偏置,初始化为零向量
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
#变量要在session中初始化后才能使用
sess.run(tf.initialize_all_variables())
#回归模型:softmax
y = tf.nn.softmax(tf.matmul(x,W) + b)
#损失函数:采用目标类别和预测类别之间的交叉熵
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
#用梯度下降训练模型:步长为0.01,目的是使cross_entropy最小化
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
#训练模型:迭代1000次,每次迭代加载50个训练样本
for i in range(1000):
batch = mnist.train.next_batch(50)
train_step.run(feed_dict={x: batch[0], y_: batch[1]})
#评估模型:检测预测是否与真实标签匹配
#tf.argmax能给出某个tensor对象在某一维上的其数据最大值所在的索引值
#correct_prediction是一个布尔数组
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
#将上面的布尔数组装换为预测准确率
#tf.cast()将correct_prediction里的数据转换为float类型
#eg:a = [1.8, 2.2] tf.cast(a, tf.int32) ==> [1, 2]
#tf.reduce_mean(x)取x的均值
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
#计算在测试机上的准确率
print (accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
#初始化权重
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)
#卷积和池化函数定义
#用2×2的窗口,采取最大池化方法
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')
#第一层卷积
#卷积核32@5×5
W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])
#使图像和计算层匹配
x_image = tf.reshape(x, [-1,28,28,1])
#卷积并使用ReLU激活函数
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
#池化
h_pool1 = max_pool_2x2(h_conv1)
#第二层卷积
#卷积核64@5×5
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)
#全连接层
W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
#将最后的pooling层的输出reshape为一个一维向量
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)
#输出层
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
#使用softmax得到各类别上概率
y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
#训练和评估模型
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
train_step = tf.train.AdamOptimizer(1e-4).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.initialize_all_variables())
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}))
参考资料
- TensorFlow中文社区-minist进阶
- TensorFlow学习笔记2
- 最主要的那个参考资料我搞丢了= =