【我是土堆 - Pytorch教程】 知识点 学习总结笔记(二)

此文章为【我是土堆 - Pytorch教程】 知识点 学习总结笔记(二)包括:TensorBoard的使用(一)、TensorBoard的使用(二)、Transforms的使用(一)、Transforms的使用(二)、 常见的Transforms(一)、常见的Transforms(二)


  学习系列笔记(已完结):

【我是土堆 - Pytorch教程】 知识点 学习总结笔记(一)_耿鬼喝椰汁的博客-CSDN博客

【我是土堆 - Pytorch教程】 知识点 学习总结笔记(二)_耿鬼喝椰汁的博客-CSDN博客

【我是土堆 - Pytorch教程】 知识点 学习总结笔记(三)_耿鬼喝椰汁的博客-CSDN博客

【我是土堆 - Pytorch教程】 知识点 学习总结笔记(四)_耿鬼喝椰汁的博客-CSDN博客

【我是土堆 - Pytorch教程】 知识点 学习总结笔记(五)_耿鬼喝椰汁的博客-CSDN博客


目录

1.TensorBoard的使用(一)

1.1 SummaryWriter类

初始化函数:

Pycharm 使用小技巧

安装TensorBoard

1.2 add_scalar() 方法的使用

例:y=x

 如何打开事件文件?

 例:y=2x

2.TensorBoard的使用(二)

2.1 add_image() 的使用

 2.2 利用opencv(numpy.array())读取图片,获得numpy型图片数据

 代码实战 step1:蚂蚁为例 

 代码实战step2:蜜蜂为例 

3.Transforms的使用(一)(二)

3.1 transforms的结构及用法

结构

搜索结构快捷键:

一些类

使用

3.2 两个问题

问题一:transforms 该如何使用(python)

问题二:为什么我们需要 Tensor 数据类型

3.3 两种读取图片的方式

1.PIL Image

2. numpy.ndarray(通过opencv)

上节课以 numpy.array 类型为例,这节课使用 torch.Tensor 类型:

4. 常见的Transforms(一)

4.1 Compose 的使用

Python中 __call__ 的用法

4.2 ToTensor 的使用

 4.3 ToPILImage 的使用

4.4 Normalize 的使用

 加入step值:

5. 常见的Transforms(二)

 5.1 Resize() 的使用

 5.2 Compose() 的使用

 5.3 RandomCrop() 的使用

(1)以 int 为例: 

 (2)以 sequence 为例:

总结使用方法


1.TensorBoard的使用(一)

  • add_scalar() 的使用   (常用来绘制 train/val loss)
  • add_image() 的使用   (常用来观察训练结果)

学 TensorBoard 目的:

  • 训练过程中loss是如何变化的
  • 模型在不同阶段的输出

1.1 SummaryWriter类

导入TensorBoard中的类 SummaryWriter :

from torch.utils.tensorboard import SummaryWriter

PyCharm查看一个类如何使用(功能):在PyCharm中,按住Ctrl键,把鼠标移到类上,点击自动跳转。

是一个直接向 log_dir 文件夹写入的事件文件,可以被 TensorBoard 进行解析

初始化函数:

def __init__(self, log_dir=None):

# 实例化SummaryWriter类
writer = SummaryWriter("logs")   # 创建一个实例,把对应的事件文件存储到logs文件夹下

主要用到两个方法:

writer.add_image()  #添加image
writer.add_scalar() #添加数
 
writer.close()

Pycharm 使用小技巧

1.ctrl + / 可将代码注释掉。

2.按 ctrl 与函数名可直接查看其功能。

3.按 Tab 键可进行缩进。

安装TensorBoard

在 Anaconda 命令行中激活 pytorch 环境,或直接在 PyCharm 的 Terminal 的 pytorch 环境中安装

输入:

pip install tensorboard

即可安装成功

1.2 add_scalar() 方法的使用

def add_scalar(
        self,
        tag,
        scalar_value,
        global_step=None,
        walltime=None,
        new_style=False,
        double_precision=False,
    ):

添加一个标量数据到 Summary 当中,需要参数

  • tagData指定方式,类似于图表的title
  • scalar_value需要保存的数值(y轴)
  • global_step训练到多少步(x轴)

