利用Tensorboard可视化模型、数据和训练过程

60分钟闪电战中,我们像你展示了如何加载数据,通过为我们定义的 nn.Module的子类的model提供数据,在训练集上训练模型,在测试集上测试模型。为了了解发生了什么,我们在模型训练时打印了一些统计数据,以观察训练是否正在进行。但是,我们可以做的比这更好:PyTorch和TensorBoard的集成,是一个用来可视化神经网络运行结果的工具。本教程使用Fashion-MNIST数据集说明它的一些功能,该数据集可以使用 torchvision.datasets读到Pytorch中。

在本教程中,我们会学习如何:

  • 读入数据,并进行适当的转换(几乎与之前的教程的相同)
  • 设置TensorBoard
  • 写入TensorBoard
  • 使用TensorBoard检查模型架构
  • 使用TensorBoard和更少的代码创建上一教程中可视化的交互式版本

特别是第5点,我们会看到:

  • 检查训练数据的几种方法
  • 如何在训练时跟踪模型的性能
  • 训练后如何评估模型性能

我们将从CIFAR-10教程中类似的样例代码开始:

imports
import matplotlib.pyplot as plt
import numpy as np

import torch
import torchvision
import torchvision.transform as transform

import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

transforms
transform = transforms.Compose(
    [transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))]
)

datasets
trainset = torchvision.datasets.FashionMNIST('./data',
    download=True,
    train=True,
    transform=transform)
testset = torchvision.datasets.FashionMNIST('./data',
    download=True,
    train=False,
    transform=transform)

dataloaders
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                        shuffle=True, num_workers=2)

testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                        shuffle=False, num_workers=2)

constant for classes
classes = ('T-shirt/torp', 'Trouser', 'Pullover', 'Dress', 'Coat',
        'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle Boot')

显示单张图片的辅助函数
(在下面的'plot_classes_preds'函数会使用)
def matplotlib_imshow(img, one_channel=False):
    if one_channel:
        img = img.mean(dim=0)
    img = img / 2 + 0.5 # unnormalize
    npimg = img.numpy()
    if one_channel:
        plt.imshow(npimg, cmap='Greys')
    else:
        plt.imshow(np.transpose(npimg, (1, 2, 0)))

我们将在本教程中定义一个类似的模型架构,只做一些小的修改以说明图片现在是单通道而非3通道、28 _28而非32_32。

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16*4*4, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 4 * 4)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = Net()

我们将定义同样的优化器和损失函数:

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

TensorBoard 设置

现在我们要设置TensorBoard,从 torch.utils导入 tensorboard,并定义一个 SummaryWriter,它是将信息写入TensorBoard的关键对象。

from torch.utils.tensorboard import SummaryWriter

默认的日志目录是'runs' - 在这里,我们会更加具体
writer = SummaryWriter('runs/fashion_mnist_experiment_1')

注意,此行创建了 runs/fashion_mnist_experiment_1文件夹。

写入TensorBoard

现在,让我们把一个图片写入TensorBoard – 具体来说,a grid – using make_grid

获取一些随机的训练样本
dataiter = iter(trainloader)
images, labels = dataiter.next()

创建图片网格
img_grid = torchvision.utils.make_grid(images)

show images
matplotlib_imshow(img_grid, one_channel=True)

写入TensorBoard
writer.add_image('four_fashion_mnist_images', img_grid)

运行:

tensorboard --logdir=runs

从命令行中导航到http://localhost:6006,应该会显示以下内容:

利用Tensorboard可视化模型、数据和训练过程

现在,你知道如何使用TensorBoard了!但是对于该例,Jupyter Notebook也可以做,TensorBoard真正擅长的是创建可交互的可视化界面。我们将在接下来展示其中一个,并在教程最后再介绍几个。

使用TensorBoard检查模型

TensorBoard的一个强大的功能是可视化复杂的模型结构。让我们可视化我们构建的模型

