Pytorch学习2
transforms
重点:看官方注释文档
参考:https://www.cnblogs.com/zhangxiann/p/13570884.html
ToTensor()
HWC⟶CHW,将所有数除以255,将数据归一化到【0,1】
补充:类的使用
class Person:
def __call__(self, name):
print('__call__' + ' Hello ' + name)
def hello(self, name):
print('hello ' + name)
person = Person()
person("zhangsan")
person.hello('lisi')
输出:
__call__ Hello zhangsan
hellolisi
第一个person调用了__call__
第二个person调用了Person类下的hello函数
有了上面这个类的使用例子就更容易理解ToTensor的使用方法:
类似于将一个变量转换为函数,下面将trans_totensor转换成了类函数来使用,实现将PIL图片形式转换为tensor形式
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
img = Image.open("hymenoptera_data/train/ants/0013035.jpg")
print(img)
trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image("Totensor", img_tensor)
writer.close()
Normalize()
规范化到[-1, 1]:transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
img = Image.open("hymenoptera_data/train/ants/0013035.jpg")
print(img)
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()
输出
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x229C91B9D90>
tensor(0.3137)
tensor(-0.3725)
Resize()
调整PIL Image对象的尺寸
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
img = Image.open("hymenoptera_data/train/ants/0013035.jpg")
print(img)
print(img.size)
trans_resize = transforms.Resize((512, 512))
img_resize = trans_resize(img)
print(img_resize.size)
img_resize = trans_totensor(img_resize)
writer.close()
输出
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=768x512 at 0x2C4637341C0>
(768, 512)
(512, 512)
补充:
- 单个参数时:按图片长宽比缩放短边到参数
- 恢复原状时:w, h = img.size记录原来的宽和高,resize时需要反过来:transforms.Resize([h, w])
- resize输入的顺序是宽和长(高)
Compose()
组合多个步骤:eg 先缩放图片(Resize)再转换为tensor形式(ToTensor)
参数为一个列表,数据类型为transforms,形式为[transforms参数1, transforms参数2, ……]
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
img = Image.open("hymenoptera_data/train/ants/0013035.jpg")
print(img)
# ToTensor
trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image("Totensor", img_tensor)
# Resize
print(img.size)
trans_resize = transforms.Resize((100, 512))
img_resize = trans_resize(img)
print(img_resize.size)
img_resize = trans_totensor(img_resize)
writer.add_image("Resize", img_resize, 0)
# Compose
trans_resize_2 = transforms.Resize(500)
trans_compose = transforms.Compose([trans_resize_2, trans_totensor])
img_resize_2 = trans_compose(img)
writer.add_image("Resize", img_resize_2, 1)
writer.close()
RandomCrop
在一个随机的位置进行裁剪,一个参数表示长宽一样
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter("logs")
img = Image.open("hymenoptera_data/train/ants/0013035.jpg")
print(img)
trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image("Totensor", img_tensor)
# RandomCrop
trans_random = transforms.RandomCrop(512)
trans_compose = transforms.Compose([trans_random, trans_totensor])
for i in range(10):
img_crop = trans_compose(img)
writer.add_image("Random", img_crop, i)
writer.close()
torchvision数据集的使用
import torchvision
from PIL import Image
from torchvision import transforms
from torch.utils.tensorboard import SummaryWriter
dataset_transform = torchvision.transforms.Compose([
torchvision.transforms.ToTensor()
])
# 若根目录不存在数据集,则下载数据集;transforms参数进行transforms处理
train_set = torchvision.datasets.CIFAR10(root='./dataset', train=True, download=True, transform=dataset_transform)
test_set = torchvision.datasets.CIFAR10(root='./dataset', train=True, download=True, transform=dataset_transform)
writer = SummaryWriter("p10")
for i in range(10):
img, target = test_set[i]
print(target)
writer.add_image("test_set", img, i)
writer.close()
Dataloader的使用
将自定义的Dataset根据batch_size大小、是否shuffle等封装成一个Batch Size大小的Tensor,用于后面的训练。
参数
- dataset ( Dataset ) – 从中加载数据的数据集。
- batch_size ( int , optional ) – 每批要加载多少样本(默认值:
1
)。 - shuffle ( bool , optional ) – 设置为
True
在每个 epoch 重新洗牌数据(默认值:)False
。(True相当于随机打乱) - num_workers ( int , optional ) – 用于数据加载的子进程数。
0
表示数据将在主进程中加载。(默认0
:) - drop_last ( bool , optional ) –
True
如果数据集大小不能被批次大小整除,则设置为丢弃最后一个不完整的批次。如果False
数据集的大小不能被批大小整除,那么最后一批将更小。(默认False
:)
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
# 准备数据集
test_data = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor())
test_loader = DataLoader(dataset=test_data, batch_size=4, shuffle=False, num_workers=0, drop_last=True)
writer = SummaryWriter("dataloader")
for epoch in range(2):
step = 0
for data in test_loader:
imgs, targets = data
writer.add_images("Epoch: {}".format(epoch), imgs, step)
step += 1
writer.close()