当前位置: 首页 > news >正文

【深入浅出PyTorch】--7.2.PyTorch可视化2

目录

3.TensorBoard--可视化训练过程

3.1.TensorBoard--基本逻辑

3.2.TensorBoard-配置与启动

3.3.TensorBoard--模型结构可视化

3.4.TensorBoard--图像可视化

3.5.TensorBoard--连续变量可视化

3.6.TensorBoard--参数分布可视化

3.7.服务器端使用TensorBoard

3.8.总结

4.wandb--可视化训练过程

4.1.wandb的安装

4.2.wandb的使用

4.3.wandb的demo演示


3.TensorBoard--可视化训练过程

训练过程的可视化在深度学习模型训练中扮演着重要的角色。学习的过程是一个优化的过程,我们需要找到最优的点作为训练过程的输出产物。一般来说,我们会结合训练集的损失函数和验证集的损失函数,绘制两条损失函数的曲线来确定训练的终点,找到对应的模型用于测试。那么除了记录训练中每个epoch的loss值,能否实时观察损失函数曲线的变化,及时捕捉模型的变化呢?

此外,我们也希望可视化其他内容,如输入数据(尤其是图片)、模型结构、参数分布等,这些对于我们在debug中查找问题来源非常重要(比如输入数据和我们想象的是否一致)。

TensorBoard作为一款可视化工具能够满足上面提到的各种需求。TensorBoard由TensorFlow团队开发,最早和TensorFlow配合使用,后来广泛应用于各种深度学习框架的可视化中来。本节我们探索TensorBoard的强大功能,希望帮助读者“从入门到精通”。

经过本节的学习,你将收获:

  • 安装TensorBoard工具

  • 了解TensorBoard可视化的基本逻辑

  • 掌握利用TensorBoard实现训练过程可视化

  • 掌握利用TensorBoard完成其他内容的可视化

3.1.TensorBoard--基本逻辑

我们可以将TensorBoard看做一个记录员,它可以记录我们指定的数据,包括模型每一层的feature map,权重,以及训练loss等等。TensorBoard将记录下来的内容保存在一个用户指定的文件夹里,程序不断运行中TensorBoard会不断记录。记录下的内容可以通过网页的形式加以可视化。

3.2.TensorBoard-配置与启动

在使用TensorBoard前,我们需要先指定一个文件夹供TensorBoard保存记录下来的数据。然后调用tensorboard中的SummaryWriter作为上述“记录员”

from tensorboardX import SummaryWriterwriter = SummaryWriter('./runs')

上面的操作实例化SummaryWritter为变量writer,并指定writer的输出目录为当前目录下的"runs"目录。也就是说,之后tensorboard记录下来的内容都会保存在runs。

如果使用PyTorch自带的tensorboard,则采用如下方式import:

from torch.utils.tensorboard import SummaryWriter

启动tensorboard也很简单,在命令行中输入

tensorboard --logdir=/path/to/logs/ --port=xxxx
  • “path/to/logs/"是指定的保存tensorboard记录结果的文件路径(等价于上面的“./runs",
  • port是外部访问TensorBoard的端口号,可以通过访问ip:port访问tensorboard,这一操作和jupyter notebook的使用类似。如果不是在服务器远程使用的话则不需要配置port。

有时,为了tensorboard能够不断地在后台运行,也可以使用nohup命令或者tmux工具来运行tensorboard。大家可以自行搜索,这里不展开讨论了。

下面,我们将模拟深度学习模型训练过程,来介绍如何利用TensorBoard可视化其中的各个部分。

3.3.TensorBoard--模型结构可视化

首先定义模型:

import torch.nn as nnclass Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(in_channels=3,out_channels=32,kernel_size = 3)self.pool = nn.MaxPool2d(kernel_size = 2,stride = 2)self.conv2 = nn.Conv2d(in_channels=32,out_channels=64,kernel_size = 5)self.adaptive_pool = nn.AdaptiveMaxPool2d((1,1))self.flatten = nn.Flatten()self.linear1 = nn.Linear(64,32)self.relu = nn.ReLU()self.linear2 = nn.Linear(32,1)self.sigmoid = nn.Sigmoid()def forward(self,x):x = self.conv1(x)x = self.pool(x)x = self.conv2(x)x = self.pool(x)x = self.adaptive_pool(x)x = self.flatten(x)x = self.linear1(x)x = self.relu(x)x = self.linear2(x)y = self.sigmoid(x)return ymodel = Net()
print(model)

