0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

利用Python和PyTorch处理面向对象的数据集(1)

efwedfd 来源:efwedfd 作者:efwedfd 2022-08-02 08:03 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

机器学习中一个常见问题是判定与数据交互的最佳方式。

在本文中,我们将提供一种高效方法,用于完成数据的交互、组织以及最终变换(预处理)。随后,我们将讲解如何在训练过程中正确地把数据输入给模型。

PyTorch 框架将帮助我们实现此目标,我们还将从头开始编写几个类。PyTorch 可提供更完整的原生类,但创建我们自己的类可帮助我们加速学习。

第 1 部分:原始数据和数据集

首先我们把尚未经过组织的所有样本称为“原始数据”。

把“数据集”定义为现成可用的数据,即含标签以及基本函数接口(以便于使用原始数据信息)的原始数据。

此处我们使用一种简单的原始数据形式:1 个包含图像和标签的文件夹。

但此方法可扩展至任意性质的样本(可以是图片、录音、视频等)以及包含标签的文件。

标签文件中的每一行都用于描述 1 个样本和相关标签,格式如下:

file_sample_1 label1

file_sample_2 label2

file_sample_3 label3

(。..)

当能够完成一些基本信息查询(已有样本数量、返回特定编号的样本、预处理每个样本等)时,说明我们已从原始数据集创建了 1 个数据集。

此方法基于面向对象编程以及创建用于数据处理的 “类”。

对于一组简单的图像和标签而言,此方法可能看上去略显杀鸡用牛刀(实际上,此用例通常是通过创建分别用于训练、验证和测试的独立文件夹来进行处理的)。但如果要选择标准交互方法,则此方法将来可复用于多种不同用例,以节省时间。

Python 中处理数据

在 Python 中所有一切都是对象:整数、列表、字典都是如此。

构建含标准属性和方法的“数据集”对象的原因多种多样。我认为,代码的精致要求就足以合理化这一选择,但我理解这是品味的问题。可移植性、速度和代码模块化可能是最重要的原因。

在许多示例以及编码书籍中,我发现了面向对象的编码(尤以类为甚)的其它有趣的功能和优势,总结如下:

• 类可提供继承

• 继承可提供复用

• 继承可提供数据类型扩展

• 继承支持多态现象

• 继承是面向对象的编码的特有功能

■输入 [1]:

import torch

from torchvision import transforms

to_tensor = transforms.ToTensor()

from collections import namedtuple

import functools

import copy

import csv

from PIL import Image

from matplotlib import pyplot as plt

import numpy as np

import os

import datetime

import torch.optim as optim

在我们的示例中,所有原始样本都存储在文件夹中。此文件夹的地址在 raw_data_path 变量中声明。

■输入 [2]:

raw_data_path = ‘。/raw_data/data_images’

构建模块

数据集接口需要一些函数和类。数据集本身就是一个对象,因此我们将创建 MyDataset 类来包含所有重要函数和变量。

首先,我们需要读取标签文件,然后可对样本在其原始格式(此处为 PIL 图像)以及最终的张量格式应用某些变换。

我们需要使用以下函数来读取 1 次标签文件,然后创建包含所有样本名称和标签的元组。

内存中缓存可提升性能,但如果标签文件发生更改,请务必更新缓存内容。

■ 输入 [113]:

DataInfoTuple = namedtuple(‘Sample’,‘SampleName, SampleLabel’)

def myFunc(e):

return e.SampleLabel

# in memory caching decorator: ref https://dbader.org/blog/python-memoization

@functools.lru_cache(1)

def getSampleInfoList(raw_data_path):

sample_list = []

with open(str(raw_data_path) + ‘/labels.txt’, mode = ‘r’) as f:

reader = csv.reader(f, delimiter = ‘ ’)

for i, row in enumerate(reader):

imgname = row[0]

label = int(row[1])

sample_list.append(DataInfoTuple(imgname, label))

sample_list.sort(reverse=False, key=myFunc)

# print(“DataInfoTouple: samples list length = {}”.format(len(sample_list)))

return sample_list

如需直接变换 PIL 图像,那么以下类很实用。

该类仅含 1 种方法:resize。resize 方法能够改变 PIL 图像的原始大小,并对其进行重新采样。如需其它预处理(翻转、剪切、旋转等),需在此类种添加方法。

