以猫狗大战数据集为例
Cats vs. Dogs(猫狗大战)数据集是Kaggle与泰坦尼克号并列的一个入门任务,利用给定的数据结合不同的算法实现猫和狗的识别。
原始数据集其中包含了训练集和测试集,训练集中猫和狗的图片数量都是12500张且按顺序排序,测试集中猫和狗混合乱序图片一共12500张。
为了简化任务,在这里我只使用猫狗图像各4000张、共8000张数据,链接如下:
链接:https://pan.baidu.com/s/1cJ-f-q5CQV5rdgQVAGv72Q
提取码:ultv
数据在神经网络的模型中进行传播前首先需要保证尺寸相同(部分金字塔模型也可以处理不同尺寸的输入,本次不做讨论)。在MNIST案例中,数据的格式、尺寸都已经集成好,我们只需要进行下载、加载。但是对于本任务,猫狗图像的格式虽然都是jpg,但是尺寸并不统一,所以需要进行初步的转化。例如,可以对图像进行resize、crop等操作。
这里,只提供一种比较简单的方法:resize
对于所有图像,我们将其Resize到100x100的尺寸,代码如下
import cv2
import os
from tqdm import tqdm
DataPath=r'TrainingData'# 训练数据
SavePath=r'ResizedData'
for img_dir in os.listdir(DataPath):
# 包含类别信息的文件夹
img_label_path=os.path.join(DataPath,img_dir)
# 存储处理后的图片的文件夹
save_label_path=os.path.join(SavePath,img_dir)
if not os.path.exists(save_label_path):
os.mkdir(save_label_path)
# 使用tqdm查看每一类别图片处理进度
tbar = tqdm(os.listdir(img_label_path), ncols=100)
for image in tbar:
# 进入到文件夹下进行图片遍历
image_path=os.path.join(img_label_path,image)
# 使用cv2读取图片
image_old=cv2.imread(image_path)
image_new=cv2.resize(image_old,(100,100))
# 保存图像
save_path=os.path.join(save_label_path,image)
cv2.imwrite(save_path,image_new)
print("当前处理的图片类别为{},保存路径为{},已处理完成".format(img_dir, save_label_path))
在Pytroch中创建数据集主要使用两个类:Dataset和DataLoader。
其中,Dataset既是一个集成数据集的库(例如MNIST、CIFAR都集成在Datasets中),又是一个用来表示数据集的抽象类,我们的数据集可以用这个类来构建;
而DataLoader本质上就是一个 iterable(内部定义了 __ iter __ 方法),通过读取Datasets中的数据,组装成一个batch后返回一个tensor。
总而言之,Dataset是构建Dataloader的重要实例参数之一。
Dataset类是Pytorch中所有数据集加载类中应该继承的父类,其中父类中的两个私有成员函数必须被重载,否则将会触发错误提示:
def __getitem__(self,index):
# 编写支持数据集索引的函数
def __len__(self):
# 返回数据集的大小
重点是 getitem函数,getitem接收一个index,然后返回图片数据和标签,这个index通常指的是一个list的index,这个list的每个元素就包含了图片数据的路径和标签信息。 所以这里我将介绍一种比较普遍的做法:
1-制作存储了图片的路径和标签信息的txt
2-将这些信息转化为list,该list每一个元素对应一个样本
3-通过getitem函数,读取数据和标签,并返回数据和标签
路径建议使用绝对路径,以防文件相对位置发生变化时读取失败。
标签一定要是整型变量(张量求梯度),一定要从0开始。
标签一定要是整型变量(张量求梯度),一定要从0开始。
标签一定要是整型变量(张量求梯度),一定要从0开始。
重要的事说三遍,大家一定记住,否则会触发Assertion cur_target >= 0 && cur_target < n_classes‘ failed.
特效…
import os
import random
DataPath=r'ResizedData'# 训练数据
absolutePath=r'D:\Code\pytorch\Pytorch_Train\catvsdog\data'# 这里需要替换成catvsdog的绝对路径
label=0
if __name__ == '__main__':
for dataClass in os.listdir(DataPath):
# 读取猫狗数据
data=os.listdir(os.path.join(DataPath,dataClass))
# 打乱顺序
random.shuffle(data)
# 训练集占所有数据的4/5
train_len=len(data)*4//5
# 将图片按照8:2划分为训练、验证
train_list,val_list=data[:train_len],data[train_len:]
# 将训练集写入train.txt
with open(os.path.join(absolutePath,'train.txt'), 'a')as f:
for img in train_list:
f.write(os.path.join(absolutePath,DataPath,dataClass,img)+ ' ' + str(label)+'\n')
print("标签为{}的训练集图片处理完毕".format(dataClass))
# 将验证集写入val.txt
with open(os.path.join(absolutePath,'val.txt'), 'a+')as f:
for img in val_list:
f.write(os.path.join(absolutePath,DataPath,dataClass,img) + ' ' + str(label)+'\n')
print("标签为{}的验证集图片处理完毕".format(dataClass))
label+=1
困难的任务前边已经解决了,这部分并不是很难理解,直接上代码
import torch
import numpy as np
from PIL import Image
from torch.utils.data.dataset import Dataset
import torchvision.transforms as transforms
def read_txt(path):
# 读取txt文件,将图像路径和标签写入到列表中并返回
ims,labels=[],[]
with open(path,'r') as f:
for sample in f.readlines():
im,label=sample.strip().split(" ")
ims.append(im)
labels.append(label)
return ims,labels
class ImageDataset(Dataset):
# 重载DataLoader
def __init__(self, txtpath, transform=None):
super().__init__()
self.ims, self.labels = read_txt(txtpath)
self.transform = transform
def __getitem__(self, index):
im_path=self.ims[index]
label=self.labels[index]
# 使用Image库处理图片,将其转化为张量
image=Image.open(im_path)
transf = transforms.ToTensor()
image = transf(image)
# image = self.transform(image).float().cuda()
label=torch.from_numpy(np.asarray(label,dtype=np.int32)).long()
return image,label
def __len__(self):
return len(self.ims)
后续的model及train文件之前已经介绍,这里不再赘述
链接:https://pan.baidu.com/s/1f-Gy4CAzrB0c7fUhvsKing
提取码:lo59
归去来兮,田园将芜胡不归?既自以心为形役,奚惆怅而独悲?悟已往之不谏,知来者之可追。 实迷途其未远,觉今是而昨非。舟遥遥以轻飏,风飘飘而吹衣。问征夫以前路,恨晨光之熹微。
乃瞻衡宇,载欣载奔。僮仆欢迎,稚子候门。三径就荒,松菊犹存。携幼入室,有酒盈樽。引壶觞以自酌,眄庭柯以怡颜。倚南窗以寄傲,审容膝之易安。园日涉以成趣,门虽设而常关。策扶老以流憩,时矫首而遐观。云无心以出岫,鸟倦飞而知还。景翳翳以将入,抚孤松而盘桓。
归去来兮,请息交以绝游。世与我而相违,复驾言兮焉求?悦亲戚之情话,乐琴书以消忧。农人告余以春及,将有事于西畴。或命巾车,或棹孤舟。既窈窕以寻壑,亦崎岖而经丘。木欣欣以向荣,泉涓涓而始流。善万物之得时,感吾生之行休。
已矣乎!寓形宇内复几时?曷不委心任去留?胡为乎遑遑欲何之?富贵非吾愿,帝乡不可期。怀良辰以孤往,或植杖而耘耔。登东皋以舒啸,临清流而赋诗。聊乘化以归尽,乐夫天命复奚疑!