可视化模型的思路和7.1中介绍的方法一样,都是给定一个输入数据,前向传播后得到模型的结构,再通过TensorBoard进行可视化,使用add_graph:

import torchwriter.add_graph(model, input_to_model = torch.rand(1, 3, 224, 224))
writer.close()

把生成的文件拖到英文路径下:改名为11,

路径不要带中文字符否者报错,加载的是绝对路径

python -m tensorboard.main --logdir=./test --host=0.0.0.0 --port=6006

http://0.0.0.0:6006/

3.4.TensorBoard--图像可视化

当我们做图像相关的任务时,可以方便地将所处理的图片在tensorboard中进行可视化展示。

  • 对于单张图片的显示使用add_image

  • 对于多张图片的显示使用add_images

  • 有时需要使用torchvision.utils.make_grid将多张图片拼成一张图片后,用writer.add_image显示

这里我们使用torchvision的CIFAR10数据集为例:

import torchvision
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
from tensorboardX import SummaryWritertransform_train = transforms.Compose([transforms.ToTensor()])
transform_test = transforms.Compose([transforms.ToTensor()])train_data = datasets.CIFAR10(".", train=True, download=True, transform=transform_train)
test_data = datasets.CIFAR10(".", train=False, download=True, transform=transform_test)
train_loader = DataLoader(train_data, batch_size=64, shuffle=True)
test_loader = DataLoader(test_data, batch_size=64)images, labels = next(iter(train_loader))# 仅查看一张图片
writer = SummaryWriter('./pytorch_tb')
writer.add_image('images[0]', images[0])
writer.close()# 将多张图片拼接成一张图片,中间用黑色网格分割
# create grid of images
# writer = SummaryWriter('./pytorch_tb')
# img_grid = torchvision.utils.make_grid(images)
# writer.add_image('image_grid', img_grid)
# writer.close()
#
# # 将多张图片直接写入
# writer = SummaryWriter('./pytorch_tb')
# writer.add_images("images",images,global_step = 0)
# writer.close()
 python -m tensorboard.main --logdir=./pytorch_tb --host=0.0.0.0 --port=6006 

另外注意上方menu部分,刚刚只有“GRAPHS"栏对应模型的可视化,现在则多出了”IMAGES“栏对应图像的可视化。左侧的滑动按钮可以调整图像的亮度和对比度。

此外,除了可视化原始图像,TensorBoard提供的可视化方案自然也适用于我们在Python中用matplotlib等工具绘制的其他图像,用于展示分析结果等内容。

3.5.TensorBoard--连续变量可视化

TensorBoard可以用来可视化连续变量(或时序变量)的变化过程,通过add_scalar实现:

writer = SummaryWriter('./pytorch_tb')
for i in range(500):x = iy = x**2writer.add_scalar("x", x, i) #日志中记录x在第step i 的值writer.add_scalar("y", y, i) #日志中记录y在第step i 的值
writer.close()

可视化结果如下:

如果想在同一张图中显示多个曲线,则需要分别建立存放子路径(使用SummaryWriter指定路径即可自动创建,但需要在tensorboard运行目录下),同时在add_scalar中修改曲线的标签使其一致即可:

writer1 = SummaryWriter('./pytorch_tb/x')
writer2 = SummaryWriter('./pytorch_tb/y')
for i in range(500):x = iy = x*2writer1.add_scalar("same", x, i) #日志中记录x在第step i 的值writer2.add_scalar("same", y, i) #日志中记录y在第step i 的值
writer1.close()
writer2.close()

这里也可以用一个writer,但for循环中不断创建SummaryWriter不是一个好选项。此时左下角的Runs部分出现了勾选项,我们可以选择我们想要可视化的曲线。曲线名称对应存放子路径的名称(这里是x和y)。

这部分功能非常适合损失函数的可视化,可以帮助我们更加直观地了解模型的训练情况,从而确定最佳的checkpoint。左侧的Smoothing滑动按钮可以调整曲线的平滑度,当损失函数震荡较大时,将Smoothing调大有助于观察loss的整体变化趋势。

3.6.TensorBoard--参数分布可视化

当我们需要对参数(或向量)的变化,或者对其分布进行研究时,可以方便地用TensorBoard来进行可视化,通过add_histogram实现。下面给出一个例子:

