import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data # TensorFlow中提供的演示数据 """ 神经网络的一些重要概念: 全连接层:第N层和第N-1层之间的部分 输出:有几个类别就有几个输出,每一个样本对每个类别都有一个概率值 softmax:计算每个样本对所有类别的概率 交叉熵:计算每个样本得出概率后,其损失值是多少 反向传播:通过计算的损失值,不断的去调整权重,使得损失值达到最小 """ FLAGS = tf.app.flags.FLAGS tf.app.flags.DEFINE_integer("is_train", 1, "指定程序是预测还是训练") def full_connected(): # 获取真实数据,会自动创建目录 mnist = input_data.read_data_sets("./mnist/input_data/", one_hot=True) # 1.建立数据的占位符 特征值X [None, 784] 目标值y_true [None, 10] with tf.variable_scope("data"): # None代表不确定的样本数 x = tf.placeholder(tf.float32, [None, 784]) y_true = tf.placeholder(tf.float32, [None, 10]) # 2.建立一个全连接层的神经网络 权重w [784, 10] 偏置b [10] with tf.variable_scope("fc_model"): # 随机初始化权重和偏置 weight = tf.Variable(tf.random_normal([784, 10], mean=0.0, stddev=1.0, name="w")) bias = tf.Variable(tf.constant(0.0, shape=[10])) # 预测None个样本的输出结果,matmul矩阵相乘 y_predict = tf.matmul(x, weight) + bias # 3.求所有样本的损失,然后求损失 with tf.variable_scope("soft_cross"): # 求平均交叉熵损失 loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true, logits=y_predict)) # 4.梯度下降求损失 with tf.variable_scope("optimizer"): # 0.1是学习率,minimize表示求最小损失 train_op = tf.train.GradientDescentOptimizer(0.2).minimize(loss) # 5.计算准确率,每一个样本对应每个特征值都有一个概率,tf.argmax(y_true, 1), tf.argmax(y_predict, 1)返回的是分别是真实值和预测值的正确的下标,equal判断两个下标是否一致,一样,则这个样本被标为1 with tf.variable_scope("acc"): equal_list = tf.equal(tf.argmax(y_true, 1), tf.argmax(y_predict, 1)) # equal_list None个样本 [1, 0, 1, 1, 0, 0.....] accuracy = tf.reduce_mean(tf.cast(equal_list, tf.float32)) # 收集变量 tf.summary.scalar("losses", loss) tf.summary.scalar("acc", accuracy) # 收集高纬度变量 tf.summary.histogram("weights", weight) tf.summary.histogram("biases", bias) # 定义初始化变量op init_op = tf.global_variables_initializer() # 定义一个合并变量op merged = tf.summary.merge_all() # 创建一个saver保存训练好的模型 saver = tf.train.Saver() # 开启会话进行训练 with tf.Session() as sess: # 初始化变量 sess.run(init_op) #建立events文件,然后写入 filewriter = tf.summary.FileWriter("./tmp/summary/test/", graph=sess.graph) if FLAGS.is_train ==1: # 迭代步数训练,更新参数 for i in range(2000): # 取出真实存在的特征值和目标值,50表示50个样本作为一个批次 mnist_x, mnist_y = mnist.train.next_batch(50) # 运行训练op sess.run(train_op, feed_dict={x:mnist_x, y_true:mnist_y}) # 写入每步训练的值 summary = sess.run(merged, feed_dict={x:mnist_x, y_true:mnist_y}) filewriter.add_summary(summary, i) # feed_dict这里的参数是必须,但是没有实际意义 print("训练第{}步,准确率:{}".format(i, sess.run(accuracy, feed_dict={x:mnist_x, y_true:mnist_y}))) # 保存模型 saver.save(sess, "./tmp/ckpt/fc_model") else: # 加载模型 saver.restore(sess, "tmp/ckpt/fc_model") # 进行预测 for i in range(100): x_test, y_test = mnist.test.next_batch(50) print("第{}张图片,首先数字目标是:{},预测结果是:{}".format(i, tf.argmax(y_test, 1).eval(), tf.argmax(sess.run(y_predict, feed_dict={x:x_test, y_true:y_test}), 1).eval())) return None if __name__ == "__main__": full_connected()