从感知机到神经网络的Python实现见之前的文章,本文用Tensorflow的高级API实现一个浅层的神经网络,数据使用MNIST数据集。学习曲线通过Tensorboard表示出来。
前置库与设置
import tensorflow as tf
from datetime import datetime
root_logdir="tf_logs" #设置根目录为当前目录下的tf_logs文件夹
now=datetime.utcnow().strftime("%Y%m%d%H%M%S")
logdir="{}/run-{}/".format(root_logdir,now) #文件夹名加入时间戳
图的构建
tf.reset_default_graph()
网络属性
n_inputs=28*28 #MNIST图片像素,即样本特征数
n_hidden1=300 #第一隐含层的神经元数
n_hidden2=100 #第二隐含层的神经元数
n_outputs=10 #输出数
原始数据节点
由于构建神经网络所用的dense()函数需要指明tensor的形状,此处显式声明X、Y的形状。
X=tf.placeholder(dtype=tf.float32,shape=(None,n_inputs),name="X") #X为二维矩阵,行数为样本数(未知),列数为特征数
Y=tf.placeholder(dtype=tf.int64,shape=(None),name="Y") #Y为单维向量
网络节点
tf.layers.dense()函数会根据传入参数自动创建一个权重矩阵与偏置矩阵。
with tf.name_scope("dnn"):
hidden1=tf.layers.dense(X,n_hidden1,name="hidden1",activation=tf.nn.relu)
hidden2=tf.layers.dense(hidden1,n_hidden2,name="hidden2",activation=tf.nn.relu)
logits=tf.layers.dense(hidden2,n_outputs,name="outputs")
损失函数
with tf.name_scope("loss"):
entropy=tf.nn.sparse_softmax_cross_entropy_with_logits(labels=Y,logits=logits)
loss=tf.reduce_mean(entropy,name="loss")
loss_summary=tf.summary.scalar('loss',loss)
训练节点
learning_rate=0.01
with tf.name_scope("train"):
optimizer=tf.train.GradientDescentOptimizer(learning_rate)
training_op=optimizer.minimize(loss)
评估节点
评估节点负责评估模型,此处主要计算模型的准确率。
with tf.name_scope("eval"):
correct=tf.nn.in_top_k(logits,Y,1) #取某一样本所属类别概率最大的预测结果,再与此样本的标签Y进行对比
accuracy=tf.reduce_mean(tf.cast(correct,tf.float32)) #将correct矩阵进行类型转换,再求均值
accuracy_summary=tf.summary.scalar('accuracy',accuracy)
Tensorboard设置
file_writer=tf.summary.FileWriter(logdir,tf.get_default_graph())
图的运算
载入数据
#从tensorflow中载入MNIST数据
from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets("/tmp/data/")
执行训练
n_epochs=400
batch_size=50
init=tf.global_variables_initializer() #全局变量初始化器
saver=tf.train.Saver() #模型数据保存器
with tf.Session() as sess:
init.run()
for epoch in range(n_epochs):
for iteration in range(mnist.train.num_examples//batch_size):
X_batch,Y_batch=mnist.train.next_batch(batch_size)
sess.run(training_op,feed_dict={X:X_batch,Y:Y_batch})
loss_summary_str,acc_summary_str=sess.run([accuracy_summary,loss_summary],feed_dict={X:mnist.test.images,Y:mnist.test.labels}) #给数据
file_writer.add_summary(loss_summary_str,epoch)
file_writer.add_summary(acc_summary_str,epoch)
if (epoch+1)%50==0:
acc_train=accuracy.eval(feed_dict={X:X_batch,Y:Y_batch})
acc_test=accuracy.eval(feed_dict={X:mnist.test.images,Y:mnist.test.labels})
print(epoch+1,"Train acc:",acc_train,"Test acc:",acc_test)
save_path=saver.save(sess,"./my_model_final.ckpt") #保存模型数据
file_writer.close()
Tensorboard可视化结果
在命令行中键入tensorboard --logdir Desktop\tmp\tf_logs
启动Tensorboard,然后再浏览器中键入http://Daya-Workstation:6006
进入可视化页面。
模型的图
损失曲线
测试集上的准确率曲线