个性化阅读
专注于IT技术分析

TensorBoard精品开发教程

本文概述

本教程将指导你如何使用TensorBoard, 这是一个了不起的实用程序, 可让你可视化数据及其行为。你将看到在训练神经网络时可以出于何种目的使用它。

  • 首先, 你将学习如何启动TensorBoard, 然后概述所提供的不同视图。
  • 接下来, 你将看到如何可视化在计算过程中产生的标量值。你还将学习如何从模型中获取见解, 以修复学习中的任何潜在错误。
  • 之后, 你将研究如何将向量或数据集合可视化为直方图。
  • 使用此视图, 你将比较神经网络的权重初始化在学习过程中如何影响神经网络的权重更新。

提示:在此处查看与Keras一起进行的srcmini深度学习课程。

在开始之前, 请确保导入以下库以成功运行代码:

from pandas_datareader import data
import matplotlib.pyplot as plt
import pandas as pd
import datetime as dt
import urllib.request, json
import os
import numpy as np

# This code has been tested with TensorFlow 1.6
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

启动TensorBoard

要通过TensorBoard可视化事物, 首先需要启动其服务。为了那个原因,

  1. 打开命令提示符(Windows)或终端(Ubuntu / Mac)
  2. 进入项目主目录
  3. 如果你使用的是Python virtuanenv, 请激活已在其中安装TensorFlow的虚拟环境
  4. 确保你可以通过Python查看TensorFlow库。为了那个原因,
    • 输入python3, 你会得到>>>外观提示
    • 尝试将tensorflow导入为tf
    • 如果你可以成功运行此程序, 那很好
  5. 通过键入exit()退出Python提示符(即>>>), 然后键入以下命令
    • tensorboard –logdir =摘要
    • –logdir是你将创建可视化数据的目录
    • TensorBoard将数据保存到的文件称为事件文件
    • 保存到事件文件中的数据类型称为摘要数据
    • 你可以选择使用–port = <port_you_like>更改TensorBoard运行的端口
  6. 你现在应该收到以下消息
    • TensorBoard 1.6.0位于<url>:6006(按CTRL + C退出)
  7. 在Web浏览器中输入<url>:6006
    • 此时, 你应该可以看到橙色的仪表板。你将不会显示任何内容, 因为尚未生成数据。

注意:TensorBoard不喜欢在同一目录中查看多个事件文件。这可能会导致你在显示屏上看到非常可怕的曲线。因此, 你应该为每个不同的示例(例如, summary / first, summary / second, …)创建一个单独的文件夹以保存数据。要记住的另一件事是, 如果要重新运行实验(即将事件文件保存到已填充的文件夹中), 则必须确保首先删除现有事件文件。

TensorBoard的不同观点

不同的视图采用不同格式的输入, 并以不同的方式显示它们。你可以在橙色顶部栏上更改它们。

  • 标量-可视化标量值, 例如分类精度。
  • 图形-可视化模型的计算图, 例如神经网络模型。
  • 分布-可视化数据随时间变化的方式, 例如神经网络的权重。
  • 直方图-更加精细的分布图, 以3维透视图显示分布
  • 投影仪-可用于可视化单词嵌入(即, 单词嵌入是捕获其语义关系的单词的数字表示形式)
  • 图像-可视化图像数据
  • 音频-可视化音频数据
  • 文本-​​可视化文本(字符串)数据

在本教程中, 你将涵盖以粗体显示的视图。

了解标量可视化的好处

在本节中, 你将首先了解为什么可视化某些指标(例如损失或准确性)是有益的。在训练深度神经网络时, 影响初学者的关键问题之一是缺乏对各种设计选择和超参数的影响的了解。

例如, 如果你不注意初始化深层神经网络的权重以使权重之间的差异非常大, 则模型将迅速发散和收缩。另一方面, 即使你有能力驯服神经网络来利用它们, 事情也会出错。例如, 不注意学习率会导致模型的分歧或过早地饱和到次优性能。

快速检测模型问题的一种方法是实时图形化显示模型中发生的事情(例如, 每100次迭代)。因此, 如果你的模型行为异常, 它将清晰可见。这正是TensorBoard为你提供的。你可以决定需要显示哪些值, 并且它将在学习期间保持这些值的实时可视化。

