7 Tensorboard的使用(一)

打开Pycharm,设置环境

1
2
3
4
5
6
7
8
9
10
11
12
# 从torch.utils.tensorboard模块中导入SummaryWriter类
from torch.utils.tensorboard import SummaryWriter
# 将事件和文件存储到"logs"文件夹下
writer = SummaryWriter("logs")

# writer.add_image()
# y = x
# i 范围是0到99
for i in range(100):
writer.add_scalar("y = x", i, i)

write.close()

add_scalar()方法

image-20230720095510726

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def add_scalar(
self,
tag,
scalar_value,
global_step=None,
walltime=None,
new_style=False,
double_precision=False,
):
"""Add scalar data to summary.
Args:
tag (str): Data identifier
scalar_value (float or string/blobname): Value to save
global_step (int): Global step value to record
"""

安装TensorBoard

image-20230720100426926

安装后再次运行,左侧多了一个logs文件

image-20230720100707696

终端输入

1
2
3
4
5
6
tensorboard --logdir=logs
'''
TensorFlow installation not found - running with reduced feature set.
Serving TensorBoard on localhost; to expose to the network, use a proxy or pass --bind_all
TensorBoard 2.11.2 at http://localhost:6006/ (Press CTRL+C to quit)
'''

指定端口

1
tensorboard --logdir=logs --port=6007

访问端口,显示图像

image-20230720101433132

绘制y=2x

1
2
for i in range(100):
writer.add_scalar("y = 2x", 2*i, i)
image-20230720101628747

如果不改变add_scalar()函数的标题只改变参数

1
2
for i in range(100):
writer.add_scalar("y = 2x", 3*i, i)
image-20230720101754325

image-20230720101845019

向writer中写入新的事件,同时也记录了上一个事件

解决方法:

一、删除logs下的文件,重新启动程序

二、创建子文件夹,也就是说创建新的SummaryWriter(“新文件夹”)

8 TensorBoard的使用(二)add image()的使用(常用来观察训练结果)

控制台输入

1
2
3
4
5
6
7
image_path = "data/train/ants_image/0013035.jpg"
from PIL import Image
# 读取图片
img = Image.open(image_path)
# 查看类型
print(type(img))
# <class PIL.JpegImagePlugin.JpegImageFile'>

利用numpy.array(),对PIL图片进行转换

NumPy型图片是指使用NumPy库表示和处理的图像。NumPy是一个广泛使用的Python库,用于科学计算和数据处理。它提供了一个多维数组对象(ndarray),可以用于存储和操作大量的数值数据。在图像处理领域中,NumPy数组通常用来表示图像的像素值。

NumPy数组可以是一维的(灰度图像)或二维的(彩色图像)。对于彩色图像,通常使用三维的NumPy数组表示,其中第一个维度表示图像的行数,第二个维度表示图像的列数,第三个维度表示图像的通道数(例如,红、绿、蓝通道)

控制台

1
2
3
4
import numpy as np
img_array = np.array(img)
print(type(img_array))
# <class 'numpy.ndarray'>

文件内

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 从torch.utils.tensorboard模块中导入SummaryWriter类
from torch.utils.tensorboard import SummaryWriter
import numpy as np
from PIL import Image

# 将事件和文件存储到"logs"文件夹下
writer = SummaryWriter("logs")
image_path = "data/train/ants_image/0013035.jpg"
img_PIL = Image.open(image_path)
img_array = np.array(img_PIL)
print(type(img_array))
# (H,W,C)——(高度,宽度,通道)
print(img_array.shape)
# 需要指定格式
writer.add_image("test", img_array, 1, dataformats='HWC' )

从PIL到numpy, 需要在add image()中指定shape中每一个数字/维表示的含义。

打开端口,显示图像

image-20230720104855434

添加蜜蜂图片,修改步长为2

1
2
image_path = "data/train/bees_image/16838648_415acd9e3f.jpg"
writer.add_image("test", img_array, 2, dataformats='HWC' )
image-20230720105220800

更换标题

1
writer.add_image("train", img_array, 1, dataformats='HWC' )

![image-20230720105351794](https://cdn.jsdelivr.net/gh/techniquenotes/photohouse@main/Pytorch/Learning note/Day2202307201726332.png)

9 Transforms 的使用(一)

transforms结构及用法

image-20230720112701203

ctrl+p可提示函数需要什么参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from PIL import Image
from torchvision import transforms

# 通过transform.ToTensor去解决两个问题
# 1、transform该如何使用
# 2、为什么需要Tensor这种数据类型

img_path = "train/ants_image/0013035.jpg"
img = Image.open(img_path)
print(img)
# 输出:<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x1DCFAD7CFC8>
# 创建Totensor对象
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)

