将png/jpg图像数据集转四维tensor输入PyTorch
如果拥有了自己的数据集,首先需要考虑的就是将你的数据集输入到PyTorch当中去。如果你的数据是来自于网络(比如说,从Kaggle下载,从论文作者处获得,从某个数据集官方的网站进行下载), 那你遇见的原始数据格式可能是各种情况,最常见的是各类压缩文件、pt文件、数据库格式文件或者png/jpg/webp等原始图像。如果你的数据是来自于实验室、公司数据库、甚至是领导/导师给的数据, 那你的数据大概率
如果拥有了自己的数据集,首先需要考虑的就是将你的数据集输入到PyTorch当中去。如果你的数据是来自于网络(比如说,从Kaggle下载,从论文作者处获得,从某个数据集官方的网站进行下载), 那你遇见的原始数据格式可能是各种情况,最常见的是各类压缩文件、pt文件、数据库格式文件或者png/jpg/webp等原始图像。如果你的数据是来自于实验室、公司数据库、甚至是领导/导师给的数据, 那你的数据大概率都是csv/txt/mat等结构的二维数据表。无论我们的原始数据集是呈现什么样的格式,我们必须将其转换为四维的张量,数据才可以被卷积神经网络处理。对于任意压缩文件,先解压查看内部是什么内容。
这里详细说明从图像png/jpg到四维tensor
当你拥有的数据是一系列图像,并且每个标签对应的图像是存放在单独的文件夹中时,这种情况比较简单。在torchvision中存在直接将文件夹中的图片打包成tensor类的类ImageFolder,它的参数和torchvision.datasets中其他数据导入类的参数非常相似,其中root是你的原始图像所在的根目录,transform是你希望对图像执行的具体操作。
这个类可以接受.jpg、.jpeg、.png、.ppm、.bmp、.pgm、.tif、.tiff、.webp这9种不同的图片格式作为输入,并且还能够通过文件夹的分类自动识别标签。在你的根目录下,每个类别需要有一个单独的文件夹,而类别文件夹中可以存在多个子文件夹,或直接存放图片。图片的格式不需要统一,只要在ImageFolder可接受的9中格式中即可。
train_dataset有几种可以调用的属性,例如:
train_dataset..classes #查看类别
train_dataset.targets #查看标签
train_dataset.imgs #查看具体的图像地址,返回所有图像的具体地址以及对应的标签
例如下面的例子:
ImageFolder只能够读取根目录的子文件夹中的图片,并且一定会将子文件夹的名称作为类别。当根目录中只有一个子文件夹时,则对所有的图片标签都标注为0。当根目录中没有文件夹,而是直接存放图片时,则会直接报错。
使用ImageFolder读取后的数据是无法轻易更改标签的,这是因为ImageFolder继承自pytorch中的visiondataset类,标签在这个父类中生成,并与特征图一起被固定为一个元组(用来表示从特征到标签的映射)。我们可以通过ImageFolder的各种属性、或索引等方式调用出这个元组的一份复制来进行展示,却无法直接触及到元组中的数据本身,因此我们无法通过ImageFolder读取出的标签进行改变。因此,当数据不能按照类别进行下载时,一般不会用ImageFolder对数据进行读取,而会选择更加灵活的方式:自己写一个读取数据用的类。
CLASS torch.utils.data.Dataset
在PyTorch中存在一个专门帮助我们构筑数据集的类Dataset,这个类在torch.utils.data模块下,属于PyTorch中数据处理的经典父类之一(另一个我们总是使用的经典父类是nn.Module)。在PyTorch中,许多torchvision.datasets中读数据的类,以及TensotDataset这些合并张量来生成数据的类,都继承自Dataset。如果一个读取数据的类继承自Dataset,那它读取出的数据一定是可以通过索引的方式进行调用和查看的,而继承自其他父类的、读取数据集的功能却不一定能使用索引进行查看,这种性质让Dataset子类的构成也与其他类不同。
Dataset的使用还可以参考Dataset与DataLoder基本使用方法与数据集切分函数
Dataset中规定,如果一个子类要继承Dataset,则必须在子类中定义__getitem__()方法。从这个方法的名字可以看出,它是帮助我们“获取对象”的方法。这个方法中的代码必须满足三个功能:
1)读取单个图片并转化为张量
2)读取该图片对应的标签
3)将该图片的张量与对应标签打包成一个样本并输出
该样本的形式是一个元组,元组中的第一个对象是图像张量,第二个对象是该图像对应的标签。
Dataset类中包含自动循环__getitem__()并拼接其输出结果的功能。对于任意继承自Dataset的子类,只要我们恰当地定义了__getitem__(),该子类的输出就一定是打包好的整个数据集。我们可以根据数据的实际情况定义__getitem__(),可以说实现了最大程度上的灵活性。
如何使用继承自Dataset的类读取不同的图片和标签类别?
在写具体的类之前,我们可以先定义__getitem__()方法中要求的内容,试着读取一张图片并生成样本的元组。事实上,有大量的库中都包含能够将图像转化为像素值的函数,原则上我们可以使用任何说自己熟悉的函数,比如使用opencv中的cv.imread函数进行图像的读取或使用pytorch官方推荐的scikit-learn图像处理库scikit-image来进行处理。
1)若标签为identity时
2)若标签为属性时
更多推荐
所有评论(0)