例:y=x

from torch.utils.tensorboard import SummaryWriter   #导入SummaryWriter类
 
#创建实例
writer=SummaryWriter("logs")   #把对应的事件文件存储到logs文件夹下
 
#两个方法
# writer.add_image()
# y=x
for i in range(100):
    writer.add_scalar("y=x",i,i)
 
writer.close()

运行后多了一个logs文件夹,下面是TensorBoard的一些事件文件,如图: 

 如何打开事件文件?

在 Terminal 里输入:

tensorboard --logdir=logs  # logdir=事件文件所在文件夹名

结果如图:

 点击链接:

 为了防止和别人冲突(一台服务器上有好几个人训练,默认打开的都是6006端口),也可以指定端口,命令如下:

​tensorboard --logdir=logs --port=6007

结果如图:

 例:y=2x

from torch.utils.tensorboard import SummaryWriter   #导入SummaryWriter类
 
#创建实例
writer=SummaryWriter("logs")   #把对应的事件文件存储到logs文件夹下
 
#两个方法
# writer.add_image()
# y=2x
for i in range(100):
    writer.add_scalar("y=2x",2*i,i)  # 标题、y轴、x轴
 
writer.close()

 title 和 y 不一致的情况:

下面这种情况不正确: 

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

如何解决?

把logs文件夹下的所有文件删掉,程序删掉,重新开始

或:重新写一个子文件,即创建新的 SummaryWriter("新文件夹")

删掉logs下的文件,重新运行代码,在 Terminal 里按 Ctrl+C ,再输入命令:

​tensorboard --logdir=logs --port=6007

就可以出现名字为y=2x,但实际纵坐标是y=3x数值的图像

以上即是显示 train_loss 的一个方式

2.TensorBoard的使用(二)

2.1 add_image() 的使用

def add_image(self, tag, img_tensor, global_step=None):
  • tag:对应图像的title
  • img_tensor:图像的数据类型,只能是torch.Tensor、numpy.array、string/blobnaem
  • global_step:训练步骤,int 类型

 例子:

 在Python控制台输出图片类型:

# 打开控制台,其位置就是项目文件夹所在的位置
# 故只需复制相对地址
 
image_path = "data/train/ants_image/0013035.jpg"
 
