最近在学习各个数据集的处理,我也遇到了很多的问题,我相信这些问题也是大家经常遇到的,尤其是关于transforms的使用,不得不说这个库非常的好用,帮助我们节省了很多的时间,但是不可避免我们会遇到关于pytorch中的Tensor,numpy以及PIL之间的转化,这主要是因为transforms进行转换时接受的是PIL Image类型,要不会报错,下面我就给大家讲解一下这部分的转化。

# 首先来说明一下如何使用transforms来进行定义
from torchvision import datasets, transforms
# 下面这段代码的意思是说将PIL Image对象转化成Tensor对象,并进行Normalize(归一化)操作
# 0.1307,0.3081这两个值是对mnist手写数据集归一化的数字(不用在意,网上一搜就有)
# 第一个值代表均值,第二个代表方差
data_transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

由于本篇主要讲解的是tensor、numpy、PIL Image之间的转化,所以关于transforms的转换函数就不说明了,文章的末尾会把大部分操作列举出来。

好,下面进入正题:

(1)如何把numpy传入data_transform中呢?

# 首先我们要知道transforms接受的类型是PIL Image类型的,所以需要将numpy转换成PIL Image类型
# 这里我们需要注意,如果我们要将numpy转换成PIL格式,那么要求数据类型是dtype=uint8, range[0, 255] 
# 同时传入的numpy数组的类型为(W, H, C),即(宽,高,通道),如果C=1,就不用写了
# 比如处理mnist灰度图像,则为(28, 28)
# 如果处理彩色图像,则为(宽, 高, 3)
# 以mnist图像为例,上代码

# x.shape =  (28, 28), 数据类型为numpy
x = x_train[0]
# 要想用transforms进行处理,就要转换成PIL对象
# 此时的pil_image 就是PIL Image类型
pil_image = transforms.ToPILImage()(x)
# 之后在进行转换就行了,data_transform就是上面定义的transforms
# 此时x.shape = (1, 28, 28), 这个shape中的1是转换之后自动加的,表示通道数,灰色图像就为1,彩色图像就为3,至于为什么1在前28在后进行表示,这是一位pytorch是通道优先规则,数据类型为tensor, 数据范围0-1
x = data_transform(pil_image)

(2)如何把Tensor传入data_transform中呢

# 下面来讲解tensor转PIL,有了上面numpy转PIL,这个就非常好理解了,照猫画虎,不过有两点需要注意
# 1.tensor在转PIL时,size必须是(C, W, H), C是通道,W是宽,H是高,C=1时不写
# 2.tensor数据类型为float,至于数据范围,我们只需要保证要是0-1就全是0-1,要是0-255就全是0-255,最后经过转换之后会变成0-1
# 话不多说,上代码
# x.shape = (28, 28), 类型为tensor,数据范围(0-1)
x = x_train[0]
pil_image = transforms.ToPILImage()(x_train[0])
# x.shape = (1, 28, 28),经过transforms处理之后默认转化成(1, 28, 28)形状,数据范围0-1
x = data_transform(pil_image)

以上就是三者之间的转化,下面给大家一个链接,这个博客上是关于transforms的转化函数,放在transforms.Compose([这里放转化函数,以逗号进行分割])。转化函数博客地址:

我相信通过结合我的文章和他的文章,transforms这一方面应该没有什么问题了,祝大家学习愉快。