import torch
import numpy as np
from torch.utils.tensorboard import SummaryWriter  # 导入 TensorBoard 可视化工具# 定义一个函数,用于生成服从正态分布的张量(模拟神经网络参数)
def norm(mean, std):"""生成一个形状为 (100, 20) 的张量,其元素服从均值为 mean、标准差为 std 的正态分布。这可以用来模拟某一层神经网络的参数(如权重)。参数:mean (float): 正态分布的均值std (float): 正态分布的标准差返回:torch.Tensor: 形状为 (100, 20) 的张量"""t = std * torch.randn((100, 20)) + mean  # torch.randn 生成标准正态分布(均值0,标准差1)return t# 创建一个 SummaryWriter 实例,将日志写入 './pytorch_tb/' 目录
# 后续可通过 `tensorboard --logdir=./pytorch_tb/` 在浏览器中查看可视化结果
writer = SummaryWriter('./pytorch_tb/')# 遍历均值从 -10 到 9(步长为 1),共 20 个 step
for step, mean in enumerate(range(-10, 10, 1)):# 生成当前均值下的参数张量(标准差固定为 1)w = norm(mean, 1)writer.add_histogram("w", w, step)# 立即将数据写入磁盘(确保日志及时保存,便于实时查看)writer.flush()# 关闭 SummaryWriter,释放资源并确保所有数据写入完成
writer.close()

3.7.服务器端使用TensorBoard

一般情况下,我们会连接远程的服务器来对模型进行训练,但由于服务器端是没有浏览器的(纯命令模式),因此,我们需要进行相应的配置,才可以在本地浏览器,使用tensorboard查看服务器运行的训练过程。 本文提供以下几种方式进行,其中前两种方法都是建立SSH隧道,实现远程端口到本机端口的转发,最后一种方法适用于没有下载Xshell等SSH连接工具的用户

  • MobaXterm

    1. 在MobaXterm点击Tunneling

    2. 选择New SSH tunnel,我们会出现以下界面。

    ssh_tunnel

    1. 对新建的SSH通道做以下设置,第一栏我们选择Local port forwarding< Remote Server>我们填写localhost< Remote port>填写6006,tensorboard默认会在6006端口进行显示,我们也可以根据 tensorboard --logdir=/path/to/logs/ --port=xxxx的命令中的port进行修改,< SSH server> 填写我们连接服务器的ip地址,<SSH login>填写我们连接的服务器的用户名,<SSH port>填写端口号(通常为22),< forwarded port>填写的是本地的一个端口号,以便我们后面可以对其进行访问。

    2. 设定好之后,点击Save,然后Start。在启动tensorboard,这样我们就可以在本地的浏览器输入http://localhost:6006/对其进行访问了

  • Xshell

    1. Xshell的连接方法与MobaXterm的连接方式本质上是一样的,具体操作如下:

    2. 连接上服务器后,打开当前会话属性,会出现下图,我们选择隧道,点击添加 

      xhell_ui

    3. 按照下方图进行选择,其中目标主机代表的是服务器,源主机代表的是本地,端口的选择根据实际情况而定。 

      xhell_set

    4. 启动tensorboard,在本地127.0.0.1:6006 或者 localhost:6006进行访问。

  • SSH

    1. 该方法是将服务器的6006端口重定向到自己机器上来,我们可以在本地的终端里输入以下代码:其中16006代表映射到本地的端口,6006代表的是服务器上的端口。

      ssh -L 16006:127.0.0.1:6006 username@remote_server_ip
    
    1. 在服务上使用默认的6006端口正常启动tensorboard

    tensorboard --logdir=xxx --port=6006
    
    1. 在本地的浏览器输入地址

    127.0.0.1:16006 或者 localhost:16006
    

3.8.总结

对于TensorBoard来说,它的功能是很强大的,可以记录的东西不只限于本节所介绍的范围。

主要的实现方案是构建一个SummaryWriter,然后通过add_XXX()函数来实现。

其实TensorBoard的逻辑还是很简单的,它的基本逻辑就是文件的读写逻辑,写入想要可视化的数据,然后TensorBoard自己会读出来。

4.wandb--可视化训练过程

我们使用了Tensorboard可视化训练过程,但是Tensorboard对数据的保存仅限于本地,也很难分析超参数不同对实验的影响。

