Pytorch:二、数据加载与数据集的划分(猫狗)
pytorch 的数据加载到模型的操作顺序是这样的:
1. 创建一个 Dataset 对象
2. 创建一个 DataLoader 对象
3. 循环这个 DataLoader 对象,将img, label加载到模型中进行训练
数据加载
我们拿到手的数据大致分为一下三种:
- 标签在文件夹上的数据
- 标签在图片名上的数据
- 标签与名称储存在csv文件中
一、标签在文件夹上的数据集
from torch.utils.data import DataLoader
import torch
from torchvision import transforms, datasetsdata_transform = transforms.Compose([transforms.Resize(32), #缩放图片,保持长宽比不变,最短边为32像素transforms.CenterCrop(32), #从图片中间开始切割出32*32大小的图片transforms.ToTensor(), #将图片转换成Tensor,归一化至[0,1]#标准化至[-1,1],规定均值和标准差transforms.Normalize(mean=[0.492, 0.461, 0.417],std=[0.256, 0.248, 0.251])
])
hymenoptera_dataset = datasets.ImageFolder(root="./train", transform=data_transform)
#数据加载,每次传入4张图片进行训练,随机打乱
dataset_loader = torch.utils.data.DataLoader(hymenoptera_dataset,batch_size=4,shuffle=True)
二、标签在图片名上的数据
import os
from torch.utils.data import DataLoader,Dataset
from torchvision import transforms
from PIL import Imageclass MyDataset(Dataset): #继承Datasetdef __init__(self,path_dir,transform=None): #初始化一些属性self.path_dir = path_dir #文件路径self.transform = transform #对图形进行处理self.images = os.listdir(self.path_dir) #把路径下的所有文件放在一个列表中def __len__(self): #返回整个数据集的大小return len(self.images)def __getitem__(self, index): #根据索引index返回图像及标签image_index = self.images[index] #根据索引获取图像文件名称img_path = os.path.join(self.path_dir,image_index) #获取图像的路径或目录img = Image.open(img_path).convert('RGB') #读取图像#根据目录名称获取图像标签(cat或dog)label = img_path.split('//')[-1].split('.')[0]#把字符转换为数字cat-0,dog-1label = 1 if 'dog' in label else 0if self.transform is not None:img = self.transform(img)return img,labeltransform = transforms.Compose([transforms.Resize(32), # 缩放图片,保持长宽比不变,最短边为32像素transforms.CenterCrop(32), # 从图片中间开始切割出32*32大小的图片transforms.ToTensor(), # 将图片转换成Tensor,归一化至[0,1]#标准化至[-1,1],规定均值和标准差transforms.Normalize(mean=[0.492, 0.461, 0.417], std=[0.256, 0.248, 0.251])
])dataset = MyDataset(r"C:\Users\牛牛\Desktop\机器学习\标签在图片名上的数据集\data\train", transform=transform)
#使用DataLoader加载数据
dataloader = DataLoader(dataset, batch_size=4, shuffle=True)
数据集的划分
将加载的数据划分为训练集、验证集和测试集
标签在图片名上的数据/标签在文件夹上的数据集
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'
from torchvision import transforms as T
from torch.utils.data import DataLoader, Dataset
import torch
from PIL import Imageclass MyDataset(Dataset): # 继承Datasetdef __init__(self, root, transforms=None, train=True, test=False): # 初始化一些属性self.test = test # 将test变量的赋值imgs = [os.path.join(root, img) for img in os.listdir(root)] # 数据的路径列表if self.test:imgs = sorted(imgs, key=lambda x: int(x.split('.')[-2].split('\\')[-1]))# 对测试集的数据进行排序else:imgs = sorted(imgs, key=lambda x: int(x.split('.')[-2]))# 对非测试集的数据进行排序# 排序的目的是便于后续的分割imgs_num = len(imgs) # 获取数据的长度便于切分数据集if self.test:self.imgs = imgs # 将测试集的数据直接导入elif train:self.imgs = imgs[:int(0.7 * imgs_num)] # 将train中数据的70%给trainelse:self.imgs = imgs[int(0.7 * imgs_num):] # 剩下的30%做验证集if transforms is None: # 对数据进行增强处理normalize = T.Normalize(mean=[0.488, 0.455, 0.417],std=[0.261, 0.255, 0.257])if self.test or not train:self.transforms = T.Compose([T.Resize(28),T.CenterCrop(28),T.ToTensor(),normalize])else:self.transforms = T.Compose([T.Resize(28),T.CenterCrop(28),T.RandomHorizontalFlip(),T.ToTensor(),normalize])def __len__(self): # 返回整个数据集的大小return len(self.imgs)def __getitem__(self, index): # 根据索引index返回图像及标签img_path = self.imgs[index]if self.test:label = int(self.imgs[index].split('.')[-2].split('\\')[-1])# 获取测试集文件名的部分作为标签else:label = 1 if 'dog' in img_path.split('\\')[-1] else 0# 获取train中文件名中的标签并进行数字化,dog为1,cat为0data = Image.open(img_path)data = self.transforms(data)return data, labeltrain_data = MyDataset(r"C:\Users\牛牛\Desktop\机器学习\标签在图片名上的数据集\data\train", train=True)
val_data = MyDataset(r"C:\Users\牛牛\Desktop\机器学习\标签在图片名上的数据集\data\train", train=False)
train_loader = torch.utils.data.DataLoader(train_data, batch_size=4, shuffle=True)
val_loader = torch.utils.data.DataLoader(val_data, batch_size=4, shuffle=True)
训练集验证集准备好后我们可以验证一下:
#训练集的数据
import torchvision
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
# 显示图像
def imshow(img):img = img / 2 + 0.5 # unnormalizenpimg = img.numpy()plt.imshow(np.transpose(npimg, (1, 2, 0)))plt.show()
# 随机获取部分训练数据
dataiter = iter(train_loader)
images, labels = dataiter.next()
# 显示图像
imshow(torchvision.utils.make_grid(images))
# 打印标签
print(' '.join('%s' % ["小狗" if labels[j].item()==1 else "小猫" for j in range(4)]))
输出:
#验证集的数据
import torchvision
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
# 显示图像
def imshow(img):img = img / 2 + 0.5 # unnormalizenpimg = img.numpy()plt.imshow(np.transpose(npimg, (1, 2, 0)))plt.show()
# 随机获取部分训练数据
dataiter = iter(val_loader)
images, labels = dataiter.next()
# 显示图像
imshow(torchvision.utils.make_grid(images))
# 打印标签
print(' '.join('%s' % ["小狗" if labels[j].item()==1 else "小猫" for j in range(4)]))
输出:
三、标签与名称储存在csv文件中
还有一种特殊的就是标签与名称的对应关系都储存在一个csv文件中:
其中id指的是图片的名字,breed指的是狗的品种,可以看到狗的品种非常的多,所以需要将每一个种类的数据照片放到对应种类命名的文件夹中,代码如下:
import math
import os
import shutil
from collections import Counterdata_dir = r"C:\Users\牛牛\Desktop\机器学习\猫狗识别_csv" #数据集的根目录
label_file = 'labels.csv' #根目录中csv的文件名加后缀
train_dir = 'train' #根目录中的训练集文件夹的名字
test_dir = 'test' #根目录中的测试集文件夹的名字
input_dir = 'train_valid_test' #用于存放拆分数据集的文件夹的名字,可以不用先创建,会自动创建
batch_size = 4 #送往训练的一批次中的数据集的个数
valid_ratio = 0.1 #将训练集拆分为90%为训练集10%为验证集def reorg_dog_data(data_dir, label_file, train_dir, test_dir, input_dir,valid_ratio):# 读取训练数据标签,label.csv文件读取标签以及对应的文件名。with open(os.path.join(data_dir, label_file), 'r') as f:# 跳过文件头行(栏名称)。lines = f.readlines()[1:]tokens = [l.rstrip().split(',') for l in lines]idx_label = dict(((idx, label) for idx, label in tokens))labels = set(idx_label.values())num_train = len(os.listdir(os.path.join(data_dir, train_dir)))#获取训练集的数量便于数据集的分割# 训练集中数量最少一类的狗的数量。min_num_train_per_label = (Counter(idx_label.values()).most_common()[:-2:-1][0][1])# 验证集中每类狗的数量。num_valid_per_label = math.floor(min_num_train_per_label * valid_ratio)label_count = dict()def mkdir_if_not_exist(path):#判断是否有存放拆分后数据集的文件夹,没有就创建一个if not os.path.exists(os.path.join(*path)):os.makedirs(os.path.join(*path))# 整理训练和验证集,将数据集进行拆分复制到预先设置好的存放文件夹中。for train_file in os.listdir(os.path.join(data_dir, train_dir)):idx = train_file.split('.')[0]label = idx_label[idx]mkdir_if_not_exist([data_dir, input_dir, 'train_valid', label])shutil.copy(os.path.join(data_dir, train_dir, train_file),os.path.join(data_dir, input_dir, 'train_valid', label))if label not in label_count or label_count[label] < num_valid_per_label:mkdir_if_not_exist([data_dir, input_dir, 'valid', label])shutil.copy(os.path.join(data_dir, train_dir, train_file),os.path.join(data_dir, input_dir, 'valid', label))label_count[label] = label_count.get(label, 0) + 1else:mkdir_if_not_exist([data_dir, input_dir, 'train', label])shutil.copy(os.path.join(data_dir, train_dir, train_file),os.path.join(data_dir, input_dir, 'train', label))# 整理测试集,将测试集复制存放在新建路径下的unknown文件夹中。mkdir_if_not_exist([data_dir, input_dir, 'test', 'unknown'])for test_file in os.listdir(os.path.join(data_dir, test_dir)):shutil.copy(os.path.join(data_dir, test_dir, test_file),os.path.join(data_dir, input_dir, 'test', 'unknown'))#载入数据,进行数据的拆分
reorg_dog_data(data_dir, label_file, train_dir, test_dir, input_dir,valid_ratio)
当我们运行完程序后,可以看到:
运行代码之后我们创建了train_valid_test文件夹,测试集是我们要去测试的数据,没有标签,所以测试集图像都保存在unknown文件夹中,训练集、验证集和训练验证集文件夹下将每一个种类的数据照片放到了对应种类命名的文件夹中,此时就相当于标签在文件夹上,接下来的方法就与第一种猫狗二分类标签在文件夹上的方法类似,只不过这个是多分类,至此我们完成了数据的拆分
数据拆分后便可以进行数据的加载与训练集验证集的划分了,使用ImageFolder进行数据集的加载,在加载前需要进行数据强化函数的定义,也可以在未进行transforms处理之前对加载的数据集进行查验
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'
import torch
from torch.utils.data import DataLoader
from torchvision import transforms, datasets# transform_train = transforms.Compose([
# # 随机对图像裁剪出面积为原图像面积0.08~1倍、且高和宽之比在3/4~4/3的图像,再放缩为高和宽均为224像素的新图像
# transforms.RandomResizedCrop(28, scale=(0.08, 1.0),
# ratio=(3.0/4.0, 4.0/3.0)),
# # 以0.5的概率随机水平翻转
# transforms.RandomHorizontalFlip(),
# # 随机更改亮度、对比度和饱和度
# transforms.ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4),
# transforms.ToTensor(),
# # 对各个通道做标准化,(0.485, 0.456, 0.406)和(0.229, 0.224, 0.225)是在ImageNet上计算得的各通道均值与方差
# transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) # ImageNet上的均值和方差
# ])# # 在测试集上的图像增强只做确定性的操作
# transform_test = transforms.Compose([
# transforms.Resize(28),
# # 将图像中央的高和宽均为224的正方形区域裁剪出来
# transforms.CenterCrop(28),
# transforms.ToTensor(),
# transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
# ])
#也可以使用之前的transforms的函数
data_transform = transforms.Compose([transforms.Resize(32), # 缩放图片(Image),保持长宽比不变,最短边为32像素transforms.CenterCrop(32), # 从图片中间切出32*32的图片transforms.ToTensor(), # 将图片(Image)转成Tensor,归一化至[0, 1]transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])# 标准化至[-1, 1],规定均值和标准差#然后开始加载数据集
new_data_dir=r"C:\Users\牛牛\Desktop\机器学习\猫狗识别_csv\train_valid_test"
train_ds = datasets.ImageFolder(root=os.path.join(new_data_dir, 'train'),transform=data_transform)
valid_ds = datasets.ImageFolder(root=os.path.join(new_data_dir, 'valid'),transform=data_transform)
train_loader = torch.utils.data.DataLoader(train_ds,batch_size=4,shuffle=True)
valid_loader = torch.utils.data.DataLoader(valid_ds,batch_size=4,shuffle=True)
可以检查一下我们经过划分和处理过后的数据:
#验证数据
for img, label in valid_ds: #也可更改为训练集数据print("图像img的形状{},标签label的值{}".format(img.shape, label))print("图像数据预处理后:\n",img)break
输出:
图像img的形状torch.Size([3, 32, 32]),标签label的值0
图像数据预处理后:tensor([[[-1.9295, -1.8953, -1.9638, ..., 1.8550, 1.9235, 1.9407],[-1.8268, -1.9124, -1.8953, ..., 1.8379, 1.9235, 1.9407],[-1.2103, -1.9124, -1.8439, ..., 1.8550, 1.9749, 1.9749],...,[-0.7993, -1.6213, -1.6898, ..., -0.5767, -0.5767, -0.6281],[-0.4911, -1.0219, -1.7412, ..., -0.5767, -0.6452, -0.6794],[-0.4739, -0.6281, -1.5185, ..., -0.5253, -0.6965, -0.7479]],[[-1.8256, -1.8256, -1.8782, ..., 1.3782, 1.5707, 1.3957],[-1.7206, -1.8431, -1.8081, ..., 1.4307, 1.6583, 1.3957],[-1.1604, -1.8431, -1.7556, ..., 1.4482, 1.7283, 1.4132],...,[-0.9678, -1.6681, -1.6856, ..., -1.0728, -1.0728, -1.1253],[-0.8277, -1.2129, -1.7381, ..., -1.0728, -1.1429, -1.1604],[-0.8277, -0.8978, -1.6155, ..., -1.0203, -1.1779, -1.2479]],[[-1.5081, -1.4907, -1.5430, ..., 1.0888, 1.2805, 0.9319],[-1.4559, -1.5430, -1.4907, ..., 1.1759, 1.4200, 0.9668],[-1.0898, -1.5604, -1.4559, ..., 1.1759, 1.4722, 0.9319],...,[-1.1770, -1.4907, -1.4210, ..., -1.1770, -1.1770, -1.2119],[-1.1944, -1.3513, -1.5779, ..., -1.1770, -1.2293, -1.1944],[-1.1247, -1.1247, -1.5430, ..., -1.1073, -1.2467, -1.2293]]])
import matplotlib.pyplot as plt
import numpy as np
import torchvision# 显示图像
def imshow(img):img = img / 2 + 0.5 # unnormalizenpimg = img.numpy()plt.imshow(np.transpose(npimg, (1, 2, 0)))plt.show()
# 随机获取部分训练数据
dataiter = iter(train_loader) #换此处的值即可切换数据集
images, labels = dataiter.next()
# 显示图像
imshow(torchvision.utils.make_grid(images))
# 打印标签
print(labels[0],labels[1],labels[2],labels[3])
输出:
Pytorch:二、数据加载与数据集的划分(猫狗)相关推荐
- PyTorch:数据加载,数学原理,猫鱼分类,CNN,预训练,迁移学习
1,数据加载 PyTorch开发了与数据交互的标准约定,所以能一致地处理数据,而不论处理图像.文本还是音频.与数据交互的两个主要约定是数据集(dataset)和数据加载器(dataloader).数据 ...
- TensorFlow2数据加载与数据集
加载数据集 keras 加载在线数据集 tf.keras.datasets提供了加载在线数据集的API,其中可加载的数据集包括: boston_housing module: Boston housi ...
- PyTorch 系列 | 数据加载和预处理教程
图片来源:Unsplash,作者:Damiano Baschiera 2019 年第 66 篇文章,总第 90 篇文章 本文大约 8000 字,建议收藏阅读 原题 | DATA LOADING AND ...
- matlab 读取csv_利用Pytorch进行数据加载1--CSV文件的读取和显示
import os # 文件处理模块,用于处理文件和目录 import torch # pytorch的深度学习框架 import pandas as pd #人脸识别库 from skimage i ...
- pytorch学习(一)数据加载之前的预处理(UCSD数据集)
最近在做有关视频异常检测方面的实验,需要用到UCSD数据集,pytorch自定义加载自己的数据集时需要将自己的数据的路径以及标签存放到txt文档中,方便后续的数据加载. 最后我会给出生成好的UCSD数 ...
- dataset__getitem___PyTorch源码解析与实践(1):数据加载Dataset,Sampler与DataLoader
献给学习PyTorch在路上或者计划较深入理解PyTorch的同行者们 写在前面 笔者一直使用tf,大势所趋决定转PyTorch,这个系列就作为我学习PyTorch的笔记与心得. 网络上PyTorch ...
- PyTorch1.12 亮点一览 | DataPipe + TorchArrow 新的数据加载与处理范式
目录 前言 现有的 Dataset 和 DataLoader 及其存在的问题 新的数据加载方式:DataPipe 与 DataLoader2 结构化数据处理新范式:TorchArrow 总结 参考链接 ...
- 深度学习-Pytorch:项目标准流程【构建、保存、加载神经网络模型;数据集构建器Dataset、数据加载器DataLoader(线性回归案例、手写数字识别案例)】
1.拿到文本,分词,清晰数据(去掉停用词语): 2.建立word2index.index2word表 3.准备好预训练好的word embedding 4.做好DataSet / Dataloader ...
- pytorch入门(二):数据加载和处理
pytorch入门(二):数据加载和处理 小引 数据加载 引包 数据集 编写辅助函数 显示图像及其特征点 定义数据集类 数据处理 组合变换 遍历数据集 其他注意事项 本章对应pytorch官方文档链接 ...
- pytorch基础知识整理(二)数据加载
pytorch数据加载组件位于torch.utils.data中. from torch.utils.data import DataLoader, Dataset, Sampler 1, torch ...
最新文章
- 关于View测量中的onMeasure函数
- vscode 无法跳转到函数定义_玩转VS Code
- java去掉字符串中前后空格函数_JAVA中去掉字符串空格各种方法详解
- js返回上一页与前进下一页
- exec go 重启_无停机优雅重启 Go 程序
- 信息学奥赛一本通 1848:【07NOIP提高组】字符串的展开 | OpenJudge NOI 1.7 35:字符串的展开 | 洛谷 P1098 [NOIP2007 提高组] 字符串的展开
- 【练习手记】【多题合集】用树状数组做线段树练习1、2、3
- 网桥和交换机的工作原理及区别
- 孩子学python_教孩子学编程 Python
- 57、弱电网络管理入门与基础技术
- 突如其来的第一个1024要笑着过
- Linux内存管理 (1)物理内存初始化
- Maven项目 cityFileFK02数据库连接(课外完成)
- linux查看目录是不是btrfs,btrfs文件系统常用命令使用
- python画箭头_Python中绘制箭头
- 使用Python 批量转移*.tif和*.mov文件
- 普通运维人员是秋后的蚂蚱?
- Typora导出PDF时,对PDF格式的修改
- 《马东的职场 B 计划》 学习笔记
- uvc led fabrication review
热门文章
- 编译祁大神的iguana,大神就是大神.
- 傅里叶变换复数形式的实部代表什么_复数形式傅里叶变换的物理意义中,相位究竟指的是什么?...
- Python一小时开发彩色动态二维码生成器,并使用虚拟化境进行打包发布EXE程序。
- 软件开发工具——理论篇
- win7计算机属性恢复,win7怎么打开系统还原功能?win7打开系统还原功能的方法步骤...
- 脚本小子_python数据类型代码
- zabbix报警	Lack of free swap space on zabbix
- 加权评分模型(weighted scoring model)
- On the Sentence Embeddings from Pre-trained Language Models
- STM32固件库点亮LED灯