print(tensor_img)
'''
输出:
tensor([[[0.3137, 0.3137, 0.3137, ..., 0.3176, 0.3098, 0.2980],
[0.3176, 0.3176, 0.3176, ..., 0.3176, 0.3098, 0.2980],
[0.3216, 0.3216, 0.3216, ..., 0.3137, 0.3098, 0.3020],
...,
[0.3412, 0.3412, 0.3373, ..., 0.1725, 0.3725, 0.3529],
[0.3412, 0.3412, 0.3373, ..., 0.3294, 0.3529, 0.3294],
[0.3412, 0.3412, 0.3373, ..., 0.3098, 0.3059, 0.3294]],

[[0.5922, 0.5922, 0.5922, ..., 0.5961, 0.5882, 0.5765],
[0.5961, 0.5961, 0.5961, ..., 0.5961, 0.5882, 0.5765],
[0.6000, 0.6000, 0.6000, ..., 0.5922, 0.5882, 0.5804],
...,
[0.6275, 0.6275, 0.6235, ..., 0.3608, 0.6196, 0.6157],
[0.6275, 0.6275, 0.6235, ..., 0.5765, 0.6275, 0.5961],
[0.6275, 0.6275, 0.6235, ..., 0.6275, 0.6235, 0.6314]],

[[0.9137, 0.9137, 0.9137, ..., 0.9176, 0.9098, 0.8980],
[0.9176, 0.9176, 0.9176, ..., 0.9176, 0.9098, 0.8980],
[0.9216, 0.9216, 0.9216, ..., 0.9137, 0.9098, 0.9020],
...,
[0.9294, 0.9294, 0.9255, ..., 0.5529, 0.9216, 0.8941],
[0.9294, 0.9294, 0.9255, ..., 0.8863, 1.0000, 0.9137],
[0.9294, 0.9294, 0.9255, ..., 0.9490, 0.9804, 0.9137]]])
'''

10Transforms的使用(二)

image-20230720113024746

Tensor包括深度学习需要的参数

下载Opencv

终端输入

1
pip install opencv-python

控制台

1
2
import cv2
cv_img = cv2.imread(img_path)

利用Tensor_img显示图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms

img_path = "train/ants_image/0013035.jpg"
img = Image.open(img_path)

writer = SummaryWriter("logs")
# 输出:<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x1DCFAD7CFC8>
# 创建Totensor对象
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)

writer.add_image("Tensor_img", tensor_img)

writer.close()

终端输入

1
tensorboard --logdir=logs

打开端口,显示图片

image-20230720115601972

11 常见的Transforms(一)

image-20230720141126141

Pytorch中call()的用法

1
2
3
4
5
6
7
8
9
10
11
class Person:
def __call__(self, name):
print("__call__" + "hello" + name)

def hello(self, name):
print("hello"+name)

person = Person()
person("zhangsan")
person.hello("list")
# __call__可以采用对象(参数)的方式调用,不用加.方法名

ToTensor的使用

1
2
3
4
5
6
7
8
9
10
11
12
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms

writer = SummaryWriter("logs")
img = Image.open("train/ants_image/0013035.jpg")
print(img)

trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image("Totensor", img_tensor)
writer.close()

Normalize() 归一化 的使用

image-20230720143339908

mean是均值,std是标准差

1
2
3
4
5
6
7
8
9
10
11
# 每个通道都有均值和标准差
print(img_tensor[0][0][0])
trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
img_norm = trans_norm(img_tensor)
print((img_norm[0][0][0]))
'''
输出
tensor(0.3137)
tensor(-0.3725)
0.3137*2-1=-0.3725(四舍五入后结果)
'''

输出归一化结果

1
writer.add_image("Normalize", img_norm)
image-20230720143837709

12 常见的Transforms(二)

Resize()的使用

1
2
3
4
5
6
7
8
9
print(img.size)
# Resize有两个括号(h,w)
trans_resize = transforms.Resize((480, 480))
img_resize = trans_resize(img)
print(img_resize)
'''
输出
(768, 512)
<PIL.Image.Image image mode=RGB size=480x480 at 0x1C6224EBE88>'''

将PIL类型的img_resize转为tensor类型

1
2
3
4
5
6
7
8
9
print(img.size)
# Resize有两个括号(h,w)
trans_resize = transforms.Resize((480, 480))
# img PIL -> resize -> img_resize PIL
img_resize = trans_resize(img)
# img_resieze PIL -> totensor -> img_resize tensor
img_resize = trans_totensor(img_resize)
writer.add_image("Resize", img_resize, 0)
print(img_resize)