当 PIL 图像完成预处理后,即可将其转换为张量。此外还可对张量执行进一步的处理步骤。

在以下示例种,可以看到这两种变换:

■ 输入 [4]:

class PilTransform():

“”“generic transformation of a pil image”“”

def resize(self, img, **kwargs):

img = img.resize(( kwargs.get(‘width’), kwargs.get(‘height’)), resample=Image.NEAREST)

return img

# creation of the object pil_transform, having all powers inherited by the class PilTransform

pil_transform = PilTransform()

以下是类 PilTransform 的实操示例:

■ 输入 [5]:

path = raw_data_path + “/img_00000600.JPEG”

print(path)

im1 = Image.open(path, mode=‘r’)

plt.imshow(im1)

。/raw_data/data_images/img_00000600.JPEG

■ 输出 [5]:

■ 输入 [6]:

im2 = pil_transform.resize(im1, width=128, height=128)

# im2.show()

plt.imshow(im2)

■ 输出 [6]:

最后,我们定义一个类,用于实现与原始数据的交互。

类 MyDataset 主要提供了 2 个方法:

__len__ 可提供原始样本的数量。

__getitem__ 可使对象变为可迭代类型,并按张量格式返回请求的样本(已完成预处理)。

__getitem__ 步骤:

1) 打开来自文件的样本。

2) 按样本的原始格式对其进行预处理。

3) 将样本变换为张量。

4) 以张量格式对样本进行预处理。

此处添加的预处理仅作为示例。

此类可对张量进行归一化(求平均值和标准差),这有助于加速训练过程。

请注意,PIL 图像由范围 0-255 内的整数值组成,而张量则为范围 0-1 内的浮点数矩阵。

该类会返回包含两个元素的列表:在位置 [0] 返回张量,在位置 [1] 返回包含 SampleName 和 SampleLabel 的命名元组。

■ 输入 [109]:

class MyDataset():

“”“Interface class to raw data, providing the total number of samples in the dataset and a preprocessed item”“”

def __init__(self,

isValSet_bool = None,

raw_data_path = ‘。/’,

SampleInfoList = DataInfoTuple,norm = False,

resize = False,

newsize = (32, 32)

):

self.raw_data_path = raw_data_path

self.SampleInfoList = copy.copy(getSampleInfoList(self.raw_data_path))

self.isValSet_bool = isValSet_bool

self.norm = norm

self.resize = resize

self.newsize = newsize

def __str__(self):

return ‘Path of raw data is ’ + self.raw_data_path + ‘/’ + ‘’

def __len__(self):

return len(self.SampleInfoList)

def __getitem__(self, ndx):

SampleInfoList_tup = self.SampleInfoList[ndx]

filepath = self.raw_data_path + ‘/’ + str(SampleInfoList_tup.SampleName)

if os.path.exists(filepath):

img = Image.open(filepath)

# PIL image preprocess (examples)

#resize

if self.resize:

width, height = img.size

if (width 》= height) & (self.newsize[0] 》= self.newsize[1]):

img = pil_transform.resize(img, width=self.newsize[0], height=self.newsize[1])

elif (width 》= height) & (self.newsize[0] 《 self.newsize[1]):

img = pil_transform.resize(img, width=self.newsize[1], height=self.newsize[0])

elif (width 《 height) & (self.newsize[0] 《= self.newsize[1]):

img = pil_transform.resize(img, width=self.newsize[0], height=self.newsize[1])

elif (width 《 height) & (self.newsize[0] 》 self.newsize[1]):

img = pil_transform.resize(img, width=self.newsize[1], height=self.newsize[0])

else:

print(“ERROR”)

# from pil image to tensor

img_t = to_tensor(img)

# tensor preprocess (examples)

#rotation

ratio = img_t.shape[1]/img_t.shape[2]

if ratio 》 1:

img_t = torch.rot90(img_t, 1, [1, 2])

#normalization requires the knowledge of all tensors

if self.norm:

img_t = normalize(img_t)

#return img_t, SampleInfoList_tup

return img_t, SampleInfoList_tup.SampleLabel

else:

print(‘[WARNING] file {} does not exist’.format(str(SampleInfoList_tup.SampleName)))

