一学就会 | 基于PyTorch的TensorBoard可视化

如果觉得本篇文章对您的学习起到帮助作用,请 点赞 + 关注 + 评论 ,留下您的足迹💪💪💪

TensorBoard这款工具你是一定要掌握的可视化工具。为什么我要这么说呢?因为TensorBoard可以用来展示神经网络图、张量的指标变化、张量的分布情况等。我相信您阅读了本文,你就会了解到TensorBoard可视化工具的强大之处,让我们一起开始学习吧!阅读本文大约需要15min。
本文所使用的代码下载:
链接:https://pan.baidu.com/s/1VQNui4h_dryp7qL438ro7Q
提取码:d53v

本文相关推荐阅读:

一学就会 | PyTorch入门看这篇就够了

一学就会 | LeNet在CIFAR10数据集上的应用

全文框架

TensorBoard

简介

本文主要介绍PyTorch下TensorBoard的使用。当我们进行PyTorch进行深度学习实验时,深度神经网络就像一个黑盒子,其内部的组织、结构、以及训练过程我们很难去理解,这不便于我们构建神经网络模型。因此TensorBoard应运而生,它是一个可视化工具,它可以用来展示网络图、张量的指标变化、张量的分布情况等。在深度学习任务中,如果我们想要改善模型,则我们需要对模型的指标进行衡量。

TensorBoard提供了机器学习实验所需的可视化工具:

  1. 跟踪和可视化指标,例如损失和准确性
  2. 可视化模型图(操作和图层)
  3. 查看权重,偏差或其他张量随时间变化的直方图
  4. 将嵌入物投影到较低维度的空间
  5. 显示图像,文本和音频数据
  6. 分析深度学习框架程序(本文使用PyTorch)

TensorBoard运行机制:

  1. 在python脚本中记录要监控的数据
  2. 记录下来的内容会以event file文件的形式存放在硬盘中
  3. 在终端用tensorboard命定读取event file文件
  4. TensorBoard在Web端实现可视化

TensorBoard运行机制

下文会介绍具体操作方法。

安装TensorBoard

TensorBoard并不是与PyTorch安装包绑定在一起的,我们需要另行单独安装,安装TensorBoard其实很简单,只需要在终端输入这样操作:

(torch2) C:\Users\Administrator>pip install tensorboard

需要注意,我是在虚拟环境 torch2 中安装的TensorBoard,读者应该选择自己对应的虚拟环境。

为了提升下载速度,推荐用清华镜像下载:

(torch2) C:\Users\Administrator>pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tensorboard

TensorBoard中主要功能函数介绍

我们使用TensorBoard对数据进行可视化,必然要调用相应函数,这里我们先做简单了解,我们会在后文详细介绍。

SummaryWriter类

SummaryWriter:
SummaryWriter
功能:用来创建event file的高级接口,将event file直接写入log_dir中,以供TensorBoard使用。

主要属性:

  • log_dir:保存event file的文件夹,默认为runs文件夹
  • comment:不指定log_dir时,文件夹的后缀
  • filename_suffix:event file文件名后缀

接下来用代码演示:
1、自动生成文件夹名称并创建可视化文件

# 从torch.utils.tensorboard导入SummaryWriter类
from torch.utils.tensorboard import SummaryWriter

# 实例化这个类
writer = SummaryWriter()

我们来看一下运行结果:
summary1
我们没有指定文件夹,默认创建runs/Apr08_16-14-46_PC-202003241336文件夹,从文件夹的信息可以看出,该文件创建于4月8日16时14分46秒。保存我们可视化信息的event file文件为events.out.tfevents.1586333686.PC-202003241336.10256.0。

2、指定文件夹名称并创建可视化文件

# 从torch.utils.tensorboard导入SummaryWriter类
from torch.utils.tensorboard import SummaryWriter

# 实例化这个类
writer = SummaryWriter("logs")

我们来看一下运行结果:
summary2
这一次我们指定了文件夹,创建logs文件夹。其中保存我们可视化信息的event file文件为events.out.tfevents.1586339998.PC-202003241336.2116.0。

3、创建带有文件夹后缀的可视化文件