from PIL import Image
img = Image.open(image_path)
print(type(img))

 PIL.格式不符合要求。如何将PIL类型转化成numpy类型下节说

 2.2 利用opencv(numpy.array()读取图片,获得numpy型图片数据

import numpy as np
img_array=np.array(img)
print(type(img_array))   # numpy.ndarray

在Python控制台输出图片类型:

 代码实战 step1:蚂蚁为例 

from torch.utils.tensorboard import SummaryWriter   #导入SummaryWriter类
import numpy as np
from PIL import Image
 
#创建实例
writer=SummaryWriter("logs")   #把对应的事件文件存储到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))
print(img_array.shape)   #(512,768,3)  即(H,W,C)(高度,宽度,通道)
 
writer.add_image("test",img_array,1, dataformats='HWC')  # 第1步
 
writer.close()

运行结果:

 代码实战step2:蜜蜂为例 

from torch.utils.tensorboard import SummaryWriter   #导入SummaryWriter类
import numpy as np
from PIL import Image
 
#创建实例
writer=SummaryWriter("logs")   #把对应的事件文件存储到logs文件夹下
image_path="data/train/bees_image/16838648_415acd9e3f.jpg"
img_PIL=Image.open(image_path)
img_array=np.array(img_PIL)
print(type(img_array))
print(img_array.shape)   #(512,768,3)  即(H,W,C)(高度,宽度,通道)
 
writer.add_image("test",img_array,2, dataformats='HWC')   # 第2步
 
writer.close()

输出结果如下,并产生滑块:

在一个title下,通过滑块显示每一步的图形,可以直观地观察训练中给model提供了哪些数据,或者想对model进行测试时,可以看到每个阶段的输出结果

如果想要单独显示,重命名一下title即可,即 writer.add_image() 的第一个字符串类型的参数


3.Transforms的使用(一)(二)

对图片进行一些变换

3.1 transforms的结构及用法

结构

按住Ctrl,看 transforms.py文件(工具箱),它定义了很多 class文件(工具)

搜索结构快捷键:

File—> Settings—> Keymap—> 搜索 structure(快捷键 Alt+7

一些类

  •  Compose类结合不同的transforms
  • ToTensor类把一个PIL的Image或者numpy数据类型的图片转换成 tensor 的数据类型
  • ToPILImage类把一个图片转换成PIL Image
  • Normalize类归一化,标准化,用来对数据预处理
  • Resize类尺寸变换
  • CenterCrop类中心裁剪
  • Regularize类正则化,防止模型过拟合的技术

使用

  • transforms.py   工具箱
  • 工具箱里放着 totensor / resize等类   工具

拿一些特定格式的图片,经过工具(class文件)后,就会输出我们想要的图片变换的结果。

3.2 两个问题

python的用法 ——> tensor数据类型
通过 transforms.ToTensor去解决两个问题

  1. Transforms该如何使用
  2. Tensor数据类型与其他图片数据类型有什么区别?为什么需要Tensor数据类型
from PIL import Image
from torchvision import transforms
 
# 绝对路径 D:\PycharmProjects\pythonProject\pytorchlearn\data\train\ants_image\0013035.jpg
# 相对路径 data/train/ants_image/0013035.jpg
img_path="data/train/ants_image/0013035.jpg"   #用相对路径,绝对路径里的\在Windows系统下会被当做转义符
# img_path_abs="C:\Users\11842\Desktop\Learn_torch\data\train\ants_image\0013035.jpg",双引号前加r表示转义
 
img = Image.open(img_path)   #Image是Python中内置的图片的库
print(img)  # PIL类型

问题一:transforms 该如何使用(python)

从transforms中选择一个class,对它进行创建,对创建的对象传入图片,即可返回出结果 

ToTensor将一个 PIL Image 或 numpy.ndarray 转换为 tensor的数据类型 

实战 

Ctrl+P可以提示函数里需要填什么参数

# 1、Transforms该如何使用
tensor_trans = transforms.ToTensor()  #从工具箱transforms里取出ToTensor类,返回tensor_trans对象
tensor_img=tensor_trans(img)   #创建出tensor_trans后,传入其需要的参数,即可返回结果
print(tensor_img)

运行输出:

问题二:为什么我们需要 Tensor 数据类型

在Python Console输入:

from PIL import Image
from torchvision import transforms
 
img_path= "data/train/ants_image/0013035.jpg"  
img = Image.open(img_path)   
 
tensor_trans = transforms.ToTensor() 
tensor_img = tensor_trans(img)  

右侧属性栏: 

 打开img,即用Python内置的函数读取的图片,具有的参数有:

再打开tensor_img,看一下它有哪些参数: 

Tensor 数据类型包装了反向神经网络所需要的一些理论基础的参数,如:_backward_hooks、_grad等(先转换成Tensor数据类型,再训练) 

3.3 两种读取图片的方式

1.PIL Image

from PIL import Image
img_path = "xxx"
img = Image.open(img_path)
img.show()

2. numpy.ndarray(通过opencv)

import cv2
cv_img=cv2.imread(img_path)

上节课以 numpy.array 类型为例,这节课使用 torch.Tensor 类型:

from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
 
# python的用法 ——> tensor数据类型
# 通过 transforms.ToTensor去解决两个问题
# 1、Transforms该如何使用
# 2、Tensor数据类型与其他图片数据类型有什么区别?为什么需要Tensor数据类型
 
# 绝对路径 C:\Users\11842\Desktop\Learn_torch\data\train\ants_image\0013035.jpg
# 相对路径 data/train/ants_image/0013035.jpg
img_path="data/train/ants_image/0013035.jpg"   #用相对路径,绝对路径里的\在Windows系统下会被当做转义符
# img_path_abs="C:\Users\11842\Desktop\Learn_torch\data\train\ants_image\0013035.jpg",双引号前加r表示转义
img = Image.open(img_path)   #Image是Python中内置的图片的库
#print(img)
 
writer = SummaryWriter("logs")
 
# 1、Transforms该如何使用
tensor_trans = transforms.ToTensor()  #从工具箱transforms里取出ToTensor类,返回tensor_trans对象
tensor_img = tensor_trans(img)   #创建出tensor_trans后,传入其需要的参数,即可返回结果
#print(tensor_img)
 
writer.add_image("Tensor_img",tensor_img)  # .add_image(tag, img_tensor, global_step)
# tag即名称
# img_tensor的类型为torch.Tensor/numpy.array/string/blobname
# global_step为int类型
 
writer.close()

运行后,在 Terminal 里输入:

tensorboard --logdir=logs

进入网址后可以看到图片:


4. 常见的Transforms(一)

  • 输入
  • 输出
  • 作用

图片有不同的格式,打开方式也不同

图片格式 打开方式
PIL Image.open()   ——Python自带的图片打开方式
tensor ToTensor()
narrays cv.imread()   ——Opencv

4.1 Compose 的使用

把不同的 transforms 结合在一起,后面接一个数组,里面是不同的transforms

Example:图片首先要经过中心裁剪,再转换成Tensor数据类型
        >>> transforms.Compose([
        >>>     transforms.CenterCrop(10),
        >>>     transforms.PILToTensor(),
        >>>     transforms.ConvertImageDtype(torch.float),
        >>> ])

Python中 __call__ 的用法

class Person:
    def __call__(self, name):   #下划线__表示为内置函数
        print("__call__"+"Hello "+name)
 
    def hello(self,name):
        print("hello"+name)
 
person = Person()
person("zhangsan")
person.hello("lisi")

输出结果如下:

 按 Ctrl+p,会提示需要什么参数

4.2 ToTensor 的使用

把 PIL Image 或 numpy.ndarray 类型转换为 tensor 类型(TensorBoard 必须是 tensor 的数据类型)(运行前要先把之前的logs进行删除)

from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms

writer = SummaryWriter("logs")
img = Image.open("images/pytorch.png")
print(img)  # 可以看到类型是PIL

# ToTensor的使用
trans_totensor = transforms.ToTensor()  # 将类型转换为tensor
img_tensor = trans_totensor(img)  # img变为tensor类型后,就可以放入TensorBoard当中
writer.add_image("ToTensor", img_tensor)
writer.close()

运行后,在 Terminal 里输入:

tensorboard --logdir=logs

进入网址后可以看到图片: 

 4.3 ToPILImage 的使用

把 tensor 数据类型或 ndarray 类型转换成 PIL Image

4.4 Normalize 的使用

用平均值/标准差归一化 tensor 类型的 image(输入)

图片RGB三个信道,将每个信道中的输入进行归一化

output[channel] = (input[channel] - mean[channel]) / std[channel]

设置 mean 和 std 都为0.5,则 output= 2*input -1。如果 input 图片像素值为0~1范围内,那么结果就是 -1~1之间

#Normalize的使用
print(img_tensor[0][0][0])  # 第0层第0行第0列
trans_norm = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])  # mean,std,因为图片是RGB三信道,故传入三个数
img_norm = trans_norm(img_tensor)  # 输入的类型要是tensor
print(img_norm[0][0][0])
writer.add_image("Normalize",img_norm)

