深度学习 -- PyTorch学习 torchvision工具学习 Transforms模块 Normalize用法

前言

计算机视觉是深度学习的一个重要应用领域。PyTorch提供现成的torchvision工具,帮助处理图像和视频。torchvision包含一些常用的数据集、模型、转换函数等,学习和使用这些API有助于更快更好的在CV领域应用PyTorch。

torchvision

torchvision的数据集都是torch.utils.data.Dataset的子类,都实现了__getitem__ 和 __len__函数,可传递给支持并行处理的多进程torch.utils.data.DataLoader加载器进行数据加载。

使用torchvision编写图像数据集

假定现在手头里有25000张猫和狗的图像数据,它们存放在同一个目录下,文件名命名为dog.xxx.jpg和cat.xxx.jpg。(xxx为编号0-12499)

我们要对猫和狗进行分类任务

import torch
import os
import numpy as np
from PIL.Image import Image
from torch.utils.data import Dataset

class DogsCatsDataset(Dataset):
    '''猫狗数据集定义'''
    def __init__(self,root):
        # root 为图片路径
        imgs = os.listdir(root)  # 把root目录下的文件名变成列表的形式
        # 仅保存图片的完整路径
        self.imgs = [os.path.join(root,img) for img in imgs]
        
    def __getitem__(self, item):
        img_path = self.imgs[item]
        # 根据文件名确定标签,dog为1 cat为0
        label = 1 if 'dog' in img_path else 0
        pil_img = Image.open(img_path)
        img_array = np.array(pil_img)
        
        # 把图像数据转换为张量
        img = torch.from_numpy(img_array)
        return img ,label
    
    def __len__(self):
        return len(self.imgs)
        
        
if __name__ == '__main__':
    dataset = DogsCatsDataset("./路径")
    img,label = dataset[1] 
    print(img.shape,label)

这段代码假设您的数据集保存在一个名为 ./路径 的目录中,并且该目录包含多个子目录,每个子目录中包含多个图片文件。每个图片文件的文件名以 .jpg 或 .png 结尾。

首先,代码将根据图片的文件名确定其标签。‘dog’ 表示狗的标签,‘cat’ 表示猫的标签。

然后,代码将打开每个图片文件,并将其转换为张量。这里使用了 PyTorch 中的 torch.from_numpy() 函数将 NumPy 数组转换为张量。

最后,代码返回张量和标签。len() 方法返回数据集中图片的数量。

在示例中,代码将打印张量的形状和标签。在这种情况下,张量的形状为 (1,),标签为 1,因为图片文件名为 ‘dog’。



Transforms模块

前文定义的猫狗数据集类存在三个问题:

  • 每张图片的宽、高不一样,需要进行处理
  • 图片的每个像素的取值范围是0-255,深度网络需要归一化到0-1的范围内
  • 注入PIL工具读取到的图片张量形状是(H,W,C),但是深度网络接收的图片张量形状为(B,C,H,W),需要进行转换,其中,B为一批样本中的图片数,H和W分别为图片的高和宽,C为图片的通道数。

对此,PyTorch torchvision工具的Transforms模块提供对PIL Image对象的图像转换功能,该模块提供了常用预处理功能的实现,如填充、裁剪、灰度模式、线性变换、将图像转换成PyTorch张量,以及一些实现数据增强的功能,如反转、随机剪裁、颜色抖动。

图像转换:

python
import torch  
from PIL import Image  
  
# 读取图像  
img = Image.open('path/to/image.jpg')  
  
# 转换为张量  
img_tensor = torch.from_numpy(img.convert('RGB'))  
  
# 转换为PIL Image对象  
img_pil = Image.fromarray(img_tensor)  
  
# 转换为RGBA四元组  
img_tensor_4d = torch.stack([img_tensor, img_tensor, img_tensor], dim=0)  
img_pil_4d = Image.fromarray(img_tensor_4d)  
  
# 定义转换函数  
transforms = {
    
      
    'to_tensor': torch.nn.functional.to_tensor,  
    'to_pil_image': Image.fromarray,  
    'to_pil_image_data': Image.fromarray,  
}  
  
# 应用转换函数  
for transform, method in transforms.items():  
    img_tensor_transformed = method(img_tensor)  
    # 处理转换后的张量

图像增强:

import torch  
from PIL import Image  
import numpy as np  
  
# 读取图像  
img = Image.open('path/to/image.jpg')  
  
# 增强对比度  
img_contrast = Image.eval(img, contrast=1.5)  
  
# 增强亮度  
img_brightness = Image.eval(img, brightness=1.5)  
  
# 增强颜色  
img_gamma = Image.eval(img, gamma=1.5)  
  
# 定义增强函数  
transforms = {
    
      
    'contrast': lambda img: np.clip(img.astype(np.uint8) + np.random.randn_like(img), 0, 255),  
    'brightness': lambda img: np.clip(img.astype(np.uint8) + np.random.randn_like(img), 0, 255),  
    'gamma': lambda img: np.clip(img.astype(np.uint8) + np.random.randn_like(img), 0, 255),  
}  
  
# 应用增强函数  
for transform, method in transforms.items():  
    img_transformed = method(img)  
    # 处理增强后的张量

数据转换:

import torch  
from PIL import Image  
  
# 读取张量  
data = torch.randn(1, 3, 224, 224)  
  
# 转换为PIL Image对象  
img_pil = Image.fromarray(data.transpose(1, 2))  
  
# 转换为RGBA四元组  
data_tensor_4d = torch.stack([data.transpose(1, 0), data.transpose(0, 2), data], dim=0)  
img_pil_4d = Image.fromarray(data_tensor_4d)  
  
# 定义转换函数  
transforms = {
    
      
    'to_pil_image': Image.fromarray,  
    'to_pil_image_data': Image.fromarray,  
}  
  
# 应用转换函数  
for transform, method in transforms.items():  
    data_tensor_transformed = method(data_tensor)  
    # 处理转换后的张量

数据增强:

import torch  
from PIL import Image  
  
# 读取张量  
data = torch.randn(1, 3, 224, 224)  
  
# 增强随机旋转  
data_randrot = data.transpose(2, 0, 1)  
data_rot = data_randrot.permute(0, 2, 3, 1)  
  
# 增强随机缩放  
data_randscale = data.unsqueeze(0).unsqueeze(0).unsqueeze(0)

Normalize用法

在TransFroms中通常使用Normalize来规范化张量图像,这是就需要计算数据集的均值和标准差。

Normalize是PyTorch中的一个函数,用于将张量的每个维度的均值和标准差都设置为0或1,使得张量的值在指定的范围内。

import torch  
  
# 定义一个张量  
x = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32)  
  
# 定义Normalize的参数  
mean = [0.0, 0.0]  
std = [1.0, 1.0]  
  
# 使用Normalize进行归一化  
x_normalized = normalize(x, mean, std)  
  
print(x_normalized)

猜你喜欢

转载自blog.csdn.net/fuhao6363/article/details/130473957