首先, 首先创建一个五层神经网络, 该网络将用于对手写数字图像进行分类。为此, 你将使用著名的MNIST数据集。 TensorFlow提供了一个简单的API来加载MNIST数据, 因此你无需手动下载它。在此之前, 你定义一个简单的方法(即precision()), 该方法针对真实标签计算某些预测的准确性。

def accuracy(predictions, labels):
    '''
    Accuracy of a given set of predictions of size (N x n_classes) and
    labels of size (N x n_classes)
    '''
    return np.sum(np.argmax(predictions, axis=1)==np.argmax(labels, axis=1))*100.0/labels.shape[0]

定义输入, 输出, 权重和偏差

首先, 定义一个batch_size, 表示你在单个优化/验证或测试步骤中采样的数据量。然后, 定义layer_ids, 它为要定义的神经网络的每个层提供一个标识符。然后, 你可以定义layer_sizes。

请注意, len(layer_sizes)应该为len(layer_ids)+1, 因为layer_sizes包括开头的输入大小。

MNIST的图像尺寸为28×28, 展开为单个尺寸时将为784。然后, 你可以定义输入和标签占位符, 稍后将使用它们来训练模型。最后, 为每个图层定义两个TensorFlow变量(即权重和偏差)。

你可以使用变量作用域(此处有更多信息), 以便可以很好地命名变量, 并且以后可以更轻松地访问变量。

batch_size = 100
layer_ids = ['hidden1', 'hidden2', 'hidden3', 'hidden4', 'hidden5', 'out']
layer_sizes = [784, 500, 400, 300, 200, 100, 10]

tf.reset_default_graph()

# Inputs and Labels
train_inputs = tf.placeholder(tf.float32, shape=[batch_size, layer_sizes[0]], name='train_inputs')
train_labels = tf.placeholder(tf.float32, shape=[batch_size, layer_sizes[-1]], name='train_labels')

# Weight and Bias definitions
for idx, lid in enumerate(layer_ids):

    with tf.variable_scope(lid):
        w = tf.get_variable('weights', shape=[layer_sizes[idx], layer_sizes[idx+1]], initializer=tf.truncated_normal_initializer(stddev=0.05))
        b = tf.get_variable('bias', shape= [layer_sizes[idx+1]], initializer=tf.random_uniform_initializer(-0.1, 0.1))

计算Logit, 预测, 损失和优化

定义了每个层的输入/输出占位符, 权重和偏差后, 你现在可以定义计算以计算神经网络的对数。 Logits是在神经网络的最后一层中产生的非标准化值。归一化后, 你称它们为预测。这涉及遍历神经网络的每一层并计算tf.matmul(h, w)+ b。你还需要对除最后一层以外的所有层应用激活函数, 如tf.nn.relu(tf.matmul(h, w)+ b)。

接下来, 定义用于优化神经网络的损失函数。在此示例中, 你可以使用交叉熵损失, 它在分类问题中通常提供比均方误差更好的结果。

最后, 你将需要定义一个优化器, 以吸收损耗并在使损耗最小化的方向上更新神经网络的权重。

# Calculating Logits
h = train_inputs
for lid in layer_ids:
    with tf.variable_scope(lid, reuse=True):
        w, b = tf.get_variable('weights'), tf.get_variable('bias')
        if lid != 'out':
          h = tf.nn.relu(tf.matmul(h, w)+b, name=lid+'_output')
        else:
          h = tf.nn.xw_plus_b(h, w, b, name=lid+'_output')

tf_predictions = tf.nn.softmax(h, name='predictions')
# Calculating Loss
tf_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=train_labels, logits=h), name='loss')

# Optimizer
tf_learning_rate = tf.placeholder(tf.float32, shape=None, name='learning_rate')
optimizer = tf.train.MomentumOptimizer(tf_learning_rate, momentum=0.9)
grads_and_vars = optimizer.compute_gradients(tf_loss)
tf_loss_minimize = optimizer.minimize(tf_loss)

定义摘要

