resize操作推荐使用bilinear或者bicubic;
典型的变换流水线
from torchvision.transforms import v2
transforms=v2.Compose([v2.ToImage(),#Convert to tensor,only needed if you had a PIL image
v2.ToDtype(torch.uint8,scale=True),#optional,most input are already uint8 at this point
v2.RandomResizeCrop(size=(224,224),antialias=True),#Or Resize(antialias=True)
v2.ToDtype(torch.float32,scale=True),#Normalize expects float input
v2.Normalize(mean=[0.485,0.456,0.406],std=[0.229,0.224,0.225])])
- 在num_workers>0的torch.utils.data.DataLoader的模块作用下,上述代码将给出典型训练环境中的最好性能;
- 变换对输入步长、内存格式敏感;
- 一些变换对于通道在前的图像具有更快的性能;
- 另一些对通道在后的图像具有更快的性能;
- 变换对于tensor的操作,将保持输入的格式,但根据具体情况,这也不总是期望的;
- 如果追求更快的性能,可能需要自己去尝试;
- 单个变换使用torch.compile()可帮助分解内存格式变量;
- 类似于Resize和RandomResizedCrop的变换,倾向于通道最后的输入,且torch.compile()没有任何优势;
变换类、函数和内核
- 像Resize这样的变化可以作为类来使用;
- 同时对于torchvision.transforms.v2.functional中的resize()函数也可作为类来使用;
- 以上两种情况类似于torch.nn包,同时定义了类和功能等效的函数在torch.nn.functional中;
- 函数的功能支持PIL图像,纯张量格式的输入或者TVTensors;
- resize(imgae_tensor)和resize(boxes)都是有效的;
- 像RandomCrop这样的随机变换当每次被调用时会随机采样参数;
- 但是他们的函数等效(crop())不做任何随机采样,因此具有稍有不同参数;
- 当使用函数API时,get_params()变换类方法被用于执行参数采样;
- torchvision.transforms.v2.functional命名空间也包含称为kernel的对象;
- 这些是低级别的函数实现核心的功能用于特定的类型,比如:resize_bounding_boxes和resized_crop_mask;
- 虽然没有记录,但他们是公开的;
- 如果你要想获得torchscipt support用于bounding box 或mask类型的话,kernel是十分有用的;
Torchscript 支持
- 很多变换类和函数支持torchscript;
- 对于组合变换,使用torch.nn.Sequential而不是Compose:
transforms=torch.nn.Sequential(CenterCrop(10),Normalize((0.485,0.456,0.406),(0.229,0.224,0.225)))
scripted_trtansforms=torch.jit.script(transforms)