2. tensorboard和 transform的使用
正文
本篇文章主要介绍 pytorch 中 tensorboard 和 transform 的使用。
1、tensorboard
tensorboard原本是tensorflow的可视化工具,pytorch从1.2.0开始支持tensorboard。之前的版本也可以使用tensorboardX代替。
tensorboard常常作为一个辅助工具,可以把Pytorch中的参数传递到Tensorboad上面。
tensorboard 的打开与关闭
tensorboard 作为一个可视化的辅助工具,是通过将日志文件写入到我们的目标文件夹中实现
既然是通过文件的写入和读取来实现的,那么必定包含文件的打开与关闭操作,具体的代码如下所示:
from torch.utils.tensorboard import SummaryWriter # 创建一个对象,并设置存储路径 writer = SummaryWriter('./logs') writer.close()
add_image(), add_scalar()
了解文件的打开与关闭之后,下一步就是如何向日志文件中写入数据,这里主要是介绍最为常用的两个方法 SummaryWriter.add_image() 和 SummaryWriter.add_scalar()
- SummaryWriter.add_scalar()
首先,查看帮助文档
不能不夸奖一般 Pycharm 的帮助文档,写的非常详细(ctrl
键按住,点击函数名即可)
那么,我们也写一个
from torch.utils.tensorboard import SummaryWriter # 创建一个对象,并设置存储路径 writer = SummaryWriter('./logs') for i in range(20): writer.add_scalar("my:y=2x", i * 2, i) writer.close()
- SummaryWriter.add_image()
帮助文档如下:
同样是照着葫芦画瓢,走一个
from torch.utils.tensorboard import SummaryWriter # 用于读取图像和类型转化 from PIL import Image import numpy as np # 创建一个对象,并设置存储路径 img_path = r"F:\projects\pycharm\pytorch_dl\test\data\train\ants\0013035.jpg" writer = SummaryWriter('./logs') img_PIL = Image.open(img_path) img_array = np.array(img_PIL) writer.add_image("test_img", img_array, 0, dataformats="HWC") writer.close()
tensorboard 通过端口查看数据
需要在环境中cmd运行
tensorboard --logdir=logs tensorboard --logdir=./logs --port=6066
默认端口号是6006,通过--port 参数我们可以指定特定的端口
tag 冲突处理
当我们在同一个 log
文件夹中,指定了同一个 tag
,可能会照成显示图像的混乱,解决这个问题可以有以下这几个方法
-
更改日志文件存储位置
-
删除原本的日志文件
这两种方法都需要重启我们的 tensorboard
命令,ctrl
+ c
终止原本的 tenforboard 进程,然后开启新的 tensorboard
进程即可
2、transform的使用
transform 的简单使用与 Tensor 数据类型
transform
顾名思义,就是用于数据类型转化的意思,他是torchvision
模块下面的一个子模块transforms
,该模块中包含大量用户数据类型转化的类型和方法。下面我们进入该模块中进行查看。 (注:pycharm
中 按住 ctrl
单机进去该模块即可)
常用的主要是一下这几个类:
Compose:通过查看帮助文档可知,他是 多个 transform 的结合体,也就是说可以进行多次 transform 变化
ToTensor:
PILToTensor : Converts a PIL Image (H x W x C) to a Tensor of shape (C x H x W). 也是进行了类型的转换设置维度信息发生了变化
其他的请自行查看帮助文档,这里不再赘述。
下面,我进行一下简单使用的演示:
from torch.utils.tensorboard import SummaryWriter from torchvision import transforms from PIL import Image import numpy as np img_path = r'F:\projects\pycharm\pytorch_dl\test\data\train\ants\5650366_e22b7e1065.jpg' img_PIL = Image.open(img_path) img_array = np.array(img_PIL) tensor_trans = transforms.ToTensor() img_tensor1 = tensor_trans(img_PIL) img_tensor2 = tensor_trans(img_array) writer = SummaryWriter('logs2') writer.add_image('test1', img_tensor1, 0) writer.add_image('test1', img_tensor2, 1) writer.close()
查看转换之后的 tensor
类型,可以看到一些专美用于做神经网络的属性,可以说tensor
很大程度上是为了方面深度学习代码的书写(就像是 numpy
用于科学计算一样),
上面的代码中我们也使用 tensor
,将其写在 Log
文件的 日志中去
常见 transform 的使用
这里,我先引入一个小知识 pytorch 中类的 __call__函数和 forward函数都不用显示的调用函数,
这两个函数的作用是能够让python中的类的对象能够像方法一样被调用!具体可以参考博客:
深入探究# PyTorch中的 forward() 方法详解
transform 非常的常见,常常用于转化数据的格式(上一节有着些许的介绍),下面我将进行更为详细的介绍。
我们的函数的认知(尤其是库函数),主要从一下三种方面出发:
- 函数的作用 -- 这也是我们使用该函数的目的已经应用场景
- 函数的输入格式 -- 教会我们如何使用函数
- 函数的输出格式
在我看来,想要快速的了解函数的功能与使用方法,上手一个函数,还是需要看官方文档,幸好Pycharm IDE 中集成了帮助文档,虽然英文,不过写的足够详细,下面我将一个一个的介绍 transform 模块的常用函数
首先,我们还是大致看一下 transform.py 中的函数
下面,我们查看官方文档 + 使用 tensorboard 进行查看函数的作用
首先,我们先说2个小技巧:
- 输入代码的时候
ctrl
+p
可以提示函数参数 - 设置代码提示是是否忽略大小写(参考下午)
ToPILImage
我们使用 cv2.read() 和 Image.open()分别进行读取图片,将其放入到 logs 文件中,通过 tensorboard进行查看
# 导入几个包 from torchvision.transforms import transforms from torch.utils.tensorboard import SummaryWriter from PIL import Image import cv2 import numpy as np # define the variable and open tensorboard writer = SummaryWriter('logs') img_path = r'F:\projects\pycharm\pytorch_dl\test\data\val\bees\72100438_73de9f17af.jpg' # read the image img_array = cv2.imread(img_path) # 其实并不是失真,而是在导入图片时使用了opencv,正常展示顺序是RGB,而opencv的读取顺序是BGR, trans_toPIL = transforms.ToPILImage() trans_toTensor = transforms.ToTensor() img_PIL = trans_toPIL(img_array) # 调用了 __call__ 函数,转化形成 PIL img_PIL_2 = Image.open(img_path) # 直接读的 PIL图片格式 print(type(img_array)) writer.add_image('ndarrayy - PILImage - PILImage', img_array, 0, dataformats="HWC") writer.add_image('ndarrayy - PILImage - PILImage', trans_toTensor(img_PIL), 1) writer.add_image('ndarrayy - PILImage - PILImage', trans_toTensor(img_PIL_2), 2) # close tensorboard writer.close()
发现颜色出了问题
其实这不是cv2读取文件出现了问题,而是我们cv2读取文件 读取通道顺序为B、G、R
和我们平时的 RGB 顺序完全相反,所以造成了这种奇奇怪怪的现象,将其修改也较为简单
# 第一种方法,推荐使用该种方法,因为第一种方法存在问题 # 尤其是在转换 tensor的时候,我的 pycharm 会直接 报错,异常退出,我还找了半天bug b,g,r = cv2.split(img_array) #分别提取B、G、R通道 img_array = cv2.merge([r, g, b]) # 可以将其写成一个函数封装一下子了 # 第二种方法 #img[:,:,0]表示图片的蓝色通道,对一个字符串s进行翻转用的是s[::-1],同样img[:,:,::-1]就表示BGR通道翻转,变成RGB img_array = img_array[:, :, ::-1]
转化之后,再次运行一下,发现颜色正常。
注意:一定要将之前的 event 日志全部给删除,然后重启我们的 tensorboard 工具
这里,我再进行一下 cv2 的些许补充,主要是对下述代码进行讲解,具体请看注释
# 导入几个包 import matplotlib.pyplot as plt from torchvision.transforms import transforms from torch.utils.tensorboard import SummaryWriter from PIL import Image import cv2 import numpy as np # define the variable and open tensorboard writer = SummaryWriter('logs') img_path = r'F:\projects\pycharm\pytorch_dl\test\data\val\bees\72100438_73de9f17af.jpg' # read the image img_array_bgr = cv2.imread(img_path) # 首先我们使用了 cv2 库函数读取了图片,bgr色彩,ndarray类型 img_PIL = Image.open(img_path) # 我们又使用了 Image 类读取了图片 PIL 类型 b, g, r = cv2.split(img_array_bgr) # 这一步,我们使用 bgr分离,将 img_array_bgr --> img_array_rgb img_array_rgb = cv2.merge([r, g, b]) cv2.imshow("img_array", img_array_rgb) cv2.waitKey() cv2.imshow("img_array", img_array_bgr) cv2.waitKey() # 我们将 rgb, bgr 分别转换为 PIL 进行 show展示 img_PIL.show() trans_toPIL = transforms.ToPILImage() img_PIL_rgb = trans_toPIL(img_array_rgb) img_PIL_rgb.show() img_PIL_bgr = trans_toPIL(img_array_bgr) img_PIL_bgr.show() # close tensorboard writer.close()
rgb和 img_PIL_Image_open都是一个图片
心得:
不难看出,cv2读取读片是 bgr, 解析显示图片也是 bgr,所以说仅仅是在 cv2 中使用,不需要进行 bgr->rgb 维度的转换,但是倘若cv2中混有 tensor,或者是 PIL因为他们使用了rgb 色系,应当进行相应类型的转换。
toTensor
这个之前讲过,也用过很多次,这里不再赘述(而且用法和 toPILImage 差不多)
Resize
帮助文档的解释如下图所示:
直接找一个图进行实践即可(效果显著,像素变得非常的拉胯!!!)
# 导入几个包 import matplotlib.pyplot as plt from torchvision.transforms import transforms from torch.utils.tensorboard import SummaryWriter from PIL import Image import cv2 import numpy as np # define the variable and open tensorboard writer = SummaryWriter('logs') img_path = r'F:\projects\pycharm\pytorch_dl\test\data\val\bees\72100438_73de9f17af.jpg' # read the image img_array = cv2.imread(img_path) # 其实并不是失真,而是在导入图片时使用了opencv,正常展示顺序是RGB,而opencv的读取顺序是BGR, # img_array = img_array[:, :, ::-1] b, g, r = cv2.split(img_array) img_array2 = cv2.merge([r, g, b]) img_array3 = img_array[:, :, ::-1] img_array = img_array2 trans_toPIL = transforms.ToPILImage() trans_toTensor = transforms.ToTensor() trans_resize = transforms.Resize(100) trans_resize2 = transforms.Resize([100, 50]) # 注意这个[],因为他是一个序列 list img_tensor = trans_toTensor(img_array) img_tensor_resize = trans_resize.forward(img_tensor) img_tensor_resize2 = trans_resize2.forward(img_tensor) writer.add_image("img_tensor_resize", img_tensor, 0) writer.add_image("img_tensor_resize", img_tensor_resize, 1) writer.add_image("img_tensor_resize", img_tensor_resize2, 2) # close tensorboard writer.close()
debug 查看他的像素值变化:
Normalize
Normalize,规范化,特殊情况下也可以成为归一化,
归一化就是要把需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内。首先归一化是为了后面数据处理的方便,其次是保证程序运行时收敛加快。归一化的具体作用是归纳统一样本的统计分布性。归一化在0-1之间是统计的概率分布,归一化在某个区间上是统计的坐标分布。归一化有同一、统一和合一的意思。
归一化的目的简而言之,是使得没有可比性的数据变得具有可比性,同时又保持相比较的两个数据之间的相对关系,如大小关系;或是为了作图,原来很难在一张图上作出来,归一化后就可以很方便的给出图上的相对位置等。
帮助文档的解释如下图所示:
走一个小代码试一试
# 导入几个包 import matplotlib.pyplot as plt from torchvision.transforms import transforms from torch.utils.tensorboard import SummaryWriter from PIL import Image import cv2 import numpy as np # define the variable and open tensorboard writer = SummaryWriter('logs') img_path = r'F:\projects\pycharm\pytorch_dl\test\data\val\bees\72100438_73de9f17af.jpg' # read the image img_array_bgr = cv2.imread(img_path) # 其实并不是失真,而是在导入图片时使用了opencv,正常展示顺序是RGB,而opencv的读取顺序是BGR, img_PIL = Image.open(img_path) b, g, r = cv2.split(img_array_bgr) img_array_rgb = cv2.merge([r, g, b]) trans_to_tensor = transforms.ToTensor() trans_to_PIL = transforms.ToPILImage() trans_to_norm = transforms.Normalize([1, 2, 3], [3, 4, 5]) img_tensor = trans_to_tensor(img_array_rgb) img_tensor_norm = trans_to_norm(img_tensor) writer.add_image("Image-Normalize", img_tensor, 0) writer.add_image("Image-Normalize", img_tensor_norm, 1) # close tensorboard writer.close()
倘若你的 tensorboard
出现了问题,请记得退出你的 tensorboard 进程,并且删除你的日志文件,在此运行改程序,倘若还有问题,可能是你的代码、或者是环境出了问题。
Compose
帮助文档的解释如下图所示:
直接进行上手实验,我们连接一个 ToTensor、Resize 、 Normalize 的转换器,代码如下图所示:
# 导入几个包 import matplotlib.pyplot as plt from torchvision.transforms import transforms from torch.utils.tensorboard import SummaryWriter from PIL import Image import cv2 import numpy as np # define the variable and open tensorboard writer = SummaryWriter('logs') img_path = r'F:\projects\pycharm\pytorch_dl\test\data\val\bees\72100438_73de9f17af.jpg' # read the image img_array_bgr = cv2.imread(img_path) # 其实并不是失真,而是在导入图片时使用了opencv,正常展示顺序是RGB,而opencv的读取顺序是BGR, img_PIL = Image.open(img_path) b, g, r = cv2.split(img_array_bgr) img_array_rgb = cv2.merge([r, g, b]) trans_to_tensor = transforms.ToTensor() trans_compose = transforms.Compose([ transforms.ToTensor(), transforms.Resize(200), transforms.Normalize([1, 2, 3], [1, 2, 3]) ]) img_compose = trans_compose(img_array_rgb) writer.add_image("Compose", trans_to_tensor(img_array_rgb), 0) writer.add_image("Compose", img_compose, 1) # close tensorboard writer.close()
结果如下所示:
CenterCrop
帮助文档的解释如下图所示:
直接上代码:
# 导入几个包 import matplotlib.pyplot as plt from torchvision.transforms import transforms from torch.utils.tensorboard import SummaryWriter from PIL import Image import cv2 import numpy as np # define the variable and open tensorboard writer = SummaryWriter('logs') img_path = r'F:\projects\pycharm\pytorch_dl\test\data\val\bees\72100438_73de9f17af.jpg' # read the image img_array_bgr = cv2.imread(img_path) # 其实并不是失真,而是在导入图片时使用了opencv,正常展示顺序是RGB,而opencv的读取顺序是BGR, img_PIL = Image.open(img_path) b, g, r = cv2.split(img_array_bgr) img_array_rgb = cv2.merge([r, g, b]) trans_to_tensor = transforms.ToTensor() trans_center_crop = transforms.CenterCrop((100, 100)) img_tensor = trans_to_tensor(img_array_rgb) img_center_crop = trans_center_crop(img_tensor) writer.add_image("Image-center-crop", img_tensor, 0) writer.add_image("Image-center-crop", img_center_crop, 1) # close tensorboard writer.close()
pycharm 的小技巧
- pycharm 的断点调试,非常的好使,主要是因为他还至此在断点中查看变量的数值,并且可以进行变量的修改,简直就是和 Python console 一样,用起来都很爽
- pycharm
ctrl
+p
查看代码提示
- 顺便提一嘴,查看帮助文档的时候,尽量自己查看,不要使用翻译软件(不是很准),主要是注意 输入、输出和函数的功能
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)