目录

一、 Python中内置函数__call__详解

二. ToTensor

三、归一化Normalize

1. Normalize作用

 2. 所需参数

3. 计算方法

3.1 计算公式 

3.2 参数传入0.5的含义 

4. 归一化应用

4.1 步骤  

4.2 代码 

4.3 结果可视化 

4.4 进阶版代码

四、Resize

1. 作用

2.  所需参数

3. 具体使用

3.1 第一种方法

3.2 第二种方法

4. 输出结果

五、Compose

1. 作用 

2. 参数介绍

3. Compose和Resize的结合使用

4. 结果

六、RandomCrop 随机裁剪

1. 作用

2. 参数介绍

3. 具体使用

4. 结果

七、transforms使用总结


小技巧:如何取消在pycharm中敲代码时的大小写匹配

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_python

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_Image_02

一、 Python中内置函数__call__详解

该方法的功能类似于在类中重载 () 运算符,使得类实例对象可以像调用普通函数那样,以“对象名()”的形式使用,而无需使用对象名.方法名方式来调用方法。 

下面使用新建一个CallTest.py文件来测试call方法。

class Person:
    def __call__(self, name):
        print("调用内置__call__方法  "+name)

    def hello(self,name):
        print("调用hello方法  "+name)

p = Person()
p("zhangsan")
p.hello("lisi")

可以看到:

  • 当传入“zhangsan”字符串时,使用的是:对象名()形式进行方法调用,调用了内置call方法。
  • 当传入“lisi”字符串时,使用的是:对象名.方法名()形式进行方法调用,调用的是hello方法。

因此内置call方法可以使用对象名()形式进行调用,更加方便。

二. ToTensor

具体ToTensor的使用可以见上一章笔记:(4条消息) pytorch初学笔记(三)Tranforms的使用_好喜欢吃红柚子的博客 

需要注意的是:

  • ToTensor作用:Convert a ``PIL Image`` or ``numpy.ndarray`` to tensor
  • add_image()方法可接受的图像类型:img_tensor (torch.Tensor, numpy.array, or string/blobname): Image data
     
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms


writer = SummaryWriter("logs")

img = Image.open("image/dog.jpg")
tensor_tool = transforms.ToTensor()
img_tensor = tensor_tool()

writer.add_image("test",img)

三、归一化Normalize

1. Normalize作用

T.Normalize(mean, std)

输入(channel,height,width)形式的tensor,并输入每个channel对应的均值和标准差作为参数,函数会利用这两个参数分别将每层标准化(使数据均值为0,方差为1)后输出。

 2. 所需参数

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_pytorch_03

  • mean:(list)长度与输入的通道数相同,代表每个通道上所有数值的平均值。
  • std:(list)长度与输入的通道数相同,代表每个通道上所有数值的标准差。

3. 计算方法

3.1 计算公式 


3.2 参数传入0.5的含义 

有时我们会设置传入的mean和std为固定值0.5,是因为把0.5代入如下公式,

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_Image_04

可以得到:

output = 2 * input -1

 如果我们的输入在[0,1]之间,经过归一化之后结果即可在[-1 , 1]之间。

作用:将两个参数都设置为0.5并与transforms.ToTensor()一起使用可以使将数据强制缩放到[-1,1]区间上

4. 归一化应用

4.1 步骤  

  1.  创建PIL型图片
  2. 使用ToTensor转换为tensor型对象
  3. 使用transforms.Normalize(means, std )实例化Normalize对象norm_tool中
  4. 把tensor图像传入norm_tool中进行归一化处理
  5. 使用tensorboard可视化图像

4.2 代码 

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


writer = SummaryWriter("logs")

img = Image.open("image/dog.jpg")
tensor_tool = transforms.ToTensor()
img_tensor = tensor_tool(img)

writer.add_image("ToTensor",img_tensor)

#normalized的使用,需要输入均值和标准差