图片大小改变

image-20230720150314504

Compose()的使用

将不同的操作组合起来,按顺序执行。前一步的输出是下一步的输入,要对应。

Compose()中的参数需要是一个列表。Python中,列表的表示形式为[数据1,数据2,…]。在Composel中,数据需要是transforms类型,所以得到,Compose([transforms参数1,transforms参数2,…])

RandomCrop()随机裁剪的用法

1
2
3
4
5
trans_random = transforms.RandomCrop(512)
trans_compose_2 = transforms.Compose([trans_random, trans_totensor])
for i in range(10):
img_crop = trans_compose_2(img)
writer.add_image("RandomCrop", img_crop, i)
image-20230720152147175

总结使用方法

  • 关注输入和输出类型
  • 多看官方文档
  • 关注方法需要什么参数
  • 不知道返回值的时候
    • print()
    • print(type())
    • debug

13 torchvision中的数据集使用

下载训练集和测试集

1
2
3
4
5
6
import torchvision

# root表示数据集路径;train为true表示训练集,false表示测试集;download为true会自动从官网下载
train_set = torchvision.datasets.CIFAR10(root="./dataset", train=True, download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset", train=False, dowmload=True)

可以用迅雷加快下载速度

1
2
3
print(test_set[0])
# 表示有img 和 target两个属性
# 输出(<PIL.Image.Image image mode=RGB size=32x32 at 0x22BF14AA548>, 3)

classes内表示每种target对应哪种类别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
print(test_set.classes)
img, target = test_set[0]
print(img)
print(target)
# target对应的类型
print(test_set.classes[target])
# 显示图片
img.show()
'''
输出
['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
<PIL.Image.Image image mode=RGB size=32x32 at 0x2622292ABC8>
3
cat
'''

添加Transform参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import torchvision
from torch.utils.tensorboard import SummaryWriter

dataset_transform = torchvision.transforms.Compose([
torchvision.transforms.ToTensor()

])
# root表示数据集路径;train为true表示训练集,false表示测试集;download为true会自动从官网下载
train_set = torchvision.datasets.CIFAR10(root="./dataset", train=True, transform=dataset_transform, download=True)
test_set = torchvision.datasets.CIFAR10(root="./dataset", train=False, transform=dataset_transform, download=True)

print(test_set[0])
writer = SummaryWriter("p10")
for i in range(10):
img, target = test_set[i]
writer.add_image("test_set", img, i)

writer.close()
image-20230720161746404

14 DataLoader的使用

测试数据集中第一张图片及target

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import  torchvision
from torch.utils.data import DataLoader

# 准备的测试数据集
test_data = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)

test_loader = DataLoader(dataset=test_data, batch_size=4, shuffle=True, num_workers=0, drop_last=False)

# 测试数据集中第一张图片及target
img, target = test_data[0]
print(img.shape)
print(target)
'''
torch.Size([3, 32, 32])
3
'''
image-20230720164801159

理解batch_size

1
2
3
4
5
6
7
8
9
10
for data in test_loader:
imgs, targets = data
print(imgs,shape)
print(targets)
'''
# 每次循环取4张图片,每张图片3个通道,32*32
torch.Size([4, 3, 32, 32])
# 每张图片的target
tensor([0, 3, 0, 2])
'''

更改batch_size=64

1
2
3
4
5
6
7
8
9
10
writer = SummaryWriter("dataloader")
step = 0
# 每次取64张图片
for data in test_loader:
imgs, targets = data
# 注意是add_images
writer.add_images("test_data", imgs, step)
step = step + 1

writer.close()
image-20230720171254181

drop_last设置为false,所以不会丢掉数量小于batch_seze的组。

理解shuffle

添加epoch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# shuffle设置为false
test_loader = DataLoader(dataset=test_data, batch_size=64, shuffle=False, num_workers=0, drop_last=False)

for epoch in range(2):
writer = SummaryWriter("dataloader")
step = 0
for data in test_loader:
imgs, targets = data
writer.add_images("Epoch: {}".format(epoch), imgs, step)
step = step + 1

writer.close()
'''
"Epoch: {}".format(epoch)是一种字符串格式化的方法,在Python中常用于将变量的值插入到字符串中的特定位置。
在这个例子中,{}是一个占位符,用于表示待插入变量的位置。".format(epoch)"表示通过.format()方法将变量epoch的值插入到占位符的位置。所生成的最终字符串将包含"Epoch: "和epoch的值。
举个例子,如果epoch的值是10,那么该代码将生成字符串"Epoch: 10"。
'''

shuffle为false时两轮图片加载中随机选取结果相同

image-20230720172220235