writer.add_graph(net, images)
writer.close()

现在刷新TensorBoard,你会看到’Graphs’ tab:

利用Tensorboard可视化模型、数据和训练过程

双击’Net’展开,查看构成模型的哥哥操作的详细视图。

TensorBoard有一个非常方便的功能,可以在低维空间可视化高维数据,例如图片,我们接下来会介绍这个:

为TensorBoard添加’投影’

我们可以通过add_embedding可视化高维数据的低维表示。

辅助函数
def selec_n_random(data, labels, n=100):
    '''
    从dataset中选择n个随机的数据点及其标签
    '''
    # assert用于判断一个表达式,在为True时,正常运行,为False时触发异常:AssertionError。
    assert len(data) == len(labels)

    perm = torch.randperm(len(data)) # 将0~n-1(包括0和n-1)打乱后获得的数字序列
    return data[perm][:n], labels[perm][:n]

选择随机图片及其标签索引
images, labels = select_n_random(trainset.data, trainset.targets)

获得每一个图片的类别标签
class_labels = [classes[lab] for lab in labels]

日志嵌入
features = images.view(-1, 28 * 28)
writer.add_embedding(features,
                    metadata=class_labels,
                    label_img = images.unsqueeze(1))
writer.close()

此时,在TensorBoard的’Projector’,你会看到这100个图片,每个都是784维,被投影到3维度空间。而且,这是可交互的:你可以点击和拖拽来翻转这三个维度的投影。最后,一些易于可视化的手段:选择左上角的’color:label’,还有启用’夜间模式’,这将使图像更易查看,因为它们的背景是白色的。

利用Tensorboard可视化模型、数据和训练过程

现在,我们已经彻底检查了我们的数据,让我们从训练开始,展示TensorBoard如何让跟踪模型训练和验证更清晰。

使用TensorBoard跟踪模型

在之前的例子中,我们每2000次迭代 _打印_模型的运行loss。现在,我们将把运行loss记录到TensorBoard,并通过 plot_classes_preds函数查看模型预测。

辅助函数

def images_to_probs(net, images):
    '''
    从一个训练后的模型和一系列图片生成predictions及对应的probabilities
    '''
    output = net(images)
    # 将输出的probabilities转换为预测的类别
    _, preds_tensor = torch.max(output, 1) # preds_tensor是最大值的索引
    preds = np.squeeze(preds_tensor.numpy())
    # softmax将网络输出值映射到(0, 1)
    return preds, [F.softmax(el, dim=0)[i].item() for i, el in zip(preds, output)]

def plot_classes_preds(net, images, labels):
    '''
    使用训练后的网络生成matplotlib图片,以及1个batch的图片和标签,显示网络最高的预测及概率,以及实际
    标签,根据预测是否正确为该信息着色。使用'images_to_probs'函数。
    '''
    preds, probs = images_to_probs(net, images)
    # 绘制batch中的图片、预测和真值
    fig = plt.figure(figsize=(12, 48))
    for idx in np.arange(4):
        ax = fig.add_subplot(1, 4, idx+1, xticks=[], yticks=[])
        matplotlib_imshow(images[idx], one_channel=True)
        ax.set_title("{0}, {1:.1f}%\n(label: {2})".format(
              classes[preds[idx]],
              probs[idx] * 100.0,
              classes[labels[idx]]),
                      color=('green' if preds[idx]==labels[idx].item() else 'red'))
    return fig

最后,让我们使用与之前教程中相同的训练代码训练模型,但是每1000batches将结果写入TensorBoard而不是打印到控制台;可以通过add_scalar

此外,训练时,我们将生成图片来展示模型的预测与该批次中包含的四张图片的实际结果。