trans_norm = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
img_norm = trans_norm(img_tensor)

writer.add_image("Normalize",img_norm)


writer.close()

4.3 结果可视化 

结果如下,可以看到经过归一化后的图片产生了明显的变化。

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_python_05

4.4 进阶版代码

为了让归一化结果更加明显,我们创建3个step,并且依次修改不同的mean和std,查看对应结果。 

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


writer = SummaryWriter("logs")

img = Image.open("image/dog.jpg")
tensor_tool = transforms.ToTensor()
img_tensor = tensor_tool(img)

writer.add_image("ToTensor",img_tensor)

#normalized的使用,需要输入均值和标准差

norm_tool = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
img_norm = norm_tool(img_tensor)
writer.add_image("Normalize",img_norm)

norm_tool = transforms.Normalize([1,3,5],[3,1,2])
img_norm = norm_tool(img_tensor)
writer.add_image("Normalize",img_norm,1)

norm_tool = transforms.Normalize([2,5,3],[1,5,6])
img_norm = norm_tool(img_tensor)
writer.add_image("Normalize",img_norm,2)

writer.close()

可以看到每一个step的图片都是不一样的。

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_transformer_06

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_numpy_07

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_numpy_08

四、Resize

1. 作用

resize可以把输入的图片按照输入的参数值重新设定大小。

2.  所需参数

需要输入想要重新设定的图片大小。

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_python_09

 输入的参数类型可以为包含长和宽数值的一个序列(h,w)或者一个整数x。 

size (sequence or int): Desired output size. If size is a sequence like (h, w), output size will be matched to this. If size is an int, smaller edge of the image will be matched to this number.

  • 如果输入的参数是一个序列,即长和宽两个整数,则图像会按该长和宽进行resize。
  • 如果输入的参数是一个整数x,将图片短边缩放至x,长宽比保持不变。

!!!   新版的resize的输入图形类型可以是PIL型或者tensor型   !!!

warning: The output image might be different depending on its type: when downsampling, the interpolation of PIL images and tensors is slightly different, because PIL applies antialiasing. This may lead to significant differences in the performance of a network. Therefore, it is preferable to train and serve a model with the same input types.

注意:

输出图像可能根据其类型不同而不同:当下采样时,PIL图像的插值和张量略有不同,因为PIL应用了抗锯齿。这可能会导致显著的差异在网络的性能中。因此,最好是训练和服务一个具有相同输入的模型类型。

3. 具体使用

    下面给出输入图片类型为PIL和tensor的两张类型的图片resize,使用的图片为狗狗图片,原大小为960*600,resize的输入参数为一个序列(512,512),即经过resize后图片会被缩放成长和宽均为512的正方形大小。

由于输入类型为PIL型图片,后续使用add_image方法时需要再把PIL型转换为tensor型,因此我们的操作分为两步,有两种实现方法。

3.1 第一种方法

  1. 将PIL型图片resize
  2. 将resize后的PIL型图片转换为tensor进行输出 
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms


writer = SummaryWriter("log")
img_path = "image/dog.jpg"
#创建PIL类型图片
img_PIL = Image.open(img_path)
#resize图形为512*512
trans_resize_tool = transforms.Resize((512,512))
img_resized_PIL = trans_resize_tool(img_PIL)
#将resize后的PIL图形转换成tensor
trans_totensor_tool = transforms.ToTensor()
img_resized_tensor = trans_totensor_tool(img_resized_PIL)
#使用tensorboard输出
writer.add_image("resize",img_resized_tensor)
writer.close()

3.2 第二种方法

  1. 将PIL型图片先转换为tensor型
  2. 将tensor型图片进行resize
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms


