使用TensorBoard进行可视化

1. TensorBoard介绍

TensorBoard是TensorFlow推出的可视化工具,可以可视化模型结构、跟踪并以表格形式显示模型指标。

TensorBoard的使用包括两个步骤:

  1. 在代码中设置TensorBoard,在训练的过程中将会根据设置产生日志文件
  2. 在浏览器中可视化该日志文件,查看网络结构、loss的变化情况等

下面以 LeNet-5 为例,介绍如何在TensorFlow和PyTorch中配置TensorBoard。

2. 代码中设置TensorBoard

2.1 TensorFlow中设置

2.1.1 使用说明

在TensorFlow通过两个简单步骤即可使用TensorBoard(更多的功能可参考官方文档)。

  1. tensorboard_callback = keras.callbacks.TensorBoard(log_dir='logs/tf') :初始化日志文件。其中,log_dir 是日志文件的存放位置

  2. model.fit(callbacks=[tensorboard_callback]) :设置回调函数,在模型训练期间将会调用 tensorboard_callback 从而向日志文件中写入数据

    注意:

    日志文件的绝对路径中不能包含中文

2.1.2 代码实现

LeNet-5 的搭建可参考[TensorFlow搭建神经网络]https://blog.csdn.net/qq_41100617/article/details/132122966)

import timeimport tensorflow as tf
from keras import datasets
from keras import layers
from tensorflow import kerasdef my_model(input_shape):# 首先,创建一个输入节点inputs = keras.Input(input_shape)# 搭建神经网络x = layers.Conv2D(filters=6, kernel_size=(5, 5), strides=(1, 1), activation='relu')(inputs)x = layers.AveragePooling2D(pool_size=(2, 2), strides=(2, 2))(x)x = layers.Conv2D(filters=16, kernel_size=(5, 5), strides=(1, 1), activation='relu')(x)x = layers.AveragePooling2D(pool_size=(2, 2), strides=(2, 2))(x)x = layers.Flatten()(x)x = layers.Dense(units=16 * 4 * 4, activation='relu')(x)x = layers.Dense(units=120, activation='relu')(x)# 输出层outputs = layers.Dense(units=10, activation='softmax')(x)model = keras.Model(inputs=inputs, outputs=outputs)return model(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()train_images = tf.reshape(train_images, (train_images.shape[0], train_images.shape[1], train_images.shape[2], 1))
train_images = tf.cast(train_images, tf.float32)test_images = tf.reshape(test_images, (test_images.shape[0], test_images.shape[1], test_images.shape[2], 1))
test_images = tf.cast(test_images, tf.float32)model = my_model(train_images.shape[1:])loss = keras.losses.SparseCategoricalCrossentropy()
optimizer = keras.optimizers.SGD(0.0001)
model.compile(loss=loss, optimizer=keras.optimizers.SGD(0.00001))# 初始化日志文件
tensorboard_callback = keras.callbacks.TensorBoard(log_dir='logs/tf/' + time.strftime('%m-%d-%H-%M', time.localtime(time.time())))# 在训练过程中设置回调
model.fit(train_images, train_labels, validation_split=0.3, epochs=1000, batch_size=20,callbacks=[tensorboard_callback])pre_labels = model.predict(test_images)

2.2 PyTorch中设置

2.2.1 使用说明