running_loss = 0.0
for epoch in range(1): # 遍历数据集的次数

    for i, data in enumerate(trainloader, 0):
        # 获得输入;data是一个[inputs, labels]的列表
        inputs, labels = data

        # 将梯度置零
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
        if i % 1000 == 999: # 每1000 mini-batche
            # 记录running_loss
            writer.add_scalar('training loss',
                            running_loss / 1000,
                            epoch * len(trainloader) + i) # 第三个参数是步值(可理解为X轴)
            # 记录一个Matplotlib图片,在和一个随机的mini-batch上展示模型的预测
            writer.add_figure('predictions vs. actuals',
                            plot_classes_preds(net, inputs, labels),
                            global_step=epoch * len(trainloader) + i)
            running_loss = 0.0
print('Finished Training')

现在你可以在scalars tab看到训练15000次的运行loss被绘制出来了。

利用Tensorboard可视化模型、数据和训练过程

此外,还可以看到模型在随机的batches上通过学习得到预测。查看’Images’ tab 并在’predictions vs. actual’中向下滚动可以看到查看此内容,这表明,例如,经过3000次训练迭代,该模型已经能够区分视觉上不同的类别,例如衬衫、运动鞋和外套,尽管它不像之后的训练那么自信:

利用Tensorboard可视化模型、数据和训练过程

在之前的教程中,我们看到了模型训练后在每个类别上的准确率,现在,我们将用TensorBoard为每类绘制precision-recall曲线(关于P-R曲线)。

使用TensorBoard评估训练模型

1. 获取test_size的具有x个num_classes Tensor的概率值预测
2. 获得test_zie Tensor的预测
class_probs = []
class_label = []
with torch.no_grad():
    for data in testloader:
        images, labels = data
        output = net(images)
        class_probs_batch = [F.softmax(el, dim=0) for el in output]

        class_probs.append(class_probs_batch)
        class_label.append(labels)

test_probs = torch.cat([torch.stack(batch) for batch in class_probs])
test_label = torch.cat(class_label)

辅助函数
def add_pr_curve_tensorboard(class_idx, test_probs, test_label, globa_step=0):
    '''
    接受从0到9的‘class_index’并绘制相应的p-r曲线
    '''
    tensorboard_truth = test_label == class_index
    tensorboard_probs = test_probs[:, class_index]

    writer.add_pr_curve(classes[class_index],
                        tensorboard_truth,
                        tensorboard_probs,
                        global_step=global_step)
    writer.close()

绘制所有的pr曲线
for i in range(len(classes)):
    add_pr_curve_tensorboard(i, test_probs, test_label)

现在,你会看到’PR CURVES’包含了每一类别的pr曲线,细看之后你会发现,在一些类,模型几乎拥有曲线下100%的面积,而其它类很低:

利用Tensorboard可视化模型、数据和训练过程

这是对TensorBoard和PyTorch与其集成的介绍。当然,你可以在Jupyter Notebook中执行TensorBoard可做的所有事情,但TensorBoard默认可获得交互的视觉效果。

