在b站上看视频学习tensorflow基本知识,同时记录一下~
由于课程第一节讲的是环境搭建,那部分自己完成了,没有听课,所以就从(二)开始吧
- 视频内容:05-1;05-2;05-3
- 主要内容:使用Tensorboard进行结构可视化
- 代码链接参考:github,由于所有的代码都是在Jupyter Notebook中进行编写以及运行,所有代码编写过程中有很多次运行,查看输出结果。
- 代码格式是.ipynb格式,查看代码方法:已经安装好了Anaconda等环境,打开终端,输入
Jupyter Notebook
,就可以按照路径打开代码了。
5-1 优化mnist手写识别
优化策略:
- 批次大小设置为128;
- 学习率设置为变量,epoch(50)每迭代一次改一次学习率,赋给学习率,学习率越来越小;
- 网络两个隐藏层2000和500个神经元;
- 定义了dropout,设置为0.8;
- 使用交叉熵代价函数;
结果:发现迭代速度很快。
完整代码如下:
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 载入数据
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
# 批次的大小
batch_size = 128
n_batch = mnist.train.num_examples // batch_size
x = tf.placeholder(tf.float32, [None,784])
y = tf.placeholder(tf.float32, [None, 10])
keep_prob = tf.placeholder(tf.float32)
lr = tf.Variable(1,dtype = tf.float32)
# 创建神经网络
W1 = tf.Variable(tf.truncated_normal([784,2000],stddev=0.1))
b1 = tf.Variable(tf.zeros([1, 2000]))
# 激活层
layer1 = tf.nn.relu(tf.matmul(x,W1) + b1)
# drop层
layer1 = tf.nn.dropout(layer1,keep_prob=keep_prob)
# 第二层
W2 = tf.Variable(tf.truncated_normal([2000,500],stddev=0.1))
b2 = tf.Variable(tf.zeros([1, 500]))
layer2 = tf.nn.relu(tf.matmul(layer1,W2) + b2)
layer2 = tf.nn.dropout(layer2,keep_prob=keep_prob)
# 第三层
W3 = tf.Variable(tf.truncated_normal([500,10],stddev=0.1))
b3 = tf.Variable(tf.zeros([1,10]))
# prediction = tf.nn.softmax(tf.matmul(layer2,W3) + b3)
prediction = tf.matmul(layer2,W3) + b3
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=prediction))
# 梯度下降法
# train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
train_step = tf.train.AdadeltaOptimizer(lr).minimize(loss)
# train_step = tf.train.AdamOptimizer().minimize(loss)
# train_step = tf.train.RMSPropOptimizer(learning_rate=0.001).minimize(loss)
# train_step = tf.train.AdagradOptimizer(learning_rate=1).minimize(loss)
# 初始化变量
init = tf.global_variables_initializer()
prediction_2 = tf.nn.softmax(prediction)
# 得到一个布尔型列表,存放结果是否正确
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(prediction_2,1)) #argmax 返回一维张量中最大值索引
# 求准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) # 把布尔值转换为浮点型求平均数
with tf.Session() as sess:
sess.run(init)
for epoch in range(50):
sess.run(tf.assign(lr, 1*(0.98**epoch)))
for batch in range(n_batch):
# 获得批次数据
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
sess.run(train_step, feed_dict={x:batch_xs, y:batch_ys, keep_prob:0.8})
learning_rate = sess.run(lr)
acc = sess.run(accuracy, feed_dict={x:mnist.test.images,y:mnist.test.labels,keep_prob:1.0} )
print("Iter " + str(epoch) + " Testing Accuracy: " + str(acc)+ ", lr: "+ str(learning_rate))
5-2 tensorboard可视化工具
而在训练过程中,主要用到了tf.summary()的各类方法,能够保存训练过程以及参数分布图并在tensorboard显示。
TensorBoard通过summary对数据进行汇总。常用操作如下:
- tf.summary.FileWriter——用于将汇总数据写入磁盘
tf.summary.FileWriter(train_log_dir, sess.graph)
打开一个writer,相当于python中的open函数,打开一个写句柄。
train_log_dir:要保存的目录
sess.graph:保存计算图(该参数可以为空) - tf.summary.scalar——对标量数据汇总和记录
tf.summary.scalar(name, tensor) # 生成一个summary
name:生成节点的名称
tensor:需要展示的tensor - tf.summary.histogram——记录数据的直方图
tf.summary.histogram(name, tensor) # 直方图
name:节点名称 - tf.summary.merge——对各类的汇总进行一次合并
tf.summary.merge([loss_summary, accuracy_summary])
需要手动指定需要聚合的变量,存入参数列表中 - tf.summary.merge_all——合并默认图像中的所有汇总
tf.summary.merge_all()
将此函数以上所有带有 summary 的变量聚合起来,使用起来比较省心
保存一个图的完整代码如下:writer = tf.summary.FileWriter('logs/',sess.graph)
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 载入数据
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
# 批次的大小
batch_size = 128
n_batch = mnist.train.num_examples // batch_size
# 命名空间
with tf.name_scope('input'):
x = tf.placeholder(tf.float32, [None,784],name="X-input")
#变量的name只是一个名字,类似备注,
#用这个变量的时候,还是使用前面的名字的,而不是name
y = tf.placeholder(tf.float32, [None, 10],name='y-input')
# 创建一个简单的神经网络
with tf.name_scope('layer'):
with tf.name_scope('weights'):
W = tf.Variable(tf.zeros([784,10]),name='W')
with tf.name_scope('biases'):
b = tf.Variable(tf.zeros([1, 10]),name='b')
with tf.name_scope('xw_plus_b'):
wx_plus_b = tf.matmul(x,W) + b
with tf.name_scope('softmax'):
prediction = tf.nn.softmax(wx_plus_b)
# 代价函数
with tf.name_scope('loss'):
loss = tf.reduce_mean(tf.square(y-prediction))
# 梯度下降法
with tf.name_scope('train'):
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
# 初始化变量
init = tf.global_variables_initializer()
# 得到一个布尔型列表,存放结果是否正确
with tf.name_scope('accuracy'):
with tf.name_scope('correct_prediction'):
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(prediction,1)) #argmax 返回一维张量中最大值索引
# 求准确率
with tf.name_scope('accuracy'):
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) # 把布尔值转换为浮点型求平均数
with tf.Session() as sess:
sess.run(init)
writer = tf.summary.FileWriter('logs/',sess.graph)
for epoch in range(1):
for batch in range(n_batch):
# 获得批次数据
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
sess.run(train_step, feed_dict={x:batch_xs, y:batch_ys})
acc = sess.run(accuracy, feed_dict={x:mnist.test.images,y:mnist.test.labels})
print("Iter " + str(epoch) + " Testing Accuracy: " + str(acc))
#结果:Iter 0 Testing Accuracy: 0.7965
5-3 查看网络运行的数据
我们指导scalar只能显示标量信息,他不能直接显示张量的信息,但是我们可以换一种方式,比如显示张量的最大值、最小值、平均值等信息。
- 首先写一个函数:定义一个函数参数概要,可能分析权值变化和偏置变化的时候用到。
def variable_summaries(var):
with tf.name_scope('summaries'):
mean = tf.reduce_mean(var)
tf.summary.scalar('mean',mean) # 平均值
with tf.name_scope('stddev'):
stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))
tf.summary.scalar('stddev',stddev) # 标准差
tf.summary.scalar('max', tf.reduce_max(var)) # 最大值
tf.summary.scalar('min', tf.reduce_min(var)) # 最小值
tf.summary.histogram('histogram',var) # 直方图
要显示哪个张量,就可以直接用这个函数来完成。函数中有:tf.summary.scalar
表示:生成一个summary
- 调用刚才定义的函数
variable_summaries(W)
来查看权重和偏置。 - 权值和偏执有很多,才会去算平均值标准差等,loss就一个值,那就没必要调用我们定义的函数。所以直接用:
tf.summary.scalar('loss', loss)
就可以了。 - 写完所有的层之后,在运行图之前,合并所有的标量,
merged = tf.summary.merge_all()
- 仍然完成画图任务,代码:
writer = tf.summary.FileWriter('logs/',sess.graph)
- 运行网络并记录log,
summary,_ = sess.run([merged, train_step], feed_dict={x:batch_xs, y:batch_ys})
- 刚才保存了图,现在记录保另一组变量变量:
writer.add_summary(summary,epoch)
完整的具体代码:
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 载入数据
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
# 批次的大小
batch_size = 128
n_batch = mnist.train.num_examples // batch_size
# 参数概要
def variable_summaries(var):
with tf.name_scope('summaries'):
mean = tf.reduce_mean(var)
tf.summary.scalar('mean',mean) # 平均值
with tf.name_scope('stddev'):
stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))
tf.summary.scalar('stddev',stddev) # 标准差
tf.summary.scalar('max', tf.reduce_max(var)) # 最大值
tf.summary.scalar('min', tf.reduce_min(var)) # 最小值
tf.summary.histogram('histogram',var) # 直方图
# 命名空间
with tf.name_scope('input'):
x = tf.placeholder(tf.float32, [None,784],name="X-input")
y = tf.placeholder(tf.float32, [None, 10],name='y-input')
# 创建一个简单的神经网络
with tf.name_scope('layer'):
with tf.name_scope('weights'):
W = tf.Variable(tf.zeros([784,10]),name='W')
variable_summaries(W)
with tf.name_scope('biases'):
b = tf.Variable(tf.zeros([1, 10]),name='b')
variable_summaries(b)
with tf.name_scope('xw_plus_b'):
wx_plus_b = tf.matmul(x,W) + b
with tf.name_scope('softmax'):
prediction = tf.nn.softmax(wx_plus_b)
# 代价函数
with tf.name_scope('loss'):
loss = tf.reduce_mean(tf.square(y-prediction))
tf.summary.scalar('loss', loss)
# 梯度下降法
with tf.name_scope('train'):
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
# 初始化变量
init = tf.global_variables_initializer()
# 得到一个布尔型列表,存放结果是否正确
with tf.name_scope('accuracy'):
with tf.name_scope('correct_prediction'):
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(prediction,1)) #argmax 返回一维张量中最大值索引
# 求准确率
with tf.name_scope('accuracy'):
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) # 把布尔值转换为浮点型求平均数
tf.summary.scalar('accuracy', accuracy)
# 合并所有summary
merged = tf.summary.merge_all()
with tf.Session() as sess:
sess.run(init)
writer = tf.summary.FileWriter('logs/',sess.graph)
for epoch in range(51):
for batch in range(n_batch):
# 获得批次数据
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
# 运行网络并记录log
summary,_ = sess.run([merged, train_step], feed_dict={x:batch_xs, y:batch_ys})
# 记录变量
writer.add_summary(summary,epoch)
#前面为writer只保存了图,现在还要将刚才运行的所有保存起来。
#调用writer的add_summary方法将训练过程以及训练步数保存
acc = sess.run(accuracy, feed_dict={x:mnist.test.images,y:mnist.test.labels})
print("Iter " + str(epoch) + " Testing Accuracy: " + str(acc))
writer.close()
writer.close()