PyTorch1.1之后添加了TensorBoard,在PyTorch中使用TensorBoard主要有3个步骤(具体信息可查看其官方文档):

  1. SummaryWriter :创建一个日志文件,主要有以下两个参数:
    • log_dir :保存日志文件的目录,默认值为 runs/当前日期时间存放的路径中不能包含中文!)
    • commentlog_dir 取默认值时添加到 log_dir 后面的后缀,当设置了 log_dir 时,该值无效
  2. add_XXX: 向创建好的日志文件里面添加数据,常用的有:
    • add_graph :添加GRAPHS,其中存放了网络结构。有以下两个常用参数:
      • model :模型
      • input_to_model :模型的输入数据
    • add_scalar : 添加SCALARS,其中可以存放折线图数据用于显示训练过程中的损失值变化情况。有以下三个常用参数:
      • tag :折线图的标签。指定tag时,加入 / 分割,可将多个折线图放在一个tag下,如 :tag=train/loss, tag=train/map,此时train下面会有loss和map两个折线图
      • scalar_value :折线图纵轴的值,一般是loss、准确率等数据
      • global_step :折线图的横轴,一般是epoch
    • add_scalars :在一张折线图中同时绘制多个数据,有以下三个常用参数:
      • main_tag, :与 add_scalar 中的 tag 用法一样
      • tag_scalar_dict :纵轴的值,因为是多个数据,需要以字典形式传入(具体看下面代码实现)
      • global_step :与 add_scalar 中的 global_setp 用法一样
  3. close:结束log写入,一般用在训练结束后

类似于操作文件,SummaryWriter 也可以和 with 一起使用,此时可以不需显示调用 close ,如:

writer = SummaryWriter()
# 写入数据……
writer.close()#上面的代码等价于下面with SummaryWriter() as w:# 写入数据……

2.2.2 代码实现

LeNet-5 的搭建可参考PyTorch搭建神经网络

import timeimport torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
from sklearn.metrics import classification_report
from torch import optim
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from tqdm import tqdmclass LeNet(nn.Module):def __init__(self, in_channels):super(LeNet, self).__init__()self.conv1 = nn.Conv2d(in_channels=in_channels, out_channels=6, kernel_size=5, stride=1)self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)self.conv2 = nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5, stride=1)self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)self.fc1 = nn.Linear(in_features=16 * 4 * 4, out_features=120)self.fc2 = nn.Linear(in_features=120, out_features=84)self.fc3 = nn.Linear(in_features=84, out_features=10)def forward(self, x):x = self.conv1(x)x = F.relu(x)x = self.pool1(x)x = self.conv2(x)x = F.relu(x)x = self.pool2(x)x = x.reshape(x.shape[0], -1)x = self.fc1(x)x = F.relu(x)x = self.fc2(x)x = F.relu(x)x = self.fc3(x)return xdef main():batch_size = 8num_epochs = 10train_dataset = torchvision.datasets.MNIST(root="data/", train=True, transform=transforms.ToTensor(),download=True)val_dataset = torchvision.datasets.MNIST(root="data/", train=False, transform=transforms.ToTensor(), download=True)train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size,shuffle=True)val_loader = DataLoader(dataset=val_dataset, batch_size=batch_size, shuffle=True)device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')model = LeNet(1).to(device)criterion = nn.CrossEntropyLoss()optimizer = optim.Adam(model.parameters())writer = SummaryWriter('logs/pt/' + time.strftime('%m-%d-%H-%M', time.localtime(time.time())))  # 设置了存放位置,此时即使设置了 comment 也不起作用writer.add_graph(model, torch.randn(1, 1, 28, 28))  # 先写入模型结构for epoch in tqdm(range(num_epochs)):train_loss = 0val_loss = 0accuracy = 0macro_avg_f1 = 0weighted_avg_f1 = 0# 训练模型for batch_idx, (data, label) in enumerate(train_loader):data = data.to(device=device)label = label.to(device=device)pre = model(data)loss = criterion(pre, label)train_loss = (train_loss * batch_idx + loss) / (batch_idx + 1)optimizer.zero_grad()loss.backward()optimizer.step()# 评估模型with torch.no_grad():model.eval()for batch_idx, (data, label) in enumerate(val_loader):data = data.to(device=device)label = label.to(device=device)pre = model(data)loss = criterion(pre, label).item()val_loss = (val_loss * batch_idx + loss) / (batch_idx + 1)pre = torch.argmax(pre, dim=1)score = classification_report(pre, label, output_dict=True)accuracy = (accuracy * batch_idx + score['accuracy']) / (batch_idx + 1)macro_avg_f1 = (macro_avg_f1 * batch_idx + score['macro avg']['f1-score']) / (batch_idx + 1)weighted_avg_f1 = (weighted_avg_f1 * batch_idx + score['weighted avg']['f1-score']) / (batch_idx + 1)model.train()writer.add_scalar('val/accuracy', accuracy, epoch)  # 在一个 tag 下面添加多个折线图writer.add_scalar('val/macro avg-f1', macro_avg_f1, epoch)writer.add_scalar('val/weighted avg-f1', weighted_avg_f1, epoch)writer.add_scalars('loss', {'train_loss': train_loss, 'val_loss': val_loss}, epoch)  # 一个折线图里面显示多个数据writer.close()  # 训练结束,不再写入数据,关闭writerif __name__ == '__main__':main()

