人工智能小白,不对之处,希望各位大佬不吝赐教^_^
目录
前言?
?正文
1.关于HWC维度的理解
2.为什么pytorch中transforms.ToTorch要把(H,W,C)的矩阵转为(C,H,W)??[2]
3.如何进行格式的转换?
3.1 opencv python 把图(cv2下)BGR转RGB,且HWC转CHW【3】.
3.2 Torch将HWC格式转为CHW
附录
推荐文章
前言?
最近在做一个图像分类的任务,其中涉及到对于数据集的处理,利用到了均值和标准差。但是其中的均值和标准差是一个数组,如下所示。
# 各通道的均值
CIFAR100_TRAIN_MEAN = (0.5070751592371323, 0.48654887331495095, 0.4409178433670343)
# 各通道的标准差
CIFAR100_TRAIN_STD = (0.2673342858792401, 0.2564384629170883, 0.27615047132568404)
查阅资料发现,其中每个数值代表一个通道的均值和标准差,因此我猜测是RGB通道对应的数值。后来,通过研读整个项目代码,发现了一个令我困扰的地方。
# 数据增强
transform_train = transforms.Compose([
# transforms.ToPILImage(),
# Crop the given PIL Image at a random location.
# 32*32,padding=4,图像上下左右像素均填充一个像素
transforms.RandomCrop(32, padding=4),
# 随机水平翻转,默认值是0.5
transforms.RandomHorizontalFlip(),
# (-degrees,+degrees)
transforms.RandomRotation(15),
# 数据的格式转换和标准化 HWC => CHW。
# 把图片转换为张量,同时进行归一化操作,把每个通道 0~255 的值归一化为0~1
transforms.ToTensor(),
transforms.Normalize(mean, std) # 图像张量的归一化
])
由于我之前对于张量tensor以及torch不太熟悉,查阅资料补充了对上述代码的理解。
?正文
下面将依次介绍HWC格式的理解以及torch图像格式的转换,我认为这是一个循序渐进的过程。
1.关于HWC维度的理解
我们首先需要明确的是各个参数的含义,HWC可以看作是一幅图像的shape[1],H表示图像的高度(height),W表示图像的宽度(Width),而C表示一幅图像的通道数(Channel)。
举个小栗子
hwc=[5,5,3]?的含义是什么呢?
大家可以思考一下,以图像为例,那么高宽都是5,3就是其中的通道数。因此我们也可以理解为3个?5*5 大小的特征图。?
此问题的回答来源于知乎[2].
- 因为pytorch很多函数都是设计成假设你的输入是 (c,h,w)的格式,当然你如果不嫌麻烦的话可以每次要用这些函数的时候转成chw格式,但我想这会比你输入的时候就转成chw要麻烦很多。
- 至于为什么pytorch选择设计成chw而不是hwc(毕竟传统的读图片的函数opencv的cv2.imread或者sklearn的imread都是读成hwc的格式的)这点确实比较令初学者困惑。个人感觉是因为pytorch做矩阵加减乘除以及卷积等运算是需要调用cuda和cudnn的函数的,而这些接口都设成成chw格式了,故而pytorch为了方便起见也设计成chw格式了。
- 那新问题就来了,cuda和cudnn为什么设计成chw格式呢?我想这是由于涉及到图片操作的都是和卷积相关的,而内部做卷积运算的加速设计成chw在操作上会比hwc处理起来更容易,更快。题主如果想进一步了解可以google一下cudnn的卷积实现。
3.如何进行格式的转换?
3.1 opencv python 把图(cv2下)BGR转RGB,且HWC转CHW【3】.
img = cv2.imread("test.jpg")
img_ = img[:,:,::-1].transpose((2,0,1))
- 在opencv里,图格式HWC,其余都是CHW,故使用方法transpose((2,0,1)),transpose(2,0,1)就是读入第三维的数C作为第一维的值,读入第一维的数H作为第二维,读入第二维的数作为第三维W,如果再高维,就再按照输入的读取顺序来读【4】。
- img[:,:,::-1]对应H、W、C,彩图是3通道,即C是3层。opencv里对应BGR,故通过C通道的 ::-1 就是把BGR转为RGB,其中[::-1] 代表顺序相反操作。
3.2 Torch将HWC格式转为CHW
from PIL import Image
from torchvision.transforms import ToTensor
img = Image.open('image_path')
#产生的PIL_image格式数据的取值范围是[0,255]
#形状(shape)是[h, w, c]
#像素顺序是RGB
tensor = ToTensor()(PIL_img)
# 或者
np_data = np.asarray(PIL_img)
tensor = ToTensor()(np_data)
ToTensor()接收PIL格式的数据,或者是直接从PIL转来的np.ndarray格式数据,只要保证进来的数据取值范围是[0, 255], 形状是[h, w, c],像素顺序是RGB,它就会帮你做下面的事情[5]
- 取值范围[0, 255] / 255.0 => [0, 1.0], 数据格式从int8变成了float32
- 形状(shape)转为[c, h, w]
- 像素顺序依旧是RGB
附录
- Pytorch数据前后处理整理?
- 为什么pytorch中transforms.ToTorch要把(H,W,C)的矩阵转为(C,H,W)?
- opencv python 把图(cv2下)BGR转RGB,且HWC转CHW
- Python numpy.transpose 详解
-
PIL skimage opencv torch各种图像格式的转换
?推荐文章
- 700套个人简历模板(考研保研工作)
- 人工智能2019年秋季学期期末复习知识点整理
- Fisher线性分类器的设计与实现,感知器算法的设计实现
以上就是我理解的内容啦,欢迎大家关注【小果果学长】微信公众号,获取更多资料和源码,希望大家点赞收藏加关注,如有不对的地方,非常开心和您交流。
|