wandb的出现很好的解决了这些问题,因此在本章节中,我们将对wandb进行简要介绍。 wandb是Weights & Biases(权重和偏差的缩写,它能够自动记录模型训练过程中的超参数和输出指标,然后可视化和比较结果,并快速与其他人共享结果。目前它能够和Jupyter、TensorFlow、Pytorch、Keras、Scikit、fast.ai、LightGBM、XGBoost一起结合使用。

经过本节的学习,你将收获:

  • wandb的安装

  • wandb的使用

  • demo演示

4.1.wandb的安装

wandb的安装非常简单,我们只需要使用pip安装即可。

pip install wandb

安装完成后,我们需要在官网注册一个账号并复制下自己的API keys,然后在本地使用下面的命令登录。https://wandb.ai/site

需要连接外网。call me

wandb login

这时,我们会看到下面的界面,只需要粘贴你的API keys即可。 

4.2.wandb的使用

wandb的使用也非常简单,只需要在代码中添加几行代码即可。

import wandb
wandb.init(project='my-project', entity='my-name')

这里的project和entity是你在wandb上创建的项目名称和用户名,如果你还没有创建项目,可以参考官方文档。

#api:#api接口:5db56bbfd6a1c2feb98f219ffb789d9660afa761import wandb
wandb.init(project='my-project', entity='2898694631-gyp')

4.3.wandb的demo演示

下面我们使用一个CIFAR10的图像分类demo来演示wandb的使用。


import random  # to set the python random seed
import numpy  # to set the numpy random seed
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
from torchvision.models import resnet18
import warnings
warnings.filterwarnings('ignore')#忽略警告warning

使用wandb的第一步是初始化wandb,这里我们使用wandb.init()函数来初始化wandb,其中project是你在wandb上创建的项目名称,name是你的实验名称。

# 初始化wandb
import wandb
wandb.init(project="my-project",name="wandb_demo",)

使用wandb的第二步是设置超参数,这里我们使用wandb.config来设置超参数,这样我们就可以在wandb的界面上看到超参数的变化。wandb.config的使用方法和字典类似,我们可以使用config.key的方式来设置超参数。

# 超参数设置
config = wandb.config  # config的初始化
config.batch_size = 64  
config.test_batch_size = 10 
config.epochs = 5  
config.lr = 0.01 
config.momentum = 0.1  
config.use_cuda = True  
config.seed = 2043  
config.log_interval = 10 # 设置随机数
def set_seed(seed):random.seed(config.seed)      torch.manual_seed(config.seed) numpy.random.seed(config.seed) 

第三步是构建训练和测试的pipeline,这里我们使用pytorch的CIFAR10数据集和resnet18来构建训练和测试的pipeline。

# 定义训练函数:对模型进行一个 epoch 的训练
def train(model, device, train_loader, optimizer):model.train()  # 将模型设为训练模式(启用梯度、BatchNorm 等)for batch_id, (data, target) in enumerate(train_loader):data, target = data.to(device), target.to(device)  # 数据迁移到指定设备(CPU/GPU)optimizer.zero_grad()                              # 清空优化器中的梯度output = model(data)                               # 前向传播,得到模型输出criterion = nn.CrossEntropyLoss()                  # 定义交叉熵损失函数loss = criterion(output, target)                   # 计算损失loss.backward()                                    # 反向传播,计算梯度optimizer.step()                                   # 更新模型参数# 定义测试函数:评估模型性能,并通过 wandb 记录指标和示例图像
def test(model, device, test_loader, classes):model.eval()  # 将模型设为评估模式(关闭 Dropout、冻结 BatchNorm)test_loss = 0correct = 0example_images = []  # 用于保存预测示例图像with torch.no_grad():  # 禁用梯度计算,加速推理并节省显存for data, target in test_loader:data, target = data.to(device), target.to(device)output = model(data)criterion = nn.CrossEntropyLoss()test_loss += criterion(output, target).item()  # 累加损失值pred = output.max(1, keepdim=True)[1]          # 获取预测类别(最大 logit 的索引)correct += pred.eq(target.view_as(pred)).sum().item()  # 统计正确预测数量# 将第一个样本的图像及预测/真实标签保存为 wandb.Image 对象example_images.append(wandb.Image(data[0], caption="Pred:{} Truth:{}".format(classes[pred[0].item()], classes[target[0]])))# 使用 wandb.log 记录测试阶段的关键指标和可视化示例wandb.log({"Examples": example_images,                        # 可视化预测样例"Test Accuracy": 100. * correct / len(test_loader.dataset),  # 测试准确率(%)"Test Loss": test_loss                         # 测试总损失(未平均)})# 防止 wandb.watch 被重复调用(兼容性处理)
wandb.watch_called = False# 主函数:配置环境、加载数据、初始化模型并开始训练
def main():use_cuda = config.use_cuda and torch.cuda.is_available()device = torch.device("cuda:0" if use_cuda else "cpu")kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}# 设置随机种子,保证实验可复现set_seed(config.seed)torch.backends.cudnn.deterministic = True# 定义数据预处理流程:转为 Tensor 并标准化(CIFAR-10 常用均值/标准差)transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])# 加载 CIFAR-10 训练数据集train_loader = DataLoader(datasets.CIFAR10(root='dataset',train=True,download=True,transform=transform), batch_size=config.batch_size, shuffle=True, **kwargs)# 加载 CIFAR-10 测试数据集test_loader = DataLoader(datasets.CIFAR10(root='dataset',train=False,download=True,transform=transform), batch_size=config.batch_size, shuffle=False, **kwargs)# CIFAR-10 数据集的 10 个类别名称classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')# 加载预训练的 ResNet18 模型,并移动到指定设备model = resnet18(pretrained=True).to(device)# 注意:此处未修改最后的分类层,若用于 CIFAR-10 可能存在类别数不匹配问题(但代码未改)# 定义优化器:使用 SGD,传入学习率和动量参数optimizer = optim.SGD(model.parameters(), lr=config.lr, momentum=config.momentum)# 使用 wandb 监控模型(记录参数、梯度、计算图等)wandb.watch(model, log="all")# 开始训练循环:逐 epoch 训练并测试for epoch in range(1, config.epochs + 1):train(model, device, train_loader, optimizer)test(model, device, test_loader, classes)# 保存训练好的模型到本地文件torch.save(model.state_dict(), 'model.pth')# 同时将模型文件同步到 wandb 云端wandb.save('model.pth')# 程序入口
if __name__ == '__main__':main()

