@Pigmon
2017-04-14T23:45:45.000000Z
字数 4434
阅读 905
教案
'''
A Convolutional Network implementation example using TensorFlow library.
This example is using the MNIST database of handwritten digits
(http://yann.lecun.com/exdb/mnist/)
Author: Aymeric Damien
Project: https://github.com/aymericdamien/TensorFlow-Examples/
'''
from __future__ import print_function
import tensorflow as tf
# Import MNIST data
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)
# Parameters
# 参数
learning_rate = 0.001 # 学习率
training_iters = 200000 # 训练次数
batch_size = 128 # 批处理大小,即每次输入多少个数据进入网络
display_step = 10 # 每隔多少步输出一次 log
# Network Parameters
# 卷积神经网络的参数
n_input = 784 # MNIST data input (img shape: 28*28)
# 输入特征维度,因为MNIST数据集是28x28的图像,所以维度是28x28=784
n_classes = 10 # MNIST total classes (0-9 digits)
# 分类数,因为是区分0-9的数字,所以类别有10个
dropout = 0.75 # Dropout, probability to keep units
# 优化网络的参数,代表每个神经元每次计算有 25% 的几率被忽略
# tf Graph input
# 输入数据 x: 特征, y: 人工标记类别
x = tf.placeholder(tf.float32, [None, n_input])
y = tf.placeholder(tf.float32, [None, n_classes])
keep_prob = tf.placeholder(tf.float32) #dropout (keep probability)
# Create some wrappers for simplicity
# 建立一个简化的建立卷积层的函数
# x: 输入特征值
# W:权重
# b: bias
# strides: 卷积核移动步长
def conv2d(x, W, b, strides=1):
# Conv2D wrapper, with bias and relu activation
x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')
x = tf.nn.bias_add(x, b)
return tf.nn.relu(x)
# 定义一个简化的建立下采样层的函数
# x: 被下采样的数据,4-D tensor [块大小,长,宽,通道数(灰度就是1,rgb就是3)]
# k:下采样核的尺寸,2 代表 2x2
def maxpool2d(x, k=2):
# MaxPool2D wrapper
return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1],
padding='SAME')
# Create model
# 建立卷积神经网络模型
def conv_net(x, weights, biases, dropout):
# Reshape input picture
# reshape 输入的图像,-1 代表让 tf 自动计算,这里是图像的数量
x = tf.reshape(x, shape=[-1, 28, 28, 1])
# ----------卷积网络----------
# Convolution Layer
# 加一个卷积层
conv1 = conv2d(x, weights['wc1'], biases['bc1'])
# Max Pooling (down-sampling)
# 加一个下采样层
conv1 = maxpool2d(conv1, k=2)
# Convolution Layer
# 再加一个卷积层
conv2 = conv2d(conv1, weights['wc2'], biases['bc2'])
# Max Pooling (down-sampling)
# 再加一个下采样层
conv2 = maxpool2d(conv2, k=2)
# ----------全连接层----------
# Fully connected layer
# 建立全连接层
# Reshape conv2 output to fit fully connected layer input
# 把上一层输出的数据 reshape 到适应神经网络的输入
fc1 = tf.reshape(conv2, [-1, weights['wd1'].get_shape().as_list()[0]])
# wx + b
fc1 = tf.add(tf.matmul(fc1, weights['wd1']), biases['bd1'])
# 建立全连接层,激活函数为 relu
fc1 = tf.nn.relu(fc1)
# Apply Dropout
# 丢弃参数
fc1 = tf.nn.dropout(fc1, dropout)
# ----------输出层----------
# Output, class prediction
# 输出层,用于分类。wx + b
out = tf.add(tf.matmul(fc1, weights['out']), biases['out'])
return out
# Store layers weight & bias
# 存储所有权重的 dict
weights = {
# 5x5 conv, 1 input, 32 outputs
# 第一个卷积层的权重,卷积核的尺寸是 5×5,1个输入,输出定为32
'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])),
# 5x5 conv, 32 inputs, 64 outputs
# 上一层的32个输出变成这一层的输入,这层输出定为 64
'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])),
# fully connected, 7*7*64 inputs, 1024 outputs
# 全连接层权重,因为28×28的图像经过了2次下采样,每次小一半,
# 所以现在是 7×7,全连接层是普通的神经网络,所以数据要拉平
# 成一维数组,即数量为 7×7×64,64为上一层的输出数量
# 而这一层的输出定为 1024
'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])),
# 1024 inputs, 10 outputs (class prediction)
# 输出层,上一层的 1024 个输入
# 输出类别为10个数字的概率,所以为 10
'out': tf.Variable(tf.random_normal([1024, n_classes]))
}
# 存储所有 bias 的 dict
# 数量跟每层定好的输出数量一致
biases = {
'bc1': tf.Variable(tf.random_normal([32])),
'bc2': tf.Variable(tf.random_normal([64])),
'bd1': tf.Variable(tf.random_normal([1024])),
'out': tf.Variable(tf.random_normal([n_classes]))
}
# Construct model
# 调用上面的自定义函数来构建卷积神经网络
pred = conv_net(x, weights, biases, keep_prob)
# Define loss and optimizer
# 定义损失函数和训练函数
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
# Evaluate model
# 定义正确率评估方式
correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
# Initializing the variables
# 初始化变量,所有有变量的程序都要有这句
init = tf.global_variables_initializer()
# Launch the graph
# 启动图 (会话)
with tf.Session() as sess:
sess.run(init)
step = 1
# Keep training until reach max iterations
# 循环到达到最大训练次数
while step * batch_size < training_iters:
# 从训练集获取 batch_size 个数据
batch_x, batch_y = mnist.train.next_batch(batch_size)
# Run optimization op (backprop)
# 训练
sess.run(optimizer, feed_dict={x: batch_x, y: batch_y,
keep_prob: dropout})
# 每 10 步输出一次 log
if step % display_step == 0:
# Calculate batch loss and accuracy
# 计算损失函数值和正确率
loss, acc = sess.run([cost, accuracy], feed_dict={x: batch_x,
y: batch_y,
keep_prob: 1.})
print("Iter " + str(step*batch_size) + ", Minibatch Loss= " + \
"{:.6f}".format(loss) + ", Training Accuracy= " + \
"{:.5f}".format(acc))
step += 1
print("Optimization Finished!")
# Calculate accuracy for 256 mnist test images
# 计算测试数据的正确率
print("Testing Accuracy:", \
sess.run(accuracy, feed_dict={x: mnist.test.images[:256],
y: mnist.test.labels[:256],
keep_prob: 1.}))