输出结果:

刷新网页: 

 加入step值:

第一步

#Normalize的使用
print(img_tensor[0][0][0])  # 第0层第0行第0列
trans_norm = transforms.Normalize([4,6,7],[3,2,6])  # mean,std,因为图片是RGB三信道,故传入三个数
img_norm = trans_norm(img_tensor)  # 输入的类型要是tensor
print(img_norm[0][0][0])
writer.add_image("Normalize",img_norm,1)#第一步

第二步

#Normalize的使用
print(img_tensor[0][0][0])  # 第0层第0行第0列
trans_norm = transforms.Normalize([2,6,7],[1,2,2])  # mean,std,因为图片是RGB三信道,故传入三个数
img_norm = trans_norm(img_tensor)  # 输入的类型要是tensor
print(img_norm[0][0][0])
writer.add_image("Normalize",img_norm,2)#第二步

刷新网页:

5. 常见的Transforms(二)

 5.1 Resize() 的使用

 输入:PIL Image      将输入转变到给定尺寸

  • 序列(h,w)高度,宽度
  • 一个整数不改变高和宽的比例,只单纯改变最小边和最长边之间的大小关系。之前图里最小的边将会匹配这个数(等比缩放)

PyCharm小技巧设置:忽略大小写,进行提示匹配