在这里你可以定义tf.summary对象。这些对象是TensorBoard理解的实体的类型。这意味着无论你希望显示什么值, 都应将其封装为tf.summary对象。

有几种不同类型的摘要。在这里, 由于仅可视化标量, 因此可以定义tf.summary.scalar对象。此外, 你可以使用tf.name_scope在板上划分标量。即, 具有相同名称范围的标量将显示在同一行上。在此定义三个不同的摘要。

  • tf_loss_summary:每当需要将其发布到面板时, 都通过占位符输入值
  • tf_accuracy_summary:每当需要将其发布到板时, 都可以通过占位符来输入值
  • tf_gradnorm_summary:这将计算神经网络最后一层的梯度的l2范数。梯度范数可以很好地指示神经网络的权重是否正确更新。梯度标准太小可能表示梯度消失, 或者梯度太大可能意味着梯度现象爆炸。
# Name scope allows you to group various summaries together
# Summaries having the same name_scope will be displayed on the same row
with tf.name_scope('performance'):
    # Summaries need to be displayed
    # Whenever you need to record the loss, feed the mean loss to this placeholder
    tf_loss_ph = tf.placeholder(tf.float32, shape=None, name='loss_summary')
    # Create a scalar summary object for the loss so it can be displayed
    tf_loss_summary = tf.summary.scalar('loss', tf_loss_ph)

    # Whenever you need to record the loss, feed the mean test accuracy to this placeholder
    tf_accuracy_ph = tf.placeholder(tf.float32, shape=None, name='accuracy_summary')
    # Create a scalar summary object for the accuracy so it can be displayed
    tf_accuracy_summary = tf.summary.scalar('accuracy', tf_accuracy_ph)

# Gradient norm summary
for g, v in grads_and_vars:
    if 'hidden5' in v.name and 'weights' in v.name:
        with tf.name_scope('gradients'):
            tf_last_grad_norm = tf.sqrt(tf.reduce_mean(g**2))
            tf_gradnorm_summary = tf.summary.scalar('grad_norm', tf_last_grad_norm)
            break
# Merge all summaries together
performance_summaries = tf.summary.merge([tf_loss_summary, tf_accuracy_summary])

执行神经网络:加载数据, 培训, 验证和测试

在下面的代码中, 请执行以下操作。首先, 创建一个会话, 在其中执行上面定义的操作。然后, 你创建一个用于保存摘要数据的文件夹。接下来, 创建一个摘要编写器summ_writer。你现在可以初始化所有变量。这之后将加载MNIST数据集。

然后, 对于每个时期和训练数据中的每个批次(即每次迭代), 如果是第一次迭代, 则执行gradnorm_summary, 并使用摘要编写器将gradnorm_summary写入事件文件。现在, 你可以执行模型优化和损失计算。在经历了整个训练数据集的一个时期之后, 请计算平均训练损失。

你也对验证数据集进行类似的处理。具体来说, 对于验证数据中的每个批次, 你都可以计算验证准确性。此后, 计算完整验证集的平均验证准确性。

最后, 执行测试阶段。在此, 对于测试数据中的每个批次, 你将计算每个批次的测试精度。这样, 你就可以计算整个测试集的平均测试精度。最后, 你执行performance_summaries并将它们与摘要编写器一起写入事件文件。


image_size = 28
n_channels = 1
n_classes = 10
n_train = 55000
n_valid = 5000
n_test = 10000
n_epochs = 25

config = tf.ConfigProto(allow_soft_placement=True)
config.gpu_options.allow_growth = True
config.gpu_options.per_process_gpu_memory_fraction = 0.9 # making sure Tensorflow doesn't overflow the GPU

session = tf.InteractiveSession(config=config)

if not os.path.exists('summaries'):
    os.mkdir('summaries')
if not os.path.exists(os.path.join('summaries', 'first')):
    os.mkdir(os.path.join('summaries', 'first'))

summ_writer = tf.summary.FileWriter(os.path.join('summaries', 'first'), session.graph)

tf.global_variables_initializer().run()

accuracy_per_epoch = []
mnist_data = input_data.read_data_sets('MNIST_data', one_hot=True)


