1.将图片的路径和标签写入csv文件并实现读取

  # 创建一个文件,包含image,存放方式:label pokemeon\\mew\\0001.jpg,0
def load_csv(self,filename):
if not os.path.exists(os.path.join(self.root,filename)):
images = [] # 将所有的信息组成一个列表,类别信息通过中间的一个路径判断
for name in self.name2label.keys():
# pokemeon\\mew\\0001.jpg mew可以通过字典查看其类别
images += glob.glob(os.path.join(self.root,name,'*.png'))#img的完整路径
images += glob.glob(os.path.join(self.root,name,'*.jpg'))
random.shuffle(images)
with open(os.path.join(self.root,filename),'w') as f:
writer = csv.writer(f)
for img in images:
name = img.split(os.sep)
label = self.name2label[name[-2]]
writer.writerow([img,label]) # 从csv中读取文件
images, labels = [], []
with open(os.path.join(self.root,filename),'r') as f:
reader = csv.reader(f)
for row in reader:
img,label = row
label = int(label)
images.append(img)
labels.append(label)
assert len(images) == len(labels) # 保证数据长度一致
       return images,labels

2.加载自定义数据集

 """
自定义数据集
image_resize
data argumentation(数据增强):Rotate,crop
normalize:mean,std
ToTensor """
import torch
import os,glob
import random,csv
from torch.utils.data import Dataset,DataLoader
from torchvision import transforms
from PIL import Image
import visdom class Pokemon(Dataset):
def __init__(self,root,resize,mode):
super(Pokemon,self).__init__()
self.root = root
self.resize = resize
self.name2label = {}
for name in os.listdir(os.path.join(root)): #把文件和dir都会加载近来
if not sorted(os.path.isdir(os.path.join(root,name))):#排序后,文件夹顺序固定了
continue
self.name2label[name] = len(self.name2label.keys())
# name2label:{文件夹名,类别编号}
# 创建一个文件,包含image,存放方式:label pokemeon\\mew\\0001.jpg,0
self.images, self.labels = self.load_csv('images.csv')
# 对数据进行裁剪,mode:train-0.6,validation-0.2,test-0.2数据量是不同的
if mode == 'train':
self.images = self.images[:,int(len(self.images)*0.6)]
self.labels = self.labels[:,int(len(self.images)*0.6)]
elif mode == 'val':
self.images = self.images[int(len(self.images)*0.6):int(len(self.images)*0.8)]
self.labels = self.labels[int(len(self.labels)*0.6):int(len(self.labels)*0.8)]
else:
self.images = self.images[int(len(self.images) * 0.8):]
self.labels = self.labels[int(len(self.labels) * 0.8):] def load_csv(self,filename):
if not os.path.exists(os.path.join(self.root,filename)):
images = [] # 将所有的信息组成一个列表,类别信息通过中间的一个路径判断
for name in self.name2label.keys():
# pokemeon\\mew\\0001.jpg mew可以通过字典查看其类别
images += glob.glob(os.path.join(self.root,name,'*.png'))#img的完整路径
images += glob.glob(os.path.join(self.root,name,'*.jpg'))
random.shuffle(images)
with open(os.path.join(self.root,filename),'w') as f:
writer = csv.writer(f)
for img in images:
name = img.split(os.sep)
label = self.name2label[name[-2]]
writer.writerow([img,label])
# 从csv中读取文件
images, labels = [], []
with open(os.path.join(self.root,filename),'r') as f:
reader = csv.reader(f)
for row in reader:
img,label = row
label = int(label)
images.append(img)
labels.append(label)
assert len(images) == len(labels) # 保证数据长度一致
return images,labels def __len__(self):
return len(self.images) def __getitem__(self, idx):
# idx是[0-len(self.images]
# self.images,self.label
# img:pokemeon\\mew\\0001.jpg(这是一个路径)要转变成img数据
# label:是数字
img, label = self.images[idx], self.labels[idx]
tf = transforms.Compose([
lambda x:Image.open(x).convert('RGB'),# string path -> img data
transforms.Resize(int(self.resize*1.25), int(self.resize*1.25)),
transforms.Randomrotation(15), # 旋转度数
transforms.CenterCrop(self.resize),#中心裁剪,保留resize大小
transforms.ToTensor(),
transforms.Normalize(mean=[0.485,0.456,0.406],
std=[0.229,0.224,0.225]) # 归一化之后,范围为-1~1,之前的图片范围为0~1
])
img = tf(img) # 将path转换成数据
label = torch.tensor(label) # 将变量label转换成tensor
return img,label def denormalize(self,x_hat):
mean=[0.485,0.456,0.406]
std=[0.229,0.224,0.225]
# x:[c,h,w]
# x_hat = (x-mean)/std
# maen[3]->[3,1,1]
mean = torch.tensor(mean).unsqueeze(1).unsqueeze(1)
std = torch.tensor(std).unsqueeze(1).unsqueeze(1)
x = x_hat * std+mean
return x def main():
import torchvision
vis = visdom.Visdom()
"""
如果存储比较规范的话,可以使用下面简单的代码加载数据集,文件夹的标签从0开始编码
tf = transforms.Compose([
transforms.Resize((64,64)),
transforms.ToTensor()
])
db = torchvision.datasets.ImageFolder('./pokemon',transform=tf)
loader = DataLoader(db,batch_size=32,shuffle=True)
print(db.class_to_idx) #查看类标签 """
db = Pokemon('./pokemon', 224, 'train') # 根据idx,返回一个
x,y = next(iter(db))
print('sample:',x.shape,y.shape)
#可视化
vis.image(db.denormalize(x),win='sample_x',opts=dict(title = 'sample_x'))
# 加载一批
loader = DataLoader(db,batch_size = 32,shuffle=True,num_workers=8 )
for x,y in loader:
vis.images(db.denormalize(x), nrow=8, win='batch',opts=dict(title='batch'))
vis.text(str(y.numpy()),win='label',opts=dict(title='batch-y')) if __name__ == '__main__':
main()