# 从torch.utils.tensorboard导入SummaryWriter类
from torch.utils.tensorboard import SummaryWriter

# 实例化这个类
writer = SummaryWriter(comment="Created_Sang", filename_suffix='good')

summary3
我们没有指定文件夹,默认创建runs/Apr08_18-50-38_PC-202003241336Created_Sang文件夹,同时,文件夹末尾增加了Created_Sang,源于参数comment=“Created_Sang”,从文件夹的信息可以看出,该文件创建于4月8日18时50分38秒。保存我们可视化信息的event file文件为events.out.tfevents.1586343038.PC-202003241336.4980.0good。同样文件末尾增加了good,源于参数filename_suffix=‘good’。

SummaryWriter类的方法

add_scalar()方法:

scalar
功能:记录标量
主要属性:

  • tag:图像的标签名,图的唯一标识
  • scalar_value:要记录的标量,相当于图像的y轴
  • global_step:要记录的全局步长值

接下来用代码演示用法:

# 从torch.utils.tensorboard导入SummaryWriter类
from torch.utils.tensorboard import SummaryWriter

# 实例化这个类
writer = SummaryWriter(log_dir="logs")

x = range(100)
for i in x:
    writer.add_scalar('y=2x', i * 2, i)
writer.close()

执行完后创建了runs文件夹:
summary4
在终端执行命令:
我们在PyCharm的Terminal执行命令:tensorboard>tensorboard --logdir=text4/logs

(torch2) F:\pycharm_project\tensorboard>tensorboard --logdir=text4/logs

–logdir=text4/logs用于指定文件夹。

如下图:
Teminal
接下来我们可以点击 http://localhost:6006/或者复制链接到浏览器,都可以在Web端打开TensorBoard可视化界面。

如下图:
board1
可视化界面提供以下主要功能:

  • Show data download links:可下载CSV、JSON类型的数据
  • Ignore outliers in chart scaling:选中此功能将会更合理的显示数据
  • Smoothing:平滑处理
  • Tooltip sorting method:一般选择default即可
  • Horizontal Axis:一般默认选择STEP
add_scalars()方法

scalars
功能:记录多个标量
主要属性:

  • main_tag:可视化图像总的标签
  • scalar_dict:以字典的形式存取,key是变量的tag,value是变量的值
  • global_step:要记录的全局步长值

接下来用代码演示用法:

# 从torch.utils.tensorboard导入SummaryWriter类
from torch.utils.tensorboard import SummaryWriter
import numpy as np

# 实例化这个类
writer = SummaryWriter(log_dir="logs")

r = 5
x = range(100)
for i in x:
	# 多个数据时,以字典形式存取
    writer.add_scalars('run_14h', {'xsinx':i*np.sin(i/r),
                                    'xcosx':i*np.cos(i/r),
                                    'tanx': np.tan(i/r)}, i)
writer.close()

显示结果如下:
board2
大多数功能前文已经介绍,这里需要特别说明的是Write a regex to filter runs这一选项,可以控制单独显示某一项、某两项或者显示全部的数据。

add_histogram()方法

histogram
功能:统计直方图与多分位数折线图

主要属性:

  • tag:可视化图像标签名
  • values:建立直方图的值
  • global_step:驼峰的个数,y轴(注意,不同于前文的x轴)
  • bins:一般默认值即可

接下来用代码演示用法:

# 从torch.utils.tensorboard导入SummaryWriter类
from torch.utils.tensorboard import SummaryWriter
import numpy as np

writer = SummaryWriter("logs")
for i in range(15):
    x = np.random.random(1000)
    writer.add_histogram('histogram', x + i, i)
writer.close()

显示结果如下:
board3
for循环了15次,即显示15个驼峰,global_step参数的数值即是每个驼峰对应于y轴的数值。可以看到第12个驼峰,y轴对应11(不要忘记我们计数是0-14)。x轴对应的11.7在直方图显示为468,这说明数值11.7有468个。

多分位数折线图显示如下:
多分位数折线图

add_image()方法

image
功能:记录图像

主要属性:

  • tag:图像的标签名
  • img_tensor:图像数据
  • global_step:要记录的全局步长值
  • dataformats:数据形式,如CHW,HWC,HW,默认(3, H, W)