for epoch in range(n_epochs):
    loss_per_epoch = []
    for i in range(n_train//batch_size):

        # =================================== Training for one step ========================================
        batch = mnist_data.train.next_batch(batch_size)    # Get one batch of training data
        if i == 0:
            # Only for the first epoch, get the summary data
            # Otherwise, it can clutter the visualization
            l, _, gn_summ = session.run([tf_loss, tf_loss_minimize, tf_gradnorm_summary], feed_dict={train_inputs: batch[0].reshape(batch_size, image_size*image_size), train_labels: batch[1], tf_learning_rate: 0.0001})
            summ_writer.add_summary(gn_summ, epoch)
        else:
            # Optimize with training data
            l, _ = session.run([tf_loss, tf_loss_minimize], feed_dict={train_inputs: batch[0].reshape(batch_size, image_size*image_size), train_labels: batch[1], tf_learning_rate: 0.0001})
        loss_per_epoch.append(l)

    print('Average loss in epoch %d: %.5f'%(epoch, np.mean(loss_per_epoch)))    
    avg_loss = np.mean(loss_per_epoch)

    # ====================== Calculate the Validation Accuracy ==========================
    valid_accuracy_per_epoch = []
    for i in range(n_valid//batch_size):
        valid_images, valid_labels = mnist_data.validation.next_batch(batch_size)
        valid_batch_predictions = session.run(
            tf_predictions, feed_dict={train_inputs: valid_images.reshape(batch_size, image_size*image_size)})
        valid_accuracy_per_epoch.append(accuracy(valid_batch_predictions, valid_labels))

    mean_v_acc = np.mean(valid_accuracy_per_epoch)
    print('\tAverage Valid Accuracy in epoch %d: %.5f'%(epoch, np.mean(valid_accuracy_per_epoch)))

    # ===================== Calculate the Test Accuracy ===============================
    accuracy_per_epoch = []
    for i in range(n_test//batch_size):
        test_images, test_labels = mnist_data.test.next_batch(batch_size)
        test_batch_predictions = session.run(
            tf_predictions, feed_dict={train_inputs: test_images.reshape(batch_size, image_size*image_size)}
        )
        accuracy_per_epoch.append(accuracy(test_batch_predictions, test_labels))

    print('\tAverage Test Accuracy in epoch %d: %.5f\n'%(epoch, np.mean(accuracy_per_epoch)))
    avg_test_accuracy = np.mean(accuracy_per_epoch)

    # Execute the summaries defined above
    summ = session.run(performance_summaries, feed_dict={tf_loss_ph:avg_loss, tf_accuracy_ph:avg_test_accuracy})

    # Write the obtained summaries to the file, so it can be displayed in the TensorBoard
    summ_writer.add_summary(summ, epoch)

session.close()
Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes.
Extracting MNIST_data/train-images-idx3-ubyte.gz
Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes.
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes.
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes.
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
Average loss in epoch 0: 2.30252
    Average Valid Accuracy in epoch 0: 10.02000
    Average Test Accuracy in epoch 0: 9.76000

Average loss in epoch 1: 2.30016
    Average Valid Accuracy in epoch 1: 12.56000
    Average Test Accuracy in epoch 1: 12.64000

  ...
  ...
  ...

Average loss in epoch 24: 1.03386
    Average Valid Accuracy in epoch 24: 71.88000
    Average Test Accuracy in epoch 24: 71.23000

可视化计算图

首先, 你将看到模型的计算图。你可以通过在TensorBoard中单击Graphs视图来访问此视图。它看起来应如下图所示。你会看到, 从train_inputs到损失, 以及预测流经隐藏的第1层到第5层, 流程都很好。

TensorBoard教程1

可视化摘要数据

MNIST分类是最简单的示例之一, 但仍然无法使用5层神经网络解决。对于MNIST, 在不到5个时间段内达到90%以上的精度并不困难。

那么这是怎么回事?

让我们来看看TensorBoard:

TensorBoard教程2

观察与结论

你可以看到准确性正在提高, 但是非常缓慢, 并且梯度更新随着时间的推移而增加。这是一个奇怪的行为。如果你趋向于趋同, 则应该看到渐变减小(接近零)而不是增大。但是, 由于准确性不断提高, 因此你在正确的道路上。你可能需要更高的学习率。

你现在可以尝试0.01的学习率。除了将使用0.01而不是0.0001之外, 这与神经网络的先前执行几乎相同。代替tf_learning_rate:0.0001, 使用tf_learning_rate:0.01。请注意, 有两个实例需要替换参数。

TensorBoard的第二眼:现在看起来好多了

现在你可以看到精度开始接近100并继续上升。你会看到渐变更新也随着时间的推移而逐渐减少, 并接近零。学习速率为0.01时, 情况似乎要好得多。

TensorBoard教程3

接下来, 让我们超越标量。你将看到如何分析标量向量和标量集合。

超越标量:直观显示直方图/分布

你已经看到了通过TensorBoard可视化标量的好处, 这使你可以查看模型的行为并修复模型的任何潜在问题。此外, 通过可视化图形, 你可以看到输入到预测之间存在不间断的链接, 这对于梯度计算是必需的。

现在, 你将在TensorBoard中看到另一个有用的视图;直方图或分布。

请记住, 直方图是由值在集合中具有的频率/密度表示的值的集合。你可以使用直方图直观显示一段时间内的网络权重值。可视化网络权重很重要, 因为如果权重在学习过程中到处乱跳, 则表明权重初始化或学习速率有问题。

你将在示例中看到权重如何变化。如果你看一下代码, 它将使用truncated_normal_initializer()初始化权重。

定义直方图摘要以可视化权重和偏差

在这里, 你再次定义tf.summary对象。但是, 现在你正在可视化标量向量, 因此需要定义tf.summary.histogram对象。

在这种情况下, 你定义两个直方图对象(即tf_w_hist和tf_b_hist), 它们包含给定图层的权重和偏差。你将为所有图层定义此类直方图对象, 并且每个图层将具有自己的名称范围。

最后, 你可以使用tf.summary.merge操作创建一个分组操作, 该操作一次执行所有这些摘要。

# Summaries need to be displayed
# Create a summary for each weight bias in each layer
all_summaries = []
for lid in layer_ids:
    with tf.name_scope(lid+'_hist'):
        with tf.variable_scope(lid, reuse=True):
            w, b = tf.get_variable('weights'), tf.get_variable('bias')

            # Create a scalar summary object for the loss so it can be displayed
            tf_w_hist = tf.summary.histogram('weights_hist', tf.reshape(w, [-1]))
            tf_b_hist = tf.summary.histogram('bias_hist', b)
            all_summaries.extend([tf_w_hist, tf_b_hist])

# Merge all parameter histogram summaries together
tf_param_summaries = tf.summary.merge(all_summaries)

执行神经网络(带有直方图摘要)

此步骤几乎与你之前执行的步骤相同, 但是在这里, 你几乎没有其他几行可以计算直方图摘要(即tf_param_summaries)。

注意学习率也再次改变。

image_size = 28
n_channels = 1
n_classes = 10
n_train = 55000
n_valid = 5000
n_test = 10000
n_epochs = 25

config = tf.ConfigProto(allow_soft_placement=True)
config.gpu_options.allow_growth = True
config.gpu_options.per_process_gpu_memory_fraction = 0.9 # making sure Tensorflow doesn't overflow the GPU

session = tf.InteractiveSession(config=config)

if not os.path.exists('summaries'):
    os.mkdir('summaries')
if not os.path.exists(os.path.join('summaries', 'third')):
    os.mkdir(os.path.join('summaries', 'third'))

summ_writer_3 = tf.summary.FileWriter(os.path.join('summaries', 'third'), session.graph)

tf.global_variables_initializer().run()

accuracy_per_epoch = []
mnist_data = input_data.read_data_sets('MNIST_data', one_hot=True)


for epoch in range(n_epochs):
    loss_per_epoch = []
    for i in range(n_train//batch_size):

        # =================================== Training for one step ========================================
        batch = mnist_data.train.next_batch(batch_size)    # Get one batch of training data
        if i == 0:
            # Only for the first epoch, get the summary data
            # Otherwise, it can clutter the visualization
            l, _, gn_summ, wb_summ = session.run([tf_loss, tf_loss_minimize, tf_gradnorm_summary, tf_param_summaries], feed_dict={train_inputs: batch[0].reshape(batch_size, image_size*image_size), train_labels: batch[1], tf_learning_rate: 0.00001})
            summ_writer_3.add_summary(gn_summ, epoch)
            summ_writer_3.add_summary(wb_summ, epoch)
        else:
            # Optimize with training data
            l, _ = session.run([tf_loss, tf_loss_minimize], feed_dict={train_inputs: batch[0].reshape(batch_size, image_size*image_size), train_labels: batch[1], tf_learning_rate: 0.01})
        loss_per_epoch.append(l)

    print('Average loss in epoch %d: %.5f'%(epoch, np.mean(loss_per_epoch)))    
    avg_loss = np.mean(loss_per_epoch)

    # ====================== Calculate the Validation Accuracy ==========================
    valid_accuracy_per_epoch = []
    for i in range(n_valid//batch_size):
        valid_images, valid_labels = mnist_data.validation.next_batch(batch_size)
        valid_batch_predictions = session.run(
            tf_predictions, feed_dict={train_inputs: valid_images.reshape(batch_size, image_size*image_size)})
        valid_accuracy_per_epoch.append(accuracy(valid_batch_predictions, valid_labels))

    mean_v_acc = np.mean(valid_accuracy_per_epoch)
    print('\tAverage Valid Accuracy in epoch %d: %.5f'%(epoch, np.mean(valid_accuracy_per_epoch)))

    # ===================== Calculate the Test Accuracy ===============================
    accuracy_per_epoch = []
    for i in range(n_test//batch_size):
        test_images, test_labels = mnist_data.test.next_batch(batch_size)
        test_batch_predictions = session.run(
            tf_predictions, feed_dict={train_inputs: test_images.reshape(batch_size, image_size*image_size)}
        )
        accuracy_per_epoch.append(accuracy(test_batch_predictions, test_labels))

    print('\tAverage Test Accuracy in epoch %d: %.5f\n'%(epoch, np.mean(accuracy_per_epoch)))
    avg_test_accuracy = np.mean(accuracy_per_epoch)

    # Execute the summaries defined above
    summ = session.run(performance_summaries, feed_dict={tf_loss_ph:avg_loss, tf_accuracy_ph:avg_test_accuracy})

    # Write the obtained summaries to the file, so they can be displayed
    summ_writer_3.add_summary(summ, epoch)

session.close()
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
Average loss in epoch 0: 1.02625
    Average Valid Accuracy in epoch 0: 92.76000
    Average Test Accuracy in epoch 0: 92.65000

Average loss in epoch 1: 0.19110
    Average Valid Accuracy in epoch 1: 95.80000
    Average Test Accuracy in epoch 1: 95.48000

  ...
  ...
  ...

Average loss in epoch 24: 0.00009
    Average Valid Accuracy in epoch 24: 98.28000
    Average Test Accuracy in epoch 24: 98.09000

可视化权重和偏差的直方图数据

这就是你的体重和偏见。首先, 你有3个轴;时间(x轴), 值(y轴)和值的频率/密度(z轴)。较深的直方图表示较旧的数据, 较浅的直方图表示较新的数据。 z轴上的值越高, 表示向量包含的值越接近该特定值。

注意:随着时间的推移, 你还具有直方图的”叠加”视图。你可以在左侧选项面板上更改显示类型。

TensorBoard教程4
TensorBoard教程5
TensorBoard教程6

不同初始化程序的影响

现在, 你将使用xavier_initializer()来初始化权重, 而不是使用truncated_normal_initializer()。 Xavier初始化是一种更好的初始化技术, 尤其是对于深度神经网络。

这是因为Xavier初始化不是使用用户定义的标准偏差(就像使用truncated_normal_initializer()时那样), 而是根据与图层的输入和输出连接数自动确定标准偏差。这有助于从上到下流动渐变, 而不会出现渐变消失等问题。然后, 你再次定义模型。

首先, 你定义一个batch_size, 表示在单个优化/验证或测试步骤中采样的数据量。然后, 你可以定义layer_id, 为要定义的神经网络的每个层提供一个标识符。

然后, 你可以定义layer_sizes。请注意, len(layer_sizes)应该为len(layer_ids)+1, 因为layer_sizes包括开头的输入大小。 MNIST的图像尺寸为28×28, 展开为单个尺寸时将为784。

然后, 你可以定义输入和标签占位符, 稍后将使用它们来训练模型。最后, 为每个图层定义两个TensorFlow变量(即权重和偏差)。

注意:除了权重使用的初始化技术外, 这与你初次使用的代码相同

batch_size = 100
layer_ids = ['hidden1', 'hidden2', 'hidden3', 'hidden4', 'hidden5', 'out']
layer_sizes = [784, 500, 400, 300, 200, 100, 10]

tf.reset_default_graph()

# Inputs and Labels
train_inputs = tf.placeholder(tf.float32, shape=[batch_size, layer_sizes[0]], name='train_inputs')
train_labels = tf.placeholder(tf.float32, shape=[batch_size, layer_sizes[-1]], name='train_labels')

# Weight and Bias definitions
for idx, lid in enumerate(layer_ids):

    with tf.variable_scope(lid):
        w = tf.get_variable('weights', shape=[layer_sizes[idx], layer_sizes[idx+1]], initializer=tf.contrib.layers.xavier_initializer())
        b = tf.get_variable('bias', shape= [layer_sizes[idx+1]], initializer=tf.random_uniform_initializer(-0.1, 0.1))

计算Logit, 预测, 损失和优化

定义了每个层的输入/输出占位符, 权重和偏差后, 你现在可以定义计算以再次计算神经网络的对数。

注意:这部分与你首次定义这些操作和张量时使用的代码相同。

定义摘要

在这里你可以再次定义tf.summary对象。这也与你首次定义这些操作和张量时使用的代码相同。

直方图摘要:可视化权重和偏差

在这里, 你再次定义tf.summary对象。但是, 现在你正在可视化标量向量, 因此需要定义tf.summary.histogram对象。

请注意, 这与你首次定义这些操作和张量时使用的代码相同。

执行神经网络

请注意, 这与上一节中所做的相同!

只需更改少量代码即可:将os.path.join(‘summaries’, ‘third’)的三个出现更改为os.path.join(‘summaries’, ‘fourth’), 将summ_writer_3更改为summ_writer_4(出现4次), 并且必须将0.00001的tf_learning_rate设置为0.01。


image_size = 28
n_channels = 1
n_classes = 10
n_train = 55000
n_valid = 5000
n_test = 10000
n_epochs = 25

config = tf.ConfigProto(allow_soft_placement=True)
config.gpu_options.allow_growth = True
config.gpu_options.per_process_gpu_memory_fraction = 0.9 # making sure TensorFlow doesn't overflow the GPU

session = tf.InteractiveSession(config=config)

if not os.path.exists('summaries'):
    os.mkdir('summaries')
if not os.path.exists(os.path.join('summaries', 'fourth')):
    os.mkdir(os.path.join('summaries', 'fourth'))

summ_writer_4 = tf.summary.FileWriter(os.path.join('summaries', 'fourth'), session.graph)

tf.global_variables_initializer().run()

accuracy_per_epoch = []
mnist_data = input_data.read_data_sets('MNIST_data', one_hot=True)


for epoch in range(n_epochs):
    loss_per_epoch = []
    for i in range(n_train//batch_size):

        # =================================== Training for one step ========================================
        batch = mnist_data.train.next_batch(batch_size)    # Get one batch of training data
        if i == 0:
            # Only for the first epoch, get the summary data
            # Otherwise, it can clutter the visualization
            l, _, gn_summ, wb_summ = session.run([tf_loss, tf_loss_minimize, tf_gradnorm_summary, tf_param_summaries], feed_dict={train_inputs: batch[0].reshape(batch_size, image_size*image_size), train_labels: batch[1], tf_learning_rate: 0.01})
            summ_writer_4.add_summary(gn_summ, epoch)
            summ_writer_4.add_summary(wb_summ, epoch)
        else:
            # Optimize with training data
            l, _ = session.run([tf_loss, tf_loss_minimize], feed_dict={train_inputs: batch[0].reshape(batch_size, image_size*image_size), train_labels: batch[1], tf_learning_rate: 0.01})
        loss_per_epoch.append(l)

    print('Average loss in epoch %d: %.5f'%(epoch, np.mean(loss_per_epoch)))    
    avg_loss = np.mean(loss_per_epoch)

    # ====================== Calculate the Validation Accuracy ==========================
    valid_accuracy_per_epoch = []
    for i in range(n_valid//batch_size):
        valid_images, valid_labels = mnist_data.validation.next_batch(batch_size)
        valid_batch_predictions = session.run(
            tf_predictions, feed_dict={train_inputs: valid_images.reshape(batch_size, image_size*image_size)})
        valid_accuracy_per_epoch.append(accuracy(valid_batch_predictions, valid_labels))

    mean_v_acc = np.mean(valid_accuracy_per_epoch)
    print('\tAverage Valid Accuracy in epoch %d: %.5f'%(epoch, np.mean(valid_accuracy_per_epoch)))

    # ===================== Calculate the Test Accuracy ===============================
    accuracy_per_epoch = []
    for i in range(n_test//batch_size):
        test_images, test_labels = mnist_data.test.next_batch(batch_size)
        test_batch_predictions = session.run(
            tf_predictions, feed_dict={train_inputs: test_images.reshape(batch_size, image_size*image_size)}
        )
        accuracy_per_epoch.append(accuracy(test_batch_predictions, test_labels))

    print('\tAverage Test Accuracy in epoch %d: %.5f\n'%(epoch, np.mean(accuracy_per_epoch)))
    avg_test_accuracy = np.mean(accuracy_per_epoch)

    # Execute the summaries defined above
    summ = session.run(performance_summaries, feed_dict={tf_loss_ph:avg_loss, tf_accuracy_ph:avg_test_accuracy})

    # Write the obtained summaries to the file, so they can be displayed
    summ_writer_4.add_summary(summ, epoch)

session.close()
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
Average loss in epoch 0: 0.43618
    Average Valid Accuracy in epoch 0: 95.70000
    Average Test Accuracy in epoch 0: 95.22000

Average loss in epoch 1: 0.12872
    Average Valid Accuracy in epoch 1: 96.86000
    Average Test Accuracy in epoch 1: 96.71000

  ...
  ...
  ...

Average loss in epoch 24: 0.00009
    Average Valid Accuracy in epoch 24: 98.42000
    Average Test Accuracy in epoch 24: 98.21000

如何比较不同的初始化技术

在这里, 你可以比较两种不同初始化的权重随时间变化的方式; truncated_normal_initializer(红色)和xavier_initializer(蓝色)。你可以看到xavier_initializer比普通的初始化程序使零的权重更大, 这是更好的选择。这可能使Xavier初始化的神经网络收敛得更快, 这从损耗/精度曲线可以明显看出。

TensorBoard教程7

直方图的分布图

现在, 你可以比较两个视图之间的差异。直方图视图和分布视图。分布视图本质上是查看直方图的另一种方式。如果查看下面的图像, 你可以轻松地看到分布视图是直方图视图的顶视图。注意, 在这种情况下旋转直方图可以很容易地看到相似之处。

TensorBoard教程8

总结

在本教程中, 你了解了如何使用TensorBoard。首先, 你学习了如何通过命令提示符(Windows)或终端(Ubuntu / Mac)启动其服务。接下来, 你查看了TensorBoard提供的数据的不同视图。然后, 你查看了可视化标量值(例如, 损耗/准确性)的代码, 并使用前馈神经网络模型具体了解了标量值可视化的用法。

此后, 你探索了如何使用直方图视图可视化标量的集合/向量。然后进行比较, 以突出显示使用直方图视图的神经网络权重初始化技术之间的差异。

最后, 你讨论了分布视图和直方图视图之间的相似之处。

如果你想了解有关深度学习的更多信息, 请务必查看我们的Keras深度学习课程。

如果你想与我联系, 可以给我发送电子邮件至sothhv@gmail.com或通过LinkedIn与我联系。

赞(0)
未经允许不得转载:srcmini » TensorBoard精品开发教程

评论 抢沙发

评论前必须登录!