3. 可视化

注意,这里如果直接输入tensorboard使用的是系统python环境里面的tensorboard,因此,务必确保系统python环境中已安装了tensorboard

打开 log 所在的文件夹,在该文件夹下打开命令行窗口(1.在路径显示框中输入 cmd 然后回车即可打开 或者 2. 在文件夹中按住 Shift 键同时右击鼠标然后选择‘在此处打开Powershell窗口’),输入:

tensorboard --logdir=.\logs --port=6007

其中:

  • –logdir:存放日志文件的文件夹
  • –port:端口号,默认是6006

若正常,将显示以下信息:
请添加图片描述

打开浏览器,在地址栏中输入:localhost:6007(端口号要和上面保持一致)。即可看到可视化的效果,点击不同的标签可查看不同数据

请添加图片描述

4. 配合远程服务器使用

上面的代码和浏览器都在同一个电脑上,有时需要在服务器上跑代码,这时候要想在自己的电脑浏览器上可视化TensorBoard,可以按照下面的方式:

4.1 端口转发

在电脑命令行窗口输入:

ssh -L 6008:127.0.0.1:6007 服务器用户名@服务器IP地址 -p 22

这将在连接服务器的同时将服务器上的 6007 端口转发到本地的 6008 端口。

成功连接服务器后,按照上面讲的可视化的方法在服务器对应的目录下输入:

tensorboard --logdir=日志文件的存放路径 --port=6007

成功启动后,在电脑的浏览器中输入:localhost:6008 。这里用到了两个端口号,一个是服务器上tensorboard使用的端口号 6007 ,一个是本地转发以及浏览器使用的端口号 6008 ,注意区分。

4.2 Xshell建立隧道

在Xshell中选择需要设置的会话,然后右键选择属性,进行如下设置

请添加图片描述
请添加图片描述

设置完之后连接服务器,在服务器对应的目录下输入:

tensorboard --logdir=日志文件的存放路径 --port=6007

成功启动后,在电脑的浏览器中输入:localhost:6008 。这里用到了两个端口号,一个是服务器上tensorboard使用的端口号 6007 ,一个是浏览器使用的端口号 6008 ,注意区分。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/53596.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在轻量级RTSP服务支持H.264扩展SEI发送接收自定义数据?

为什么开发轻量级RTSP服务? 开发轻量级RTSP服务的目的是为了解决在某些场景下用户或开发者需要单独部署RTSP或RTMP服务的问题。这种服务的优势主要有以下几点: 便利性:通过轻量级RTSP服务,用户无需配置单独的服务器,…

【Linux后端服务器开发】Reactor模式实现网络计算器

目录 一、Reactor模式概述 二、日志模块:Log.hpp 三、TCP连接模块:Sock.hpp 四、非阻塞通信模块:Util.hpp 五、多路复用I/O模块:Epoller.hpp 六、协议定制模块:Protocol.hpp 七、服务器模块:Server.…

05 - ArrayList还是LinkedList?使用不当性能差千倍

