pytorch 图像预处理之减去均值,除以方差

在使用 torchvision.transforms进行数据处理时我们经常进行的操作是:

transforms.Normalize((0.485,0.456,0.406), (0.229,0.224,0.225))

前面的(0.485,0.456,0.406)表示均值,分别对应的是RGB三个通道;后面的(0.229,0.224,0.225)则表示的是标准差。这上面的均值和标准差的值是ImageNet数据集计算出来的,所以很多人都使用它们。
在这里插入图片描述

GPU上面的环境变化太复杂,这里我直接给出在笔记本CPU上面的运行时间结果。由于方式3需要将tensor转换到GPU上面,这一过程很消耗时间,大概需要十秒,故而果断抛弃这样的做法

img (168, 300, 3)
sub div in numpy,time 0.0110
sub div in torch.tensor,time 0.0070
sub div in torch.tensor with torchvision.transforms,time 0.0050
tensor1=tensor2
tensor2=tensor3

img (1079, 1349, 3)
sub div in numpy,time 0.1899
sub div in torch.tensor,time 0.1469
sub div in torch.tensor with torchvision.transforms,time 0.1109
tensor1=tensor2
tensor2=tensor3

耗时最久的是numpy,其次是转换成torch.tensor,最快的是直接使用torchvision.transforms

我现在在GPU上面跑的程序GPU利用率特别低(大多数时间维持在2%左右,只有很少数的时间超过80%),然后设置打印点调试程序时发现,getitem()输出一张图像的时间在0.1秒的数量级,这对于GPU而言是非常慢的,因为GPU计算速度很快,CPU加载图像和预处理图像的速度赶不上GPU的计算速度,就会导致显卡大量时间处于空闲状态,经过对于图像I/O部分代码的定位,发现是使用numpy减去图像均值除以方差这一操作浪费了太多时间,而且输入图像的分辨率越大,所消耗的时间就会更多,原则上,图像预处理每个阶段的时间需要维持在0.01秒的数量级

import numpy as np
import time
import torch
import torchvision.transforms as transforms
import cv2

img_path='F:\\2\\00004.jpg'
PIXEL_MEANS =(0.485, 0.456, 0.406)    # RGB  format mean and variances
PIXEL_STDS = (0.229, 0.224, 0.225)

方式一 在numpy中进行减去均值除以方差,最后转换成torch.tensor

one_start=time.time()

img=cv2.imread(img_path)	 			# (H,W,C) 
img=img[:,:,::-1]	 					# GBR转换为RGB

img=img.astype(np.float32, copy=False)	# 像素值变为浮点数
img/=255.0
img-=np.array(PIXEL_MEANS)
img/=np.array(PIXEL_STDS)

tensor1=torch.from_numpy(img.copy())	# 输出的应该是转换成torch.tensor的标准形式
tensor1=tensor1.permute(2,0,1)			# (H,W,C)转为(C,H,W)

one_end=time.time()
print('sub div in numpy,time {:.4f}'.format(one_end-one_start))
del img

方式二 转换成torch.tensor,再减去均值除以方差

two_start=time.time()
img=cv2.imread(img_path)
img=img[:,:,::-1]

print('img',img.shape,np.min(img),np.min(img))
tensor2=torch.from_numpy(img.copy()).float()
tensor2/=255.0
tensor2-=torch.tensor(PIXEL_MEANS)
tensor2/=torch.tensor(PIXEL_STDS)

tensor2=tensor2.permute(2,0,1)
two_end=time.time()
print('sub div in torch.tensor,time {:.4f}'.format(two_end-two_start))

del img

方式三 转换成torch.tensor,再放到GPU上面,最后减去均值除以方差

# three_start=time.time()
# img=cv2.imread(img_path)
# img=img[:,:,::-1]
# tensor3=torch.from_numpy(img.copy()).cuda().float()
# tensor3-=torch.tensor(PIXEL_MEANS).cuda()
# tensor3/=torch.tensor(PIXEL_STDS).cuda()
# three_end=time.time()
# print('sub div in torch.tensor on cuda,time {:.4f}'.format(three_end-three_start))

# del img

方式四 转换成torch.tensor,使用transform方法减去均值除以方差

four_start=time.time()
img=cv2.imread(img_path)
img=img[:,:,::-1]
transform=transforms.Compose(
    [transforms.ToTensor(),transforms.Normalize(PIXEL_MEANS, PIXEL_STDS)]
)
tensor4=transform(img.copy())
four_end=time.time()
print('sub div in torch.tensor with torchvision.transforms,time {:.4f}'.format(four_end-four_start))

del img

if torch.sum(tensor1-tensor2)<=1e-3:
    print('tensor1=tensor2')
if torch.sum(tensor2-tensor4)==0:
    print('tensor2=tensor3')