哎,中国大陆要断开,真麻烦,用一下别人的实验结果

我们可以发现,使用wandb可以很方便的记录我们的训练结果,除此之外,wandb还为我们提供了很多的功能,比如:模型的超参数搜索,模型的版本控制,模型的部署等等。这些功能都可以帮助我们更好的管理我们的模型,更好的进行模型的迭代和优化。这些功能我们在后面的更新中会进行介绍。

http://www.dtcms.com/a/490174.html

相关文章:

  • 商城系统-自动化测试报告
  • 递归-面试题08.06.汉诺塔问题-力扣(LeetCode)
  • 珠海网站建设 骏域网站域名 空间 网站制作
  • AI视频生成工具完全指南:从Sora到开源替代方案全解析
  • 多模态大模型研究每日简报【2025-10-16】
  • Azure Workbooks 权限配置完整指南
  • 公司做网站需要哪些资料百度蜘蛛抓取网站模块
  • 后端定义两个实体参数,前端如何传值
  • **点云处理:发散创新,探索前沿技术**随着科技的飞速发展,点云处理技术在计算机视觉、自动驾驶、虚拟现实等领域的应用愈发广
  • HarmonyOS分布式硬件共享:调用手机摄像头的手表应用
  • 网站开发英语英语山东教育网站开发公司
  • 手表东莞网站建设技术支持网站搭建公司加盟
  • DevTunnel:免费安全穿透内网网页
  • el-input 输入框宽度自适应宽度
  • [嵌入式系统-126]:CUDA运行在CPU上,还是运行在GPU之上?
  • 启动模板创建AWS EC2 Auto Scaling指南
  • 【LeetCode_160】相交链表
  • HUAWEI A800I A2 aarch64架构服务器鲲鹏920开启虚拟化功能
  • Java-151 深入浅出 MongoDB 索引详解 性能优化:慢查询分析 索引调优 快速定位并解决慢查询
  • 微信小程序快速入门【02】
  • YOLO-V1 与 YOLO-V2 技术详解:从经典到优化的目标检测演进
  • 天津市网站制作公司百度seo点击器
  • 建设部网站燃气管理部门网络软件开发
  • 三种思路彻底掌握 BST 判断(递归与迭代全解析)——力扣98.验证二叉搜索树
  • 基于k8s环境的mongodb多副本高可用方案
  • 汽车免拆诊断案例 | 2014 款宝马 M4 车冷起动后发动机抖动
  • 横泉水库建设管理局网站鄂州网站建设哪家专业
  • 虚拟人驱动密码:惯性动作捕捉设备+无穿戴动作捕捉技术
  • Linux01
  • StarRocks 数据分析加速:ETL 如何实现实时同步与高效查询