pytorch学习(二):transforms使用

发布于:2024-05-16 ⋅ 阅读:(60) ⋅ 点赞:(0)

作用:将特定的图片通过transforms工具处理,得到我们想要的结果。

ToTensor写成如下会报错:

img=cv2.imread('./data/train/ants/0013035.jpg')
tensor_img=transforms.ToTensor(img)
print(tensor_img)

正确形式:

img=cv2.imread('./data/train/ants/0013035.jpg')
tensor_trans=transforms.ToTensor()
tensor_img=tensor_trans(img)
print(tensor_img)

 原因:

在PyTorch的torchvision.transforms模块中,ToTensor是一个用于图像预处理的类,而不是一个函数。因此,你不能直接调用transforms.ToTensor(img)来转换图像,因为这不是这个类设计的使用方式。

ToTensor类是用来创建一个预处理对象的,该对象可以被调用以将PIL图像或NumPy ndarray转换为PyTorch张量(tensor)。

正确的使用方式是:

  1. 首先,实例化ToTensor类,得到一个转换对象。
  2. 然后,使用该转换对象来转换图像。

遇见小错误:tensorboard无法显示图片,原因:忘记 writer.close()

__call__函数和普通函数的区别:

class Person:
    def __call__(self,name):
        print('__call__'+' hello'+name)
    def hello(self,name):
        print(' hello' + name)
person=Person()
person('cool')
person.hello('cool')

在Python的类中,__call__函数和forward函数(后者并不是Python的一个内置特殊方法,但经常在神经网络或计算图中见到)有不同的调用规则。

__call__ 函数

__call__ 是一个特殊方法,允许类的实例像函数那样被调用。当你尝试调用一个类的实例时,Python会自动查找并调用该实例的__call__方法。

class CallableClass:  
    def __call__(self, *args, **kwargs):  
        print("CallableClass is being called!")  
        print(f"Arguments: {args}, Keyword arguments: {kwargs}")  
  
# 创建一个实例  
instance = CallableClass()  
  
# 调用实例,就像调用一个函数  
instance(1, 2, 3, a=4, b=5)  
# 输出:  
# CallableClass is being called!  
# Arguments: (1, 2, 3), Keyword arguments: {'a': 4, 'b': 5}

forward 函数

forward 函数通常不是Python内置的一部分,但在某些库(如PyTorch)中,它被用作神经网络模块(如nn.Module)的前向传播方法。当你定义一个继承自nn.Module的类时,你通常需要实现一个forward方法,该方法描述了数据通过网络的前向传播。

import torch  
import torch.nn as nn  
import torch.nn.functional as F  
  
class SimpleNeuralNet(nn.Module):  
    def __init__(self):  
        super(SimpleNeuralNet, self).__init__()  
        self.fc = nn.Linear(10, 1)  # 一个简单的全连接层  
  
    def forward(self, x):  
        # 定义前向传播  
        x = F.relu(self.fc(x))  
        return x  
  
# 创建一个实例  
net = SimpleNeuralNet()  
  
# 创建一个随机的输入张量  
input_tensor = torch.randn(1, 10)  
  
# 调用网络实例,就像调用一个函数  
output_tensor = net(input_tensor)  # 这里实际上调用的是 net.forward(input_tensor)  
# 但我们通常不需要显式地调用 forward 方法

Randomcrop函数:增加样本数据,用于学习。

#RandomCrop
trans_random=transforms.RandomCrop(512)
trans_compose_2=transforms.Compose([trans_random,tensor_trans])
for i in range(10):
    img_crop=trans_compose_2(img_PIL)
    writer.add_image('RandomCrop',img_crop,i)

所有代码:

from torchvision import transforms
import cv2
from torch.utils.tensorboard import SummaryWriter
from PIL import Image
writer=SummaryWriter("logs")
img=cv2.imread('./data/train/ants/0013035.jpg')

#ToTensor
tensor_trans=transforms.ToTensor()
img_tensor=tensor_trans(img)
writer.add_image('tensor_img',img_tensor)

#Normalize
print(img_tensor[0][0][0])
tensor_norm=transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])#main均值,std标准差
img_norm=tensor_norm(img_tensor)#output[channel] = (input[channel] - mean[channel]) / std[channel]
print(img_norm[0][0][0])
writer.add_image('Normalize',img_norm,0)

#Resize 输入必须是PIL格式或者是tensor格式
img_PIL=Image.open('./data/train/ants/0013035.jpg')
print(img_PIL.size)
trans_resize=transforms.Resize((512,512))#高和宽
img_resize=trans_resize(img_PIL)#返回值仍然是PIL格式或者tensor格式
img_resize=tensor_trans(img_resize)
writer.add_image('Resize',img_resize,0)
print(img_resize)

trans_resize_2=transforms.Resize(512)#只输入一个参数代表最短的那个边输出的像素点的数量
trans_compose=transforms.Compose([trans_resize_2,tensor_trans])
img_resize_2=trans_compose(img_PIL)
writer.add_image('Resize_2',img_resize_2,0)
#RandomCrop
trans_random=transforms.RandomCrop(512)
trans_compose_2=transforms.Compose([trans_random,tensor_trans])
for i in range(10):
    img_crop=trans_compose_2(img_PIL)
    writer.add_image('RandomCrop',img_crop,i)

writer.close()