# if tensor3==tensor4:
#     print('tensor3=tensor4')

参考1
参考2

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Pytorch中,图像预处理通常使用transforms模块来完成。以下是一些常见的图像预处理操作: 1. Resize:调整图像大小。 ``` transforms.Resize((height, width)) ``` 2. CenterCrop:在图像中心进行裁剪。 ``` transforms.CenterCrop(size) ``` 3. RandomCrop:在随机位置进行裁剪。 ``` transforms.RandomCrop(size, padding=None, pad_if_needed=False, fill=0, padding_mode='constant') ``` 4. Normalize:对图像进行标准化处理。 ``` transforms.Normalize(mean, std) ``` 5. ToTensor:将数据类型转换为张量(Tensor)。 ``` transforms.ToTensor() ``` 6. RandomHorizontalFlip:随机水平翻转。 ``` transforms.RandomHorizontalFlip(p=0.5) ``` 7. RandomRotation:随机旋转。 ``` transforms.RandomRotation(degrees, resample=False, expand=False, center=None) ``` 这些操作可以通过组合使用来构建一个预处理管道。例如,以下代码将对图像进行中心裁剪、标准化和转换为张量: ``` transform = transforms.Compose([ transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) ``` ### 回答2: PyTorch是一种流行的机器学习框架,提供了丰富的图像预处理功能,便于处理和准备图像数据用于训练深度学习模型。 首先,PyTorch图像预处理的第一步通常是加载图像PyTorch提供了torchvision库,其中包括一些常用的数据集,如ImageFolder,可以方便地加载和处理图像数据。 接下来,预处理图像的常见步骤是将其转换为Tensor格式。PyTorch图像表示为张量,可以通过使用transforms.ToTensor()转换图像数据类型为torch.Tensor。这样可以使图像数据可以直接输入到神经网络中进行训练。 此外,图像预处理包括常见的数据增强方法,如随机裁剪、随机翻转、旋转和缩放等。这些数据增强方法有助于增加模型的泛化能力,提高模型对于不同样本的鲁棒性。可以使用transforms库提供的方法,如RandomCrop、RandomHorizontalFlip和RandomRotation等来实现这些数据增强操作。 另外,在进行图像预处理时,还可以进行归一化操作。这可以通过使用transforms.Normalize()方法,将图像的像素值进行标准化处理,使其符合模型训练的要求。标准化会根据图像像素的均值和标准进行处理。 最后,为了方便创建可以训练的数据集,可以使用torch.utils.data.DataLoader将预处理后的图像加载为批量数据。DataLoader还提供了一些常用的功能,如数据随机打乱和并行加载等。 综上所述,PyTorch提供了丰富的图像预处理功能,通过transforms库以及相关的方法,可以将图像数据加载、转换为张量、进行数据增强和标准化等操作,方便地准备和处理图像数据以供深度学习模型使用。 ### 回答3: PyTorch图像预处理是一系列的操作,用于将输入的图像数据转换为适合神经网络训练的格式。下面将介绍几种常见的PyTorch图像预处理方法。 1. 图像变换(Image Transformations):这是最基本的图像预处理步骤,包括调整图像大小,裁剪、缩放、旋转等操作。可以使用torchvision库中的transforms模块来实现,例如使用Resize函数调整图像大小,使用RandomCrop函数进行随机裁剪。 2. 数据增强(Data Augmentation):数据增强是指通过对原始图像进行一系列变换来生成新的训练样本,旨在扩大训练集规模和增加数据的多样性,以提高模型的泛化能力。常用的数据增强操作包括随机翻转、随机旋转、随机裁剪等。可以使用torchvision库中的transforms模块的RandomHorizontalFlip、RandomVerticalFlip、RandomRotation、RandomCrop等函数来实现。 3. 标准化(Normalization):标准化是将图像的像素值进行归一化处理,使其符合神经网络的输入要求。常用的标准化方法是将像素值减去均值,然后除以标准。可以使用torchvision库中的transforms模块的Normalize函数来实现。 4. 数据加载(Data Loading):在PyTorch中,可以使用torchvision库中的datasets模块来加载图像数据集。datasets模块提供了一些常用的图像数据集,如CIFAR-10、ImageNet等。加载图像数据集时,可以使用transforms参数来指定需要进行的图像预处理操作。 5. 批量处理(Batch Processing):在神经网络训练过程中,通常会将训练数据划分为小批量进行训练,以提高运算效率。可以使用torch.utils.data.DataLoader模块中的DataLoader函数来进行批量处理。 总结起来,PyTorch图像预处理包括图像变换、数据增强、标准化、数据加载和批量处理等操作,通过这些操作可以将原始图像数据转换为适合神经网络训练的格式。这些预处理操作可以提高模型的训练效果和泛化能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值