import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets('MNIST_data', one_hot=True) sess = tf.Session() # 定义 tensorflow 特有的占位符 # xs 定义为 【行数未定,但784列】; # 原理在于图片是28*28=784 即把二维形式的图片,用一维向量表示,None 表示图片的个数,即一行代表一个图片 xs = tf.placeholder(dtype=tf.float32, shape=[None, 784]) # xs 定义为 【行数未定,但10列】 # 10 列表示0到9 这几个数,None 表示图片的个数,即每行代表一个图片对应的label ys = tf.placeholder(dtype=tf.float32, shape=[None, 10]) keep_prob = tf.placeholder(dtype=tf.float32) # 定义计算预测准确度的函数 def compute_accuracy(v_xs, v_ys): global prediction '''本函数由两个sess.run()构成''' """该部分计算预测值""" y_re = sess.run(prediction, feed_dict={xs: v_xs, keep_prob: 1}) """该部分计算预测的准确度""" # tf.argmax() 返回最大值的索引,axis =1 表示行方向的 # 因为 y_pre 是预测值,v_ys 是实际值 所以通过argmax 返回行方向上的最大值, # 使用tf.equal 比较同一位置的值是否相等 返回的是[True,True,False,True ...] correct_prediction = tf.equal(tf.argmax(input=y_re, axis=1), tf.argmax(input=v_ys, axis=1)) # 使用tf.cast将tf.equal的返回值转为float [1.0,1.0,0.0,1.0 ...] # 再使用tf.reduce_mean 计算平均值 accuracy = tf.reduce_mean(tf.cast(x=correct_prediction, dtype=tf.float32)) result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys, keep_prob: 1}) return result # 定义一个初始化权值的函数 def weight_variable(shape): # 截尾正太分布 的随机数 stddev 标准差 initial = tf.truncated_normal(shape=shape, stddev=0.1) return tf.Variable(initial) # 定义一个初始化偏置量的函数 def bias_variable(shape): # 值为0.1 的常量 initial = tf.constant(value=0.1, shape=shape) return tf.Variable(initial) # 定义卷积层函数 def conv2d(input, Weight): # input 为输入的数据 # Weight 为权值, filter # strides 为步长,四个值的意思分别是:样本的步长,1 表示每个样本都作为输入 # 高度的步长,1 表示每次在高度上移动一个单位 # 宽度的步长,1 表示每次在宽度上移动一个单位 # 通道的步长,或者说是厚度上的步长,1,表示每次移动一个 # padding 有两种取值 SAME VALID,使用SAME会对输入的数据进行0补,也就是移动的步数不会丢失 # 取VALID,则不进行补0,可能会导致移动步数丢失 # 如 长度为10的,用一个长度为3的在上面每次移动一个 # 使用SAME,因为需要补0,所以最后需要移动10次 # 使用VALID,则移动8次就无法再移动【出界了】 return tf.nn.conv2d(input=input, filter=Weight, strides=[1, 1, 1, 1], padding='SAME') # 定义池化层函数 def max_pool_2x2(input): # 池化层的目的是在降低数据量,就是用一颗数据来表示一整块数据 # 这里使用最大值池化 # ksize 表示池化范围的大小;四个参数的意义与上述相同 # strides 步长 return tf.nn.max_pool(value=input, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') '''''' # 将数据xs reshape 成个数未定,长宽28*28,厚度 为1 的数据类型 x_input = tf.reshape(tensor=xs, shape=[-1, 28, 28, 1]) """第一层卷积计算 start""" '''先初始化权值和偏置参数''' # shape = [5,5,1,32] 的意思是 filter 的大小是5*5的,用于输入厚度为1,输出厚度为32 W_conv1 = weight_variable(shape=[5, 5, 1, 32]) b_conv1 = bias_variable([32]) '''真正的计算''' # 输入 x_input 28*28*1 # 输出的 h_conv1 28*28*32 # 使用了relu 激活函数;激活函数有很多种,其作用是为了去线性化 h_conv1 = tf.nn.relu(conv2d(x_input, W_conv1) + b_conv1) # 池化层 # 使用最大值池化 输入为28*28*32 # 输出为14*14*32 池化层的目的就是为了缩小特征的(个人理解) h_pool1 = max_pool_2x2(h_conv1) """第一层卷积计算 end""" """第二层卷积计算 start""" # 因为第二层卷积的输入为第一层的输出,14*14*32 # 因此 权值为5*5 输入为32厚度,输出为64 厚度 W_conv2 = weight_variable(shape=[5, 5, 32, 64]) b_conv2 = bias_variable(shape=[64]) # 输入为14*14*32 # 输出为 14*14*64 h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) # 输出为 7*7*64 h_pool2 = max_pool_2x2(h_conv2) """第二层卷积计算 end""" """全连接层1 start""" # 7*7*64 是要输入的数数据 # 1024 是神经元的个数 # 也就是经过上次池化层最后的结果为7*7*64 的图片,与1024个神经元的全连接 需要的权值矩阵,其权值个数为矩阵中元素的个数 W_fc1 = weight_variable([7 * 7 * 64, 1024]) # 每个神经元需要一个偏置 b_fc1 = bias_variable([1024]) # reshape 未知行数,每行代表一个图片全部的特征,7*7*64 h_pool2_flat = tf.reshape(tensor=h_pool2, shape=[-1, 7 * 7 * 64]) # 输入 n*(7*7*64) (7*7*64)*1024 # 输出 n*1024 h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1) # 防止过拟合的dropout方法 h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob) """全连接层2 start""" W_fc2 = weight_variable(shape=[1024, 10]) b_fc2 = bias_variable([10]) # matmul 输入:n*1024 2014*10 # 输出:n*10 # softmax 的输入为:n*10 # 输出为: prediction = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2) """全连接层2 end""" ''' 上述已将网络搭建完成 但是尚不能进行持续性的学习 原因:学习需要有一个学习的目标,在机器学习中也需要刻画一个目标 常用的刻画方式就是:找到一个损失函数,学习的目标就是不断的最小化损失函数值 或者找到一个效用函数,不断的最大化效用函数值 ''' cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction), reduction_indices=[1])) # loss train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy) sess.run(tf.global_variables_initializer()) for i in range(1000): batch_xs, batch_ys = mnist.train.next_batch(100) sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: 0.5}) if i % 50 == 0: print(compute_accuracy( mnist.test.images, mnist.test.labels))