接下来用代码演示用法:

# 从torch.utils.tensorboard导入SummaryWriter类
from torch.utils.tensorboard import SummaryWriter
import numpy as np

img0 = np.random.randn((3, 100, 100))

img1 = np.zeros((3, 100, 100))

img2 = np.ones((100, 100, 3))

writer = SummaryWriter("logs")

writer.add_image('img0', img0, 0)
writer.add_image('img1', img1, 1)
writer.add_image("img2", img2, 2, dataformats='HWC')

writer.close()

显示结果如下:
img
img0为随机噪音图像,dataformats为默认的“CHW”。img1像素值全为1,dataformats为默认的“CHW”,所以显示为全黑的图像。img2像素全为0,img2为(100, 100, 3),所以在显示图像时,dataformats应该选择dataformats=‘HWC’,即图像的通道放在了图像的最后。

add_images()方法

images
功能:记录一批图像数据

主要属性:

  • tag:图像的标签名
  • img_tensor:图像数据
  • global_step:要记录的全局步长值
  • dataformats:数据形式,如NCHW,NHWC,CHW等,默认(N, 3, H, W)

接下来用代码演示用法:

# 从torch.utils.tensorboard导入SummaryWriter类
from torch.utils.tensorboard import SummaryWriter
import torch

'''
创建三张颜色不同的图片
'''
img0 = torch.ones((1, 3, 100, 100))
img0[0, 0] = torch.tensor(255)     

img1 = torch.ones((1, 3, 100, 100))
img1[0, 1] = torch.tensor(255)     

img2 = torch.ones((1, 3, 100, 100))
img2[0, 2] = torch.tensor(255)     

# 三张图片拼接成(3, 3, 100, 100)
images = torch.cat((img0, img1, img2),dim=0)

writer = SummaryWriter("logs")
writer.add_images('images', images, 0)
writer.close()

显示结果如下:
images
我们将三张不同颜色的图片img0,img1,img2组合成一个批次,即可使用add_images()方法一起显示出来。

add_graph()方法

graph
功能:可视化模型计算图,用来观测构建神经网络的结构

主要参数:

  • model:模型,必须继承于nn.Module
  • input_to_model:输入给模型的数据
  • verbose:是否打印计算图结构信息

接下来用代码演示用法:

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

# 模拟出入数据
# 批次为4的1*28*28数据
input = torch.randn(4,1,28,28)

# 构建继承于nn.Module的卷积神经网络
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()

# 从torch.utils.tensorboard导入SummaryWriter类
from torch.utils.tensorboard import SummaryWriter

# 实例化并建立'logs'文件夹,用于保存event file
writer = SummaryWriter('logs')
writer.add_graph(net, input)
writer.close()

显示结果如下:
graph
通过TensorBoard可视化,我们构建的卷积神经网络结构一下子就一目了然了,我们构建的神经网络不在是一个抽象的模型,而是一个实实在在的线路图。

实用工具torchsummary

PyTorch中的torchsummary类似于Keras中的model.summary()。这一个简洁的API可以使模型可视化,这在调试网络时非常有帮助。

使用清华镜像下载安装torchsummary:

(torch2) F:\pycharm_project\tensorboard>pip install -i https://pypi.tuna.tsinghua.edu.cn/simple torchsummary

此功能的使用非常简答,只需要两行代码:
torchsummary
torchsummary主要参数:

  • model:pytorch模型
  • input_size:模型输入size,注意C、H、W顺序
  • batch_size:一般不用设置,默认即可
  • device:“cuda” 或 “cpu”,一般加上参数 device=“cpu” 或 device=“cuda”

torchsummary详情请参考Github文档

我们使用介绍add_graph()方法时创建的神经网络演示:

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

# 构建继承于nn.Module的卷积神经网络
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()

from torchsummary import summary
summary(net, input_size=(1, 28, 28),device="cpu")

输出模型信息如下:
model_information
从输出打印的模型信息可以看出,各个卷积层,线性层输出的维度以及参数的数量。
本例总的参数为44426个,可训练的参数也为44426个,参数占用内存为0.17M。

使用TensorBoard跟踪模型训练

