pytorch初学笔记(四):常见的Transforms使用(ToTensor、Normalize、Resize、Compose、RandomCrop)
目录
小技巧:如何取消在pycharm中敲代码时的大小写匹配
一、 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的使用_好喜欢吃红柚子的博客-CSDN博客
需要注意的是:
- 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 Imagefrom torch.utils.tensorboard import SummaryWriterfrom torchvision import transformswriter = 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. 所需参数
- mean:(list)长度与输入的通道数相同,代表每个通道上所有数值的平均值。
- std:(list)长度与输入的通道数相同,代表每个通道上所有数值的标准差。
3. 计算方法
3.1 计算公式
3.2 参数传入0.5的含义
有时我们会设置传入的mean和std为固定值0.5,是因为把0.5代入如下公式,
可以得到:
output = 2 * input -1
如果我们的输入在[0,1]之间,经过归一化之后结果即可在[-1 , 1]之间。
作用:将两个参数都设置为0.5并与transforms.ToTensor()
一起使用可以使将数据强制缩放到[-1,1]区间上。
4. 归一化应用
4.1 步骤
- 创建PIL型图片
- 使用ToTensor转换为tensor型对象
- 使用transforms.Normalize(means, std )实例化Normalize对象norm_tool中
- 把tensor图像传入norm_tool中进行归一化处理
- 使用tensorboard可视化图像
4.2 代码
from PIL import Imagefrom torch.utils.tensorboard import SummaryWriterfrom torchvision import transformswriter = 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 结果可视化
结果如下,可以看到经过归一化后的图片产生了明显的变化。
4.4 进阶版代码
为了让归一化结果更加明显,我们创建3个step,并且依次修改不同的mean和std,查看对应结果。
from PIL import Imagefrom torch.utils.tensorboard import SummaryWriterfrom torchvision import transformswriter = 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的图片都是不一样的。
四、Resize
1. 作用
resize可以把输入的图片按照输入的参数值重新设定大小。
2. 所需参数
需要输入想要重新设定的图片大小。
输入的参数类型可以为包含长和宽数值的一个序列(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 第一种方法
- 将PIL型图片resize
- 将resize后的PIL型图片转换为tensor进行输出
from PIL import Imagefrom torch.utils.tensorboard import SummaryWriterfrom torchvision import transformswriter = SummaryWriter("log")img_path = "image/dog.jpg"#创建PIL类型图片img_PIL = Image.open(img_path)#resize图形为512*512trans_resize_tool = transforms.Resize((512,512))img_resized_PIL = trans_resize_tool(img_PIL)#将resize后的PIL图形转换成tensortrans_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 第二种方法
- 将PIL型图片先转换为tensor型
- 将tensor型图片进行resize
from PIL import Imagefrom torch.utils.tensorboard import SummaryWriterfrom torchvision import transformswriter = 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)#resizetrans_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大小,为长方形。
resize后:可以看到两次操作都把图像缩放成了512*512的正方形大小,。
五、Compose
1. 作用
可以把几个tranforms组合在一起使用,相当于一个组合器,可以对输入图片一次进行多个transforms的操作。
看下图example中给出的例子,该compose把transforms中的CenterCrop和ToTensor组合在了一起。 作用即为:可以先把图片中心裁剪为10的大小,然后再把图片转换为tensor类型。
2. 参数介绍
- 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 Imagefrom torch.utils.tensorboard import SummaryWriterfrom torchvision import transformswriter = 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)#composetrans_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. 结果
图片如期进行了缩放。
六、RandomCrop 随机裁剪
1. 作用
把图像按照随机位置进行裁剪。
2. 参数介绍
参数需要输入想要裁剪成的图片大小。
- 如果输入的是序列(h,w),会按照该长和宽进行裁剪。
- 如果输入的是一个整数x,则会按照(x,x)的大小裁剪。
3. 具体使用
结合compose进行使用,完成10张大小为512*512的图片的随机裁剪。
需要使用到for循环。
from PIL import Imagefrom torch.utils.tensorboard import SummaryWriterfrom torchvision import transformswriter = 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)#composetrans_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步,而且每一步中的小狗位置都是不一样的,实现了随机裁剪的功能。
七、transforms使用总结
参考文章
(4条消息) pytorch个人学习笔记(2)—Normalize()参数详解及用法_吃米的鹰的博客-CSDN博客_normalize参数
来源地址:https://blog.csdn.net/weixin_45662399/article/details/127555842
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341