小结:

在加载自定义数据集时,一般步骤

1.定义一个类继承Dataset

2.在类中读取数据集(图片的路径),重写len函数,和getitem函数

在len函数中返回数据集的长度

在getitem函数中,处理一张图片,单个图片路径转换成图片数据(包括transform转换),返回该图片数据和标签

3,将处理好的数据集(均为张量)放入DataLoader中,进行分批

loader = DataLoader(db,batch_size = 32,shuffle=True,num_workers=8 )

4.训练时通过enumerate遍历每个batchsize

torch_13_自定义数据集实战的更多相关文章

  1. SpringBoot2.x过滤器Filter和使用Servlet3.0配置自定义Filter实战

    补充:SpringBoot启动日志 1.深入SpringBoot2.x过滤器Filter和使用Servlet3.0配置自定义Filter实战(核心知识) 简介:讲解SpringBoot里面Filter ...

  2. Tensorflow2 自定义数据集图片完成图片分类任务

    对于自定义数据集的图片任务,通用流程一般分为以下几个步骤: Load data Train-Val-Test Build model Transfer Learning 其中大部分精力会花在数据的准备 ...

  3. pytorch加载语音类自定义数据集

    pytorch对一下常用的公开数据集有很方便的API接口,但是当我们需要使用自己的数据集训练神经网络时,就需要自定义数据集,在pytorch中,提供了一些类,方便我们定义自己的数据集合 torch.u ...

  4. MMDetection 快速开始,训练自定义数据集

    本文将快速引导使用 MMDetection ,记录了实践中需注意的一些问题. 环境准备 基础环境 Nvidia 显卡的主机 Ubuntu 18.04 系统安装,可见 制作 USB 启动盘,及系统安装 ...

  5. Scaled-YOLOv4 快速开始,训练自定义数据集

    代码: https://github.com/ikuokuo/start-scaled-yolov4 Scaled-YOLOv4 代码: https://github.com/WongKinYiu/S ...

  6. PyTorch 自定义数据集

    准备数据 准备 COCO128 数据集,其是 COCO train2017 前 128 个数据.按 YOLOv5 组织的目录: $ tree ~/datasets/coco128 -L 2 /home ...

  7. Android自定义View实战(SlideTab-可滑动的选择器)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/52178553 本文出自:[openXu的博客] 目录: 初步分析重写onDraw绘制 重写o ...

  8. 高级UI晋升之自定义view实战(七)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章自定义ViewGroup实现瀑布流效果来进行详解dispatchTouch ...

  9. 自定义View实战

    PS:上一篇从0开始学自定义View有博友给我留言说要看实战,今天我特意写了几个例子,供大家参考,所画的图案加上动画看着确实让人舒服,喜欢的博友可以直接拿到自己的项目中去使用,由于我这个写的是demo ...

随机推荐

  1. IT兄弟连 HTML5教程 HTML文档主体标记body

    在HTML的<body>和</body>标记中定义文档的主体,包含文档的所有内容(比如文本.超链接.图像.表格和列表等等).<body>标签有自己的属性,设置< ...

  2. IT兄弟连 HTML5教程 HTML5的基本语法 简单HTML实例制作

    现在学习HTML5的方式 目前HTML还处于HTML4与HTML5之间的过渡使用阶段.移动端的Web界面开发已经全面使用HTML5的技术,而在PC端由于用户升级浏览器周期较长,面临着页面的兼容性问题, ...

  3. java自定义equals函数和hashCode函数

    所有类都继承自Object类,他所有的非final方法:equals,hashCode, toString, clone 和 finalize,它们都有通用约定. 我们在覆盖这些方法的时候需要遵循这些 ...

  4. rxjava介绍

    Observable 在RxJava1.x中,最熟悉的莫过于Observable这个类了,笔者刚使用RxJava2.x时,创建一个Observable后,顿时是懵逼的.因为我们熟悉的Subscribe ...

  5. HttpClient 如何设置超时时间

    今天分享一个巨坑,就是 HttpClient.这玩意有多坑呢?就是每个版本都变,近日笔者深受其害. 先看一下代码,我要发送请求调用一个c++接口. public static String doPos ...

  6. Elasticsearch 6.x版本全文检索学习之倒排索引与分词、Mapping 设置

    Beats,Logstash负责数据收集与处理.相当于ETL(Extract Transform Load).Elasticsearch负责数据存储.查询.分析.Kibana负责数据探索与可视化分析. ...

  7. Swagger UI in AspNetCore WebAPI

    Swagger其实包含了三个部分,分别是Swagger Editor文档接口编辑器,根据接口文档生成code的Swagger Codegen,以及生成在线文档的Swagger UI.在AspNetCo ...

  8. new一个对象的初始化过程

    ############################### 今天总结一下,new对象的初始化过程. ############################### 首先,当不含static成员时, ...

  9. GO基础之函数

    一.Go语言函数的格式 函数构成了代码执行的逻辑结构,在Go语言中,函数的基本组成为:关键字 func.函数名.参数列表.返回值.函数体和返回语句,每一个程序都包含很多的函数,函数是基本的代码块. 函 ...

  10. 【JavaWeb】EL表达式

    EL表达式 EL表达式语言,用于简化JSP的输出: EL表达式的基本语法:${表达式}: 示例:<h1>学生姓名:${student.name}</h1> 作用域对象 忽略书写 ...