我们构建卷积神经网络,监控损失函数loss和准确率accuracy。
PyTorch如何构建神经网络请参考一学就会 | PyTorch入门看这篇就够了
我们所使用的代码,大多来自于这篇博客,如果有问题,请进行查看。

我们对训练集和验证集的Loss和Accuracy每一个epoch检测一次,epoch值为100,即模型训练了100次。

1、加载MNIST手写数字集

from pathlib import Path
import pickle
import gzip

PATH = Path("F:\OfficialData\mnist\mnist.pkl.gz")

with gzip.open(PATH.as_posix(), "rb") as f:
        ((x_train, y_train), (x_valid, y_valid), _) = pickle.load(f, encoding="latin-1")

2、将数据转换成PyTorch可用的Tensor张量类型

import torch

x_train,y_train, x_valid, y_valid= map(torch.tensor,
                                       (x_train, y_train, x_valid, y_valid))

3、使用DataLoader、TensorDataset处理数据

bs = 64	# 一个批次大小为64

from torch.utils.data import TensorDataset, DataLoader

train_ds = TensorDataset(x_train, y_train)
train_dl = DataLoader(train_ds, batch_size=bs, shuffle=True)

valid_ds = TensorDataset(x_valid, y_valid)
valid_dl = DataLoader(valid_ds, batch_size=bs * 2)

3、构建神经网络模型并实例化

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

class Mnist_model(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(784, 500)
        self.fc2 = nn.Linear(500, 200)
        self.fc3 = nn.Linear(200, 10)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

model = Mnist_model()

4、构建损失函数和优化器

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.5)

5、计算准确率的函数

def accuracy(out, yb):
    preds = torch.argmax(out, dim=1)
    return (preds == yb).float().mean()
def accuracy_rate(model, valid_dl):
    acc = 0
    for xb, yb in valid_dl:
        acc += accuracy(model(xb), yb)

    return (acc / len(valid_dl))

6、加载TensorBoard,并实例化,创建文件夹logs

from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('logs')

7、绘制训练和验证Loss对比图,绘制训练和验证Accuracy对比图

epochs = 100
training_loss = 0
validing_loss = 0
for epoch in range(epochs):
    for data in train_dl:
        xb, yb = data
        pred = model(xb)
        loss = criterion(pred, yb)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        training_loss += loss.item()


    for data_valid in valid_dl:
        xv, yv = data_valid
        pred_valid = model(xv)
        loss_valid = criterion(pred_valid, yv)

        validing_loss += loss_valid
    writer.add_scalars('Train-Valid Loss',
                      {'Train Loss':training_loss / len(train_dl),
                       'Valid Loss':validing_loss / len(train_dl)}, epoch)

    training_loss = 0
    validing_loss = 0

    writer.add_scalars('Train-Valid Accuracy',
                       {'Train Accuracy': accuracy_rate(model, train_dl).item(),
                        'Valid Accuracy': accuracy_rate(model, valid_dl).item()}, epoch)

# 关闭writer实例
writer.close()

运行结果图如下:
Train-Valid Loss
蓝色的线为训练集loss值,红色的线为验证集loss的值。我们可以看出,Loss在训练集上的值更小,说明该模型在全新的数据面前表现可能不是很好,但是我们先不用担心,我们还要检测Accuracy的曲线对比图。
Train-Valid Accuracy
蓝色的线为训练集Accuracy值,红色的线为验证集Accuracy的值。如图我们可以看到,训练集的识别准确率是高于验证集的。验证集上的表现虽然没有训练集好,但是也有98.32%的准确率,这已经是一个很好的结果了。

总结

作者认为使用TensorBoard绘制可视化图像,是比使用matplotlib绘制图像更加方便的,它提供的功能可以满足我们对于模型监控的一般任务。

通常使用TensorBoard有三个步骤:

  1. 加载SummaryWriter类,并实例化
  2. 使用相应可视化方法,在指定文件夹生成一个或多个事件文件(event files)
  3. 启动TensorBoard的Web服务器

如果您觉得这篇文章对你有帮助,记得 点赞 + 关注 + 评论 三连,您只需动一动手指,将会鼓励我创作出更好的文章,快留下你的足迹吧💪💪💪

  • 17
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值