tensorflow提供了一个专门的可视化工具—TensorBoard,通过TensorFlow将监控数据写入文件系统,并利用Web后端监控对应的文件系统,从而可以允许用户从远程查看网络的监控数据。
TensorBoard的使用需要模型代码和浏览器文件相配合。在使用之前需要安装TensorBoard库。
pip install tensorboard
本节分模型端和浏览器端介绍如何使用tensorboard
创建监控对象类实例:tf.summary.create_file_writer(log_dir),同时指定监控数据写入目录。
步骤1:创建监控类,并指定监控数据写入的目录log_dir。
summary_writer=tf.summary.create_file_writer(log_dir)#log_dir为指定的监控数据写入的目录
步骤2:通过监控类,将监控数据写入目录。
'''类型1:被监控的数据时标量数据,通过tf.summary.scalar函数记录监控数据'''
with summary_writer.as_default():#写入环境
#当前时间戳step上的数据为loss,写入到名为train——loss数据库中
tf.summary.scalar('train——loss',float(loss),step=step)
#tensorboard通过字符串ID来区分不同类别的监控数据,因此对于误差数据,我们将它命名为‘train——loss’其他类别的数据不可写入
'''类型2:被监控的数据是图片数据:通过tf.summary.image函数记录监控图片数据'''
with summary_writer.as_default():#写入环境
#在训练时,通过tf.summary.image函数可视化样本图片。由于tensorflow中的张量一般包含了多个样本,
#因此tf.summary.image函数接受多个图片的张量数据,并通过设置max_outputs参数来选择最多显示的图片数量。
tf.summary.image('val-onebyone-images', val_images, max_outputs=9,step=step)
'''类型3:被监控的数据时张量数据,通过tf.summary.histogram函数记录监控的张量数据的直方图分布'''
with summary_writer.as_default():#写入环境
#可视化真实标签的直方图分布
tf.summary.histogram('y_hist', y, max_outputs=9,step=step)
'''类型4:被监控的数据是文本数据,通过tf.summary.text函数记录监控的文本数据'''
with summary_writer.as_default():#写入环境
#可视化文本信息
tf.summary.text('loss_text',str(float(loss)))
步骤3:运行程序,相应的监控数据将实时写入指定文件目录。
完整程序举例:
运行程序之后在创建的文件目录log_dir20200502-140016下,生成监控数据的记录文件
import tensorflow as tf
import matplotlib.pyplot as plt
import datetime
import io # 文件数据流
def image_grid(images):
# 返回一个5x5的mnist图像
figure = plt.figure(figsize=(10, 10))
for i in range(25):
plt.subplot(5, 5, i+1, title='name')
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(images[i], cmap=plt.cm.binary)
return figure
def plot_to_image(figure):
buf = io.BytesIO() # 在内存中存储画
plt.savefig(buf, format='png')
plt.close(figure)
buf.seek(0)
# 传化为TF 图
image = tf.image.decode_png(buf.getvalue(), channels=4)
image = tf.expand_dims(image, 0)
return image
######################################(1)数据加载######################################################
def preprocess(x, y):
x = tf.cast(x, dtype=tf.float32) / 255.
y = tf.cast(y, dtype=tf.int32)
return x, y
batchsz = 128
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
db=tf.data.Dataset.from_tensor_slices((x_train, y_train))
db = db.map(preprocess).shuffle(60000).batch(batchsz).repeat(10)
ds_val = tf.data.Dataset.from_tensor_slices((x_test, y_test))
ds_val = ds_val.map(preprocess).batch(batchsz, drop_remainder=True)
######################################(2)创建网络######################################################
# 利用tf.keras.Sequential容器封装网络层
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'), # 创建一层网络,设置输出节点数为128,激活函数类型为Relu
tf.keras.layers.Dropout(0.2), # 在训练中每次更新时, 将输入单元的按比率随机设置为 0, 这有助于防止过拟合
tf.keras.layers.Dense(10, activation='softmax')]) # Dense层就是所谓的全连接神经网络层
######################################(3)训练网络######################################################
'''(1)创建监控类,并指定监控数据写入的目录,本例是log_dir'''
log_dir=r'E:\PycharmProject\Deep-Learning-with-TensorFlow-book\ch08-Keras高层接口\log_dir'
current_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
log_dir = log_dir + current_time
summary_writer = tf.summary.create_file_writer(log_dir) # 创建监控类,监控数据写入到新创建的log_dir目录
sample_img = next(iter(db))[0]
sample_img = sample_img[0:25] # 前25张图
sample_img = tf.reshape(sample_img, [1, 28, 28, 1])
'''(2)监控数据写入目录:训练集25张图片作为监控数据'''
with summary_writer.as_default(): # 写入环境
tf.summary.image("Training sample:", sample_img, step=0)#图片数据作为监控数据,写入文件目录
optimizer=tf.keras.optimizers.Adam(lr=0.01)#设置优化函数
for step, (x, y) in enumerate(db): # 遍历切分好的数据step:0->599
with tf.GradientTape() as tape:
x = tf.reshape(x, (-1, 28*28))
out = model(x)
y = tf.one_hot(y, depth=10)
loss = tf.reduce_mean(tf.losses.categorical_crossentropy(y, out, from_logits=True))#计算损失
grads = tape.gradient(loss, model.trainable_variables)#计算梯度
optimizer.apply_gradients(zip(grads, model.trainable_variables))#模型参数更新
if step % 100 == 0:
print(step, 'loss:', float(loss)) # 每迭代100步打印一次损失
'''(2)监控数据写入目录:每迭代100次,损失作为监控数据写入目录'''
with summary_writer.as_default():#每迭代100步将监控数据loss写入到目录文件log_dir,命名为’train-loss‘中,
tf.summary.scalar('train-loss', float(loss), step=step) # 将loss写入到train-loss中
if step % 500 == 0:
total, total_correct = 0., 0
for _, (m, n) in enumerate(ds_val):
m = tf.reshape(m, (-1, 28*28))
out = model(m)
pred = tf.argmax(out, axis=1)
pred = tf.cast(pred, dtype=tf.int32)
correct = tf.equal(pred, n)
total_correct += tf.reduce_sum(tf.cast(correct, dtype=tf.int32)).numpy()
total += m.shape[0]
print(step, 'Evaluate Acc:', total_correct / total)#每迭代500步,使用验证集测试,并打印验证的精度
val_images = m[:25]#p
val_images = tf.reshape(val_images, [-1, 28, 28, 1])
'''(2)监控数据写入目录:每迭代500次,测试精度和测试集中的25张图片作为监控数据写入目录'''
with summary_writer.as_default():
tf.summary.scalar('test-acc', float(total_correct / total), step=step) # 将监控数据accuracy写入目录文件log_dir
tf.summary.image("val-onebyone-images:", val_images, max_outputs=25, step=step) # 将监控数据25张测试图片写入目录文件log_dir
val_images = tf.reshape(val_images, [-1, 28, 28])
figure = image_grid(val_images)
tf.summary.image('val-images:', plot_to_image(figure), step=step)
'''(3)运行程序:所有的监控写入文件目录,数据实时写入文件'''
监控数据已经写入到指定的文件目录中。实时远程查看、可视化这些监控数据,需要借助浏览器和web后端。
步骤1:打开web后端,通过终端运行tensorboard --logdir path,指定web后端监控的文件目录,即可打开web后端监控进程。
步骤2:打开浏览器,输入网址为http://localhost:6006,即可监控训练数据
标量监控页面SCALARS,图片可视化页面IMAGES
tensorboard可以可视化训练数据,Facebook开发的Visdom工具也可以方便的可视化数据,并且支持的可视化方式十分丰富。Visdom可以直接接受pytorch的张量类型的数据,但不能直接接受tensorflow的张量类型的数据,需要转换为numpy数组。对于追求丰富可视化手段和实时监控的开发者,visdom是一个很好的选择。
通常pytorch可视化工作,使用visdom实现。visdom只支持Torch和numpy数据。