PyTorch深度学习笔记(四)(Transforms的使用)
前言
本节学习Transform的基本使用
Transforms用途
把Transforms当成工具箱的话,里面的class就是不同的工具。例如像totensor、resize这些工具。
Transforms可以将一些特定格式的图片,经过Transforms里面的工具,获得我们想要的结果。
Transforms该如何使用
__call__方法的使用
创建Person类
定义方法__call__,并调用
class Person:
def __call__(self,name):
print("__call__ "+"Hello "+name)
person = Person() # 实例化对象
person("zhangsan") # 调用__call__方法
输出结果
__call__ Hello zhangsan
定义方法hello
class Person:
def hello(self,name):
print("hello "+name)
person = Person() # 实例化对象
person.hello("list") # 调用hello方法
输出结果
hello list
可以看出区别,使用__call__方法的时候直接用对象名加上属性即可调用,使用hello方法的时候还需要用点调用。
全部代码
class Person:
def __call__(self,name):
print("__call__ "+"Hello "+name)
def hello(self,name):
print("hello "+name)
person = Person() # 实例化对象
person("zhangsan") # 调用__call__方法
person.hello("list") # 调用hello方法
需要Tensor数据类型原因
Tensor有一些属性,比如反向传播、梯度等属性,它包装了神经网络需要的一些属性。
以下代码是在tensorboard中展示transforms.ToTensor工具所处理过的tensor类型图片代码:
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from PIL import Image
import cv2
img_path = "dataset/val/bees/10870992_eebeeb3a12.jpg"
img = Image.open(img_path)
writer = SummaryWriter("logs")
tensor_trans = transforms.ToTensor()
img_tensor = tensor_trans(img)
writer.add_image("Temsor_img",img_tensor)
writer.close()
Tensorboard界面如下:

常见的Transforms工具
Transforms的工具主要关注他的输入、输出、作用。
Transforms.ToTensor使用
从transforms中取出工具ToTensor(创建具体的工具)
trans_totensor = transforms.ToTensor()
填入ToTensor工具所需要输入的东西(使用工具)
img_tensor = trans_totensor(img)
以下是完整代码:
from torchvision import transforms
from PIL import Image
writer = SummaryWriter("logs")
img_path = "dataset/train/ants_image/0013035.jpg"
img = Image.open(img_path)
#ToTensor
trans_totensor = transforms.ToTensor() # 创建 transforms.ToTensor类 的实例化对象
img_tensor = trans_totensor(img) # 调用 transforms.ToTensor类 的__call__的魔术方法
print(img_tensor)
Normanize归一化
传入均值和标准差,因为图片按照 tensor 类型的存储顺序存成 C H W(通道数,长,宽)的图片,所以提供三个均值和三个标准差
trans_norm = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])#input[channel]=(input[chnnel]-mean[channel])/std[channel]
img_norm = trans_norm(img_tensor)
归一化计算公式:input[channel]=(input[chnnel]-mean[channel])/std[channel]
所以,假设均值和标准差都设置在0.5,则input=(input-0.5)/0.5=2*input-1,若input图片的像素值设定在0到1之内,即input=[0,1],则最后结果在-1到1之间,即result=[-1,1]
print(img_tensor[0][0][0])
print(img_norm[0][0][0])
前后输出结果对比
tensor(0.3137)
tensor(-0.3725)
转为tensor类型后在Tensorboard中打开后看到的效果

可以看出归一化操作前后,图片明显不同
完整代码
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
img_path = "dataset/train/ants_image/0013035.jpg"
img = Image.open(img_path)
#Normalize
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])
writer.add_image("Normalize",img_norm)
writer.close()
Resize裁剪
Resize裁剪方法一(指定裁剪大小)
PIL数据类型的 img -> resize到尺寸为512*512的大小 -> PIL数据类型的 img_resize
trans_resize = transforms.Resize((512,512))
img_resize = trans_resize(img)
想在tensorboard显示,则需要将PIL类型转换为tensor类型
PIL 数据类型的 img_resize -> ToTensor ->tensor数据类型的 img_resize (变量名相同,值覆盖)
img_resize = trans_totensor(img_resize)
在Tensorboard中打开的效果

可以看出裁剪后的效果
完整代码
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
img_path = "dataset/train/ants_image/0013035.jpg"
img = Image.open(img_path)
#Resize1
print(img.size)
trans_resize = transforms.Resize((512,512))
img_resize = trans_resize(img)
img_resize = trans_totensor(img_resize)
print(img_resize)
writer.add_image("Resize",img_resize,0)
writer.close()
Resize裁剪方法二(等比缩放)
等比例变换 and Compose的使用
等比缩放:
trans_resize_2 = transforms.Resize(512)
如果输入为一个整数,则图像的短边会被裁剪到这个大小,长边同比例缩放。例如,如果高度>宽度,输入整数为512,那么图像会被按照以下格式裁剪(512*高度/宽度,512)。
Compose函数中的两个参数表示按顺序执行的图像变换,后面一个参数的输入为前面一个参数的输出,先将图像调整大小为等比例的256像素,然后将PIL Image转换为Tensor格式。
(类似流水线操作:PIL类型的 Image -> 操作:resize(256) -> PIL类型的 Image -> 操作:totensor -> tensor类型的 Image)
trans_compose = transforms.Compose([trans_resize_2, trans_totensor])
img_resize_2 = trans_compose(img)
Compose()中的参数需要的是一个列表。Python中,列表所需要的数据形式是[数据1,数据2,...]。在Compose中,数据需要的是transforms类型数据,所以得到Compose[transforms参数1,transforms参数2,...]。
在Tensorboard中打开的效果
因为是等比例缩小,所以形状没变,但可以看出清晰度降低。
完整代码
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
img_path = "dataset/train/ants_image/0013035.jpg"
img = Image.open(img_path)
#Resize2 and Compose
trans_resize_2 = transforms.Resize(256)
trans_compose = transforms.Compose([trans_resize_2,trans_totensor])
img_resize_2 = trans_compose(img)
writer.add_image("Resize2",img_resize_2,0)
writer.close()
RandomCrop随机裁剪
RandomCrop随机裁剪方式一(等比缩放)
等比例随机裁剪为312*312
trans_random = transforms.RandomCrop(312)
Compose()组合处理图像(裁剪 and tensor转换)
trans_compose_2 = transforms.Compose(trans_random,trans_totensor)
裁剪10块
for i in range(10):
img_crop = trans_compose_2(img)
writer.add_image("RandomCrop",img_crop,i)
在Tensorboard中打开的效果


可以看出随机裁剪效果
完整代码
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
img_path = "dataset/train/ants_image/0013035.jpg"
img = Image.open(img_path)
#RandomCrop1
trans_random = transforms.RandomCrop(312)
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)
writer.close()
RandomCrop随机裁剪方式二(指定大小裁剪)
跟Resize的方法一大致相同,不多赘述
在Tensorboard中打开的效果


可以看出随机裁剪效果
以下是完整代码
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
img_path = "dataset/train/ants_image/0013035.jpg"
img = Image.open(img_path)
#RandomCrop2
trans_random = transforms.RandomCrop((312,100)) # 指定随即裁剪的宽和高
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)
print(img_crop.size())
writer.close()
注意输入输出
看官方文档
关注方法需要什么参数
不知道返回类型的时候 print 、print(type()) 、debug
更多推荐



所有评论(0)