Original: https://www.cnblogs.com/DeepRS/p/15871843.html
Author: Deep_RS
Title: 利用Tensorboard可视化模型、数据和训练过程

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/610572/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • LeetCode-47. 全排列 II

    题目来源 题目详情 给定一个可包含重复数字的序列 nums , 按任意顺序 返回所有不重复的全排列。 示例 1: 输入: nums = [1,1,2]输出:[[1,1,2],[1,…

    Linux 2023年6月7日
    085
  • 如何在博客中添加Aplayer音乐播放器

    前言 是否有一首音乐,前奏一响起,让你灵魂不自主的颤栗。音乐就像老胶卷,每个旋律,每句歌词,都承载着每个人的往事回忆和情愫感受。 我收藏了好多的音乐,奈何好多音乐受版权限制,需要购…

    Linux 2023年6月7日
    0103
  • Vim 编辑器|批量注释与批量取消注释

    添加注释 ctrl + v 进入块选泽模式。 上下键选中需要注释的行。 按大写 I 进入插入模式,输入注释符。 按两次 ESC 退出,即完成添加注释。 取消注释 ctrl + v …

    Linux 2023年5月27日
    0109
  • Redis分布式锁的N种姿势

    Redis几种架构 Redis发展到现在,几种常见的部署架构有: 单机模式; 主从模式; 哨兵模式; 集群模式; 我们首先基于这些架构讲解Redisson普通分布式锁实现,需要注意…

    Linux 2023年5月28日
    0111
  • Kubernetes-DashBoard部署

    DashBoard 在kubernetes中完成的所有操作都是通过命令行工具kubectl完成的。其实,为了提供更丰富的用户体验,kubernetes还开发了一个基于web的用户界…

    Linux 2023年6月13日
    097
  • Vim配置文件-详解(.vimrc)

    Vim配置文件的作用 Vim启动时,会根据配置文件(.vimrc)来设置 Vim,因此我们可以通过此文件来定制适合自己的 Vim 所有系统用户在启动Vim时,都会加载这个配置文件。…

    Linux 2023年6月13日
    091
  • freePBR的UE4材质合集

    我手动下载了freepbr.com上的所有ue4材质,放到百度云上分享给大家。 freePBR的UE4材质合集 想开个新坑了。但工欲善其事必先利其器。于是我手动下载了freepbr…

    Linux 2023年6月6日
    0101
  • nginx配置文件讲解及示例(可复制)

    【示例一】 运行用户 user www-data; 启动进程,通常设置成和cpu的数量相等 worker_processes 1; 全局错误日志及PID文件 error_log /…

    Linux 2023年6月6日
    082
  • Ubuntu20.04 命令行 修改系统IP地址

    Ubuntu 修改IP地址(静态IP) 配置文件修改 — 命令行修改 ifconfig的安装及使用,ip 命令的使用 0. 前言 1. 修改配置文件 1.1 输入(修改…

    Linux 2023年6月6日
    0191
  • ES查询区分大小写

    ES查询在默认的情况下是不区分大小写的,在5.0版本之后将 string类型拆分成两种新的数据类型, text用于全文搜索(模糊搜索), keyword用于关键字搜索(精确搜索)。…

    Linux 2023年6月8日
    0109
  • ssh 或 putty 连接linux报错解决方法

    由于当天多次输入错误密码,ssh和putty就连接不上了,纠结了很久解决问题 ssh连接提示错误:server unexpectedly closed network connec…

    Linux 2023年6月13日
    099
  • 配置nginx只打印延迟超过0.1s和非2XX的accesslog

    背景 当业务accesslog全开时,写入es的qps达到了10W,评估后觉得不太值得,所以考虑抽样打印。查看相关文档后发现目前我们使用的nginx版本不支持抽样打印,所以考虑其他…

    Linux 2023年6月14日
    0115
  • Linux下PAM模块学习总结

    Linux下PAM模块学习总结 转载自 https://www.cnblogs.com/kevingrace/p/8671964.html Original: https://ww…

    Linux 2023年6月7日
    0104
  • Docker centos7,宝塔

    拉取一个centos镜像 docker pull centos:centos7 运行一个容器 docker run -i -t -d –restart=always –name…

    Linux 2023年6月6日
    099
  • SpringBoot + Vue + ElementUI 实现后台管理系统模板 — 后端篇(四): 整合阿里云 短信服务、整合 JWT 单点登录

    (1) 相关博文地址: SpringBoot + Vue + ElementUI 实现后台管理系统模板 — 前端篇(一):搭建基本环境:https://www.cnblogs.c…

    Linux 2023年6月11日
    0108
  • 银河麒麟KYLIN安装wireshark进行抓包

    银河麒麟KYLIN安装wireshark进行抓包(前提是网络连通):sudo apt-get updatesudo apt-get install wireshark -y弹出框选…

    Linux 2023年6月13日
    0125
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球