一般情况下,你需要输入R,才能提示出Resize
我们想设置,即便你输入的是r,也能提示出Resize,也就是忽略了大小写进行匹配提示
File—> Settings—> 搜索case—> Editor-General-Code Completion-去掉Match case前的√

—>Apply—>OK

返回值还是 PIL Image

#Resize的使用
print(img.size)  # 输入是PIL.Image
 
trans_resize = transforms.Resize((512,512))
#img:PIL --> resize --> img_resize:PIL
img_resize = trans_resize(img)  #输出还是PIL Image
 
#img_resize:PIL --> totensor --> img_resize:tensor(同名,覆盖)
img_resize = trans_totensor(img_resize)
 
writer.add_image("Resize",img_resize,0)
print(img_resize)

图片进行了缩放: 

 5.2 Compose() 的使用

Compose() 中的参数需要是一个列表,Python中列表的表示形式为[数据1,数据2,...]

在Compose中,数据需要是transforms类型,所以得到Compose([transforms参数1,transforms参数2,...])

#Compose的使用(将输出类型从PIL变为tensor类型,第二种方法)
 
trans_resize_2 = transforms.Resize(512)  # 将图片短边缩放至512,长宽比保持不变
 
# PIL --> resize --> PIL --> totensor --> tensor
#compose()就是把两个参数功能整合,第一个参数是改变图像大小,第二个参数是转换类型,前者的输出类型与后者的输入类型必须匹配
 
trans_compose = transforms.Compose([trans_resize_2,trans_totensor])
img_resize_2 = trans_compose(img)   # 输入需要是PIL Image
writer.add_image("Resize",img_resize_2,1)

输出结果:

 5.3 RandomCrop() 的使用

 随机裁剪,输入PIL Image

参数size:

  • sequence:(h,w) 高,宽
  • int:裁剪一个该整数×该整数的图像

(1)以 int 为例: 

#RandomCrop()的使用
trans_random = transforms.RandomCrop(512)
trans_compose_2 = transforms.Compose([trans_random,trans_totensor])
for i in range(10):  #裁剪10个
    img_crop = trans_compose_2(img)  # 输入需要是PIL Image
    writer.add_image("RandomCrop",img_crop,i)

 (2)以 sequence 为例:

#RandomCrop()的使用
trans_random = transforms.RandomCrop((200,500))
trans_compose_2 = transforms.Compose([trans_random,trans_totensor])
for i in range(10):  #裁剪10个
    img_crop = trans_compose_2(img)
    writer.add_image("RandomCropHW",img_crop,i)


总结使用方法

1.关注输入和输出类型

2.多看官方文档

3.关注方法需要什么参数:参数如果设置了默认值,保留默认值即可,没有默认值的需要指定(看一下要求传入什么类型的参数)

4.不知道变量的输出类型可以

  • 直接print该变量
  • print(type()),看结果里显示什么类型
  • 断点调试 dubug

最后要 totensor,在 tensorboard 看一下结果(tensorboard需要tensor数据类型进行显示)


这篇课程的学习和总结到这里就结束啦,如果有什么问题可以在评论区留言呀~

如果帮助到大家,可以一键三连支持下~


 学习系列笔记(已完结):

【我是土堆 - Pytorch教程】 知识点 学习总结笔记(一)_耿鬼喝椰汁的博客-CSDN博客

【我是土堆 - Pytorch教程】 知识点 学习总结笔记(二)_耿鬼喝椰汁的博客-CSDN博客

【我是土堆 - Pytorch教程】 知识点 学习总结笔记(三)_耿鬼喝椰汁的博客-CSDN博客

【我是土堆 - Pytorch教程】 知识点 学习总结笔记(四)_耿鬼喝椰汁的博客-CSDN博客

【我是土堆 - Pytorch教程】 知识点 学习总结笔记(五)_耿鬼喝椰汁的博客-CSDN博客

猜你喜欢

转载自blog.csdn.net/m0_57787115/article/details/129692030