集合作为一种存储数据的容器,是我们日常开发中使用最频繁的对象类型之一。JDK 为开发者提供了一系列的集合类型,这些集合类型使用不同的数据结构来实现。因此,不同的集合类型,使用场景也不同。 很多同学在面试的时候,…

Leetcode-每日一题【剑指 Offer 05. 替换空格】

题目 请实现一个函数&#xff0c;把字符串 s 中的每个空格替换成"%20"。 示例 1&#xff1a; 输入&#xff1a;s "We are happy."输出&#xff1a;"We%20are%20happy." 限制&#xff1a; 0 < s 的长度 < 10000 解题思路 前置知识 Str…

Vue + ElementUI 实现可编辑表格及校验

效果 完整代码见文末 实现思路 使用两个表单分别用于实现修改和新增处理。 通过一个editIndex变量判断是否是编辑状态来决定是否展示输入框&#xff0c;当点击指定行的修改后进行设置即可&#xff1a; <el-table-columnv-for"(column, index) in columns":key&qu…

下载Windows 10光盘镜像(ISO文件)

文章目录 下载Windows 10镜像文件 下载Windows 10镜像文件 打开微软官网下载地址 立即下载工具 找到下载工具&#xff0c;双击运行&#xff0c;等待 接受条款&#xff0c;等待 选择为另一台电脑安装介质 选择Windows10&#xff0c;下一步 选择ISO文件&#xff0c;…

HTTP——五、与HTTP协作的Web服务器

HTTP 一、用单台虚拟主机实现多个域名二、通信数据转发程序 &#xff1a;代理、网关、隧道1、代理2、网关3、隧道 三、保存资源的缓存1、缓存的有效期限2、客户端的缓存 一台 Web 服务器可搭建多个独立域名的 Web 网站&#xff0c;也可作为通信路径上的中转服务器提升传输效率。…

nginx部署本地umi build项目

一、安装 brew install nginxBrew 安装可以参考网上教程 https://juejin.cn/post/6986190222241464350 安装后启动nginx服务查看是否成功 brew services start nginx启动报错 Error: undefined method launchd_service_path‘ for xxx 解决&#xff1a;更新brew brew updat…

AI相机“妙鸭相机”原理分析和手动实现方案

妙鸭相机 一个通过上传大约20张照片&#xff0c;生成专属自拍。在2023年7月末爆火&#xff0c;根据36Kr报道&#xff0c;妙鸭相机系阿里系产品&#xff0c;挂靠在阿里大文娱体系下&#xff0c;并非独立公司。 使用方法是上传20张自拍照片&#xff0c;之后可以选择模板生成自己…

【新版系统架构补充】-嵌入式技术

嵌入式微处理体系结构 冯诺依曼结构 传统计算机采用冯诺依曼结构&#xff0c;也称普林斯顿结构&#xff0c;是一种将程序指令存储器和数据存储器合并在一起的存储器结构 冯诺依曼的计算机程序和数据共用一个存储空间&#xff0c;程序指令存储地址和数据存储地址指向同一个存…

ConcurrentHashMap 的简单介绍

ConcurrentHashMap是Java集合框架中的一个并发容器&#xff0c;它是线程安全的哈希表的实现。它被设计为比Hashtable和SynchronizedMap&#xff08;通过使用同步方法或块来保证线程安全&#xff09;更高效和可扩展的替代品。 ConcurrentHashMap具有以下特点&#xff1a; 线程…

Qt应用开发(基础篇)——滑块类 QSlider、QScrollBar、QDial

一、前言 滑块类QScrollBar、QSlider和QDial继承于QAbstractSlider&#xff0c;父类主要拥有最大值、最小值、步长、当前值、滑块坐标等信息&#xff0c;滑动的时候触发包含值数据变化、滑块按下、滑块释放等信号。键盘包括左/上和右/下箭头键通过定义的singleStep改变当前值&a…