1 from tensorflow.examples.tutorials.mnist importinput_data2 mnist = input_data.read_data_sets('MNIST_data', one_hot=True)3 #下载下来的数据集被分成两部分:60000行的训练数据集(mnist.train)和10000行的测试数据集(mnist.test)。
4 #在机器学习模型设计时必须有一个单独的测试数据集不用于训练而是用来评估这个模型的性能,从而更加容易把设计的模型推广到其他数据集上(泛化)。
5 #在MNIST训练数据集中,mnist.train.images 是一个形状为 [60000, 784] 的张量,60000个数,每个数784个像素点
6 #mnist.train.labels 是一个 [60000, 10] 的数字矩阵。 60000个数,10中9个0一个1,表示这个数是几
7 importtensorflow as tf8
9
10 defweight_variable(shape):11 initial = tf.truncated_normal(shape, stddev=0.1)12 returntf.Variable(initial)13
14 defbias_variable(shape):15 initial = tf.constant(0.1, shape=shape)16 returntf.Variable(initial)17
18 defconv2d(x, W):19 return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')20
21 defmax_pool_2x2(x):22 return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],23 strides=[1, 2, 2, 1], padding='SAME')24
25
26 #Create the model
27 #placeholder
28 x = tf.placeholder("float", [None, 784])#mnist.train.images 图片
29 #x不是一个特定的值,而是一个占位符placeholder,我们在TensorFlow运行计算时输入这个值。
30 #我们希望能够输入任意数量的MNIST图像,每一张图展平成784维的向量。我们用2维的浮点数张量来表示这些图,
31 #这个张量的形状是[None,784 ]。(这里的None表示此张量的第一个维度可以是任何长度
32
33
34 #交叉熵,其用来衡量在给定的真实分布下,使用非真实分布所指定的策略消除系统的不确定性所需要付出的努力的大小。
35 #交叉熵可在神经网络(机器学习)中作为损失函数,p表示真实标记的分布,q则为训练后的模型的预测标记分布,交叉熵损失函数可以衡量p与q的相似性。
36 #交叉熵作为损失函数还有一个好处是使用sigmoid函数在梯度下降时能避免均方误差损失函数学习速率降低的问题,因为学习速率可以被输出的误差所控制。
37 #交叉熵越小越好,最低的交叉熵也就是使用了真实分布所计算出来的信息熵
38
39 #为了计算交叉熵,我们首先需要添加一个新的占位符用于输入正确值:
40 y_ = tf.placeholder("float", [None, 10])#mnist.train.labels 标签
41
42 ##first
43 W_conv1 = weight_variable([5, 5, 1, 32])44 b_conv1 = bias_variable([32])45
46
47 x_image = tf.reshape(x, [-1,28,28,1])48
49 h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) +b_conv1)50 h_pool1 =max_pool_2x2(h_conv1)51
52 #second
53 W_conv2 = weight_variable([5, 5, 32, 64])54 b_conv2 = bias_variable([64])55
56 h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) +b_conv2)57 h_pool2 =max_pool_2x2(h_conv2)58
59
60 #61
62 W_fc1 = weight_variable([7 * 7 * 64, 1024])63 b_fc1 = bias_variable([1024])64
65 h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])66 h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) +b_fc1)67
68
69
70 #dropout
71
72 keep_prob = tf.placeholder("float")73 h_fc1_drop =tf.nn.dropout(h_fc1, keep_prob)74
75
76 #softmax 以下三行是核心代码
77 #Variable代表一个可修改的张量,存在在TensorFlow的用于描述交互性操作的图中。它们可以用于计算输入值,也可以在计算中被修改。
78 #用来表示权重值和偏置量
79 W_fc2 = weight_variable([1024, 10])80 b_fc2 = bias_variable([10])81 #注意,W的维度是[784,10],因为我们想要用784维的图片向量乘以它以得到一个10维的证据值向量,每一位对应不同数字类。
82 #b的形状是[10],所以我们可以直接把它加到输出上面。
83
84
85 y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) +b_fc2)86 #用tf.matmul(X,W)表示x乘以W
87 #这里h_fc1_drop是一个2维张量拥有多个输入。然后再加上b,把和输入到tf.nn.softmax函数里面。
88 #函数softmax(wx+b),最后得到输入的这个数是0~9的概率是多少(都是非负的,且概率和为1)
89
90
91
92
93 #计算交叉熵:
94 cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))95 #用 tf.log 计算 y 的每个元素的对数。接下来,我们把 y_ 的每一个元素和 tf.log(y) 的对应元素相乘。
96 #最后,用 tf.reduce_sum 计算张量的所有元素的总和。(注意,这里的交叉熵不仅仅用来衡量单一的一对预测和真实值,
97 #而是所有100幅图片的交叉熵的总和。对于100个数据点的预测表现比单一数据点的表现能更好地描述我们的模型的性能。
98
99 train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)100 correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))101 accuracy = tf.reduce_mean(tf.cast(correct_prediction, "double"))102
103
104 #在运行计算之前,我们需要添加一个操作来初始化我们创建的变量:
105 init =tf.initialize_all_variables()106 sess =tf.InteractiveSession()107 sess.run(init)108
109
110 #然后开始训练模型,这里我们让模型循环训练20000次!
111 for i in range(20000):112 batch = mnist.train.next_batch(50)113 if i%100 ==0:114 train_accuracy = accuracy.eval(feed_dict={115 x:batch[0], y_: batch[1], keep_prob: 1.0})116 print ("step %d, training accuracy %f"%(i, train_accuracy))117 train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})118 #________________________________________________________________________________训练完成
119 print ("test accuracy %f"%accuracy.eval(feed_dict={120 x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}