return None

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 机器学习
    +关注

    关注

    67

    文章

    8570

    浏览量

    137421
  • python
    +关注

    关注

    59

    文章

    4892

    浏览量

    90417
  • pytorch
    +关注

    关注

    2

    文章

    813

    浏览量

    14953
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    AI Ceph 分布式存储教程资料大模型学习资料2026

    在人工智能的浪潮中,算力、算法与数据被誉为三驾马车。然而,随着大模型(LLM)参数量突破万亿级别,数据规模膨胀至 PB 乃至 EB 级别,传统的存储架构已难以支撑这场算力竞赛的“粮草”需求
    发表于 05-01 17:35

    Python AI 数字化实战:从 Pandas 自动化到 DeepSeek “星逻系统”开发,无密

    技术优化的角度,快速上手必须学会“数据类型降级”。例如,将Int64降为Int32,或将Object类型(底层是昂贵的Python字符串对象指针)转化为Categorical(分类类型)。在底层
    发表于 04-30 13:43

    Python全栈一课通(470)(12.96 GB)-网盘资源下载

    只懂单一节点的“螺丝钉”,往往是最先被优化、被降薪的群体。(看讠果aixuetang。xyz) 如果将《470吃透 Python 全栈:Web 开发、接口、爬虫、自动化全包含》置于经济学的显微镜下,它
    发表于 04-19 16:30

    [VirtualLab] 使用Python进行跨平台参数扫描

    摘要 VirtualLab Fusion允许外部访问其建模技术、求解器和结果。这有助于应用其他数据处理或优化工具来进一步研究光学模拟。在本示例中,我们演示如何使用Python脚本运行参数扫描,以及
    发表于 03-31 09:36

    PyTorch 中RuntimeError分析

    ? 错误原因 这个 RuntimeError 是因为在 PyTorch 中,upsample_nearest2d_out_frame(最近邻2D上采样)操作尚未对 BFloat16 数据类型提供
    发表于 03-06 06:02

    1688 商品详情 API 调用与数据解析 Python 实战

    你想要的是 1688 商品详情 API 的 Python 调用与数据解析实战方案,核心是完成 API 凭证配置、接口请求(含签名)、响应数据解析、异常处理 的全流程落地,我会提供可直接
    的头像 发表于 02-10 11:23 507次阅读

    Pytorch 与 Visionfive2 兼容吗?

    Pytorch 与 Visionfive2 兼容吗? $ pip3 install torch torchvision torchaudio --index-url https
    发表于 02-06 08:28

    如何使用Python读取不间断数据,并将其传输到LabVIEW进行处理?

    使用Python读取Count,如何将读取到的数据传输至Labview;传输过程中Python要保持读取的动作,不能停止。
    发表于 01-23 11:09

    C语言和C++之间的区别是什么

    区别 1面向对象编程 (OOP): C语言是一种面向过程的语言,它强调的是通过函数将任务分解为一系列步骤进行执行。 C++在C语言的基础上扩展了
    发表于 12-11 06:23

    PYQT 应用程序框架及开发工具

    大家好,本团队此次分享的内容为开发过程中使用到的PYQT 应用程序框架及开发工具。 pYqt 是一个多平台的 python 图形用户界面应用程序框架,由于其面向对象、 易扩展(可实现组件编程等
    发表于 10-29 07:15

    基于蜂鸟E203架构的指令K扩展

    扩展指令架构(RISC-V ISA)的K扩展。 K扩展是一种可选的指令扩展,它增加了一些向量和矩阵操作的指令。这些指令可以利用硬件并行性,高效地处理大量
    发表于 10-21 09:38

    云训练平台数据过大无法下载数据至本地怎么解决?

    起因是现在平台限制了图片数量,想要本地训练下载数据时发现只会跳出网络异常的错误,请问这有什么解决办法?
    发表于 07-22 06:03

    使用AICube导入数据点创建后提示数据不合法怎么处理

    重现步骤 data目录下 labels.txt只有英文 **错误日志** 但是使用示例的数据可以完成训练并部署
    发表于 06-24 06:07

    数据下载失败的原因?

    数据下载失败什么原因太大了吗,小的可以下载,想把大的下载去本地训练报错网络错误 大的数据多大?数据量有多少?
    发表于 06-18 07:04

    跟老齐学Python:从入门到精通

    本帖最后由 yuu_cool 于 2025-6-3 16:52 编辑 本资料是面向编程零基础读者的Python 入门教程,内容涵盖了Python 的基础知识和初步应用。以比较轻快的风格,向零基
    发表于 06-03 16:10