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. LeetCode 706:设计哈希映射 Design HashMap

    题目: 不使用任何内建的哈希表库设计一个哈希映射 具体地说,你的设计应该包含以下的功能 put(key, value):向哈希映射中插入(键,值)的数值对.如果键对应的值已经存在,更新这个值. get ...

  2. 【shell脚本】对100以内的所有正整数相加求和(1+2+3+4...+100)===sum.sh

    对100以内的所有正整数相加求和(1+2+3+4...+100) [root@VM_0_10_centos shellScript]# cat sum.sh #!/bin/bash # 对100以内的 ...

  3. GO 键盘输入和打印输出

    键盘输入和打印输出 一.打印输出 1.1 fmt包 fmt包实现了类似C语言printf和scanf的格式化I/O.格式化verb('verb')源自C语言但更简单. 详见官网fmt的API:http ...

  4. WPF TextBox绑定Int类型的属性

    TextBox双向绑定int属性,清空输入框时Setter方法未触发. 我的解决方案: 1.属性置为int?: 2.xmlns:sys="clr-namespace:System;assem ...

  5. VS 自动创建带增删查改的MVC网站

    VS 自动创建带增删查改的MVC网站 MVC.Net教程   废话放在前头,说一下这个文章的缘起某天某妹纸找我,说这个MVC的创建不太会,要记一下controllers.models.还有页面引用的东 ...

  6. SQL server已经设置为单用户模式,还是无法做分离、属性设置等操作

    https://www.cnblogs.com/xingyunqiu/p/10336938.html SQL server已经设置为单用户模式,Sql server还原失败数据库正在使用,无法获得对数 ...

  7. 高效取余运算(n-1)&hash原理探讨

    Java的HashMap源码中用到的(n-1)&hash这样的运算,查找发现这是一种高效的求余数的办法,但其中的原理是什么呢为什么可以这么做呢? 先上结论:假设被除数是x,对于除数是2n的取余 ...

  8. Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲

    Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲 Java生鲜电商平台:   微服务是当前非常流行的技术框架,通过服务的小型化.原子化以及分布式架构的弹性伸缩和高可用性, ...

  9. 2019年上半年收集到的人工智能LSTM干货文章

    2019年上半年收集到的人工智能LSTM干货文章 门控神经网络:LSTM 和 GRU 简要说明 LSTM-CNN-Attention算法系列之一:LSTM提取时间特征 对时间序列分类的LSTM全卷积网 ...

  10. [Linux] deepin系统添加PHP仓库源出错Error: could not find a distribution template for Deepin/stable

    aptsources.distro.NoDistroTemplateException: Error: could not find a distribution template for Deepi ...