writer = SummaryWriter("log")
img_path = "image/dog.jpg"
#创建PIL对象
img_PIL = Image.open(img_path)
#把PIL转换为tensor类型
trans_totensor_tool = transforms.ToTensor()
img_tensor = trans_totensor_tool(img_PIL)
#resize
trans_resize_tool = transforms.Resize((512,512))
img_tensor_resized = trans_resize_tool(img_tensor)
#输出
writer.add_image("resize2",img_tensor_resized)
writer.close()

4. 输出结果

原始图像:960*600大小,为长方形。 

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_python_10

 resize后:可以看到两次操作都把图像缩放成了512*512的正方形大小,。

    

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_python_11

 

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_Image_12

五、Compose

1. 作用 

可以把几个tranforms组合在一起使用,相当于一个组合器,可以对输入图片一次进行多个transforms的操作。

看下图example中给出的例子,该compose把transforms中的CenterCrop和ToTensor组合在了一起。 作用即为:可以先把图片中心裁剪为10的大小,然后再把图片转换为tensor类型。

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_python_13

  

2. 参数介绍

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_Image_14

  • compose中传入的参数需要是一个列表,列表中的数据类型是transforms型。
  • 参数1的输出类型必须与参数2的输入类型匹配。 

因为compose的工作顺序是从左到右的,第一个参数transform介绍之后再进行第二个transform的操作,所以需要前一个的输出和后一个的输入匹配。

3. Compose和Resize的结合使用

我们结合上面resize的学习进行一个compose的使用,这次resize的参数只输入一个数字,300,即会等比例缩放为短边为300大小的图片。

compose负责把ToTensor和resize组合起来,一步到位实现PIL图形到resize后的tensor图形的转换。

注:

为了测试参数顺序对compose的影响,代码中我写了2个compose,分别调换了ToTensor和resize的顺序,结果完全一致,这是因为ToTensor的输出tensor可以作为resize的输入,而resize的输出PIL也可以作为ToTensor的输入,因此无影响。

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


writer = SummaryWriter("log")
img_path = "image/dog.jpg"
#创建PIL对象
img_PIL = Image.open(img_path)
#创建totensor和resize工具
trans_totensor_tool =transforms.ToTensor()
trans_resize_tool =transforms.Resize(300)
#compose
trans_compose_tool1 = transforms.Compose([trans_totensor_tool,trans_resize_tool])
trans_compose_tool2 = transforms.Compose([trans_resize_tool,trans_totensor_tool])
#图形转换
img_tensor_resized = trans_compose_tool1(img_PIL)

writer.add_image("compose",img_tensor_resized)
writer.add_image("compose",img_tensor_resized,1)

writer.close()

4. 结果

图片如期进行了缩放。 

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_python_15

六、RandomCrop 随机裁剪

1. 作用

把图像按照随机位置进行裁剪。

2. 参数介绍

参数需要输入想要裁剪成的图片大小。

  • 如果输入的是序列(h,w),会按照该长和宽进行裁剪。
  • 如果输入的是一个整数x,则会按照(x,x)的大小裁剪。

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_transformer_16

3. 具体使用

结合compose进行使用,完成10张大小为512*512的图片的随机裁剪。

需要使用到for循环。

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

writer = SummaryWriter("log")
img_path = "image/dog.jpg"
#创建PIL对象
img_PIL = Image.open(img_path)
#创建工具
trans_totensor_tool = transforms.ToTensor()
trans_randomcrop_tool = transforms.RandomCrop(512)
#compose
trans_compose_tool = transforms.Compose([trans_totensor_tool,trans_randomcrop_tool])
for i in range(10):
    img_tensor_ramdomcroped = trans_compose_tool(img_PIL)
    writer.add_image("randomcrop",img_tensor_ramdomcroped,i)

writer.close()

4. 结果

可以看到step一共有10步,而且每一步中的小狗位置都是不一样的,实现了随机裁剪的功能。 

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_transformer_17

    

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_Image_18

 

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_Image_19

     

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_python_20

七、transforms使用总结

pytorch实现的带有Transformer的翻译模型 pytorch transform.normalize_python_21