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

审核编辑:郭婷

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

    关注

    66

    文章

    8116

    浏览量

    130546
  • python
    +关注

    关注

    51

    文章

    4674

    浏览量

    83459
  • pytorch
    +关注

    关注

    2

    文章

    760

    浏览量

    12825
收藏 人收藏

    评论

    相关推荐

    如何利用Python和pandas来处理json数据

    了如何利用Python和pandas(Python的第三方库)来处理json数据,主要内容包含: json
    的头像 发表于 11-01 10:59 630次阅读
    如何<b class='flag-5'>利用</b><b class='flag-5'>Python</b>和pandas来<b class='flag-5'>处理</b>json<b class='flag-5'>数据</b>

    PyTorch 与 TensorFlow的区别分析

    PyTorch是一个开源的深度学习框架,建立于Torch之上,底层为C++,并标榜Python First,强调其为Python 语言量身打造的,使用上就与Python项目的撰写并没有
    发表于 10-27 10:41 733次阅读
    <b class='flag-5'>PyTorch</b> 与 TensorFlow的区别分析

    Python编程实用指南

    Python 是一种解释型、面向对象、动态数据类型的高级程序设计语言。通过 Python 编程,我们能够解决现实生活中的很多任务。本书是一本
    发表于 09-27 06:21

    pytorch模型转换需要注意的事项有哪些?

    什么是JIT(torch.jit)? 答:JIT(Just-In-Time)是一组编译工具,用于弥合PyTorch研究与生产之间的差距。它允许创建可以在不依赖Python解释器的情况下运行的模型
    发表于 09-18 08:05

    Python面向对象编程详解

    一般编程可分为面向过程编程,和面向对象编程。Python面向对象编程,与Java的
    发表于 09-04 16:35 268次阅读
    <b class='flag-5'>Python</b>的<b class='flag-5'>面向</b><b class='flag-5'>对象</b>编程详解

    什么是面向对象编程(OOP)?面向对象的程序设计

    在编程领域,面向对象编程 (OOP) 是一种强大的范例,使开发人员能够构建复杂且可扩展的应用程序。
    的头像 发表于 07-19 14:57 786次阅读

    没有“中间商赚差价”, OpenVINO™ 直接支持 PyTorch 模型对象

    体验—— OpenVINO 的 mo 工具可以直接将 PyTorch 模型对象转化为 OpenVINO 的模型对象,开发者可以不需要将 ONNX 模型作为中间过渡。
    的头像 发表于 06-27 16:39 419次阅读
    没有“中间商赚差价”, OpenVINO™ 直接支持 <b class='flag-5'>PyTorch</b> 模型<b class='flag-5'>对象</b>

    使用Teachable Machine和Python轻松进行对象检测

    电子发烧友网站提供《使用Teachable Machine和Python轻松进行对象检测.zip》资料免费下载
    发表于 06-27 09:26 0次下载
    使用Teachable Machine和<b class='flag-5'>Python</b>轻松进行<b class='flag-5'>对象</b>检测

    Pytorch模型转换为DeepViewRT模型时出错怎么解决?

    我最终可以在 i.MX 8M Plus 处理器上部署 .rtm 模型。 我遵循了 本指南,我将 Pytorch 模型转换为 ONNX 模型,然后按照指南中的描述,我尝试将 ONNX 模型转换为量化
    发表于 06-09 06:42

    PyTorch教程3.2之面向对象的设计实现

    电子发烧友网站提供《PyTorch教程3.2之面向对象的设计实现.pdf》资料免费下载
    发表于 06-05 15:48 0次下载
    <b class='flag-5'>PyTorch</b>教程3.2之<b class='flag-5'>面向</b><b class='flag-5'>对象</b>的设计实现

    PyTorch教程-3.2. 面向对象的设计实现

    3.2. 面向对象的设计实现¶ Colab [火炬]在 Colab 中打开笔记本 Colab [mxnet] Open the notebook in Colab Colab [jax
    的头像 发表于 06-05 15:38 273次阅读
    <b class='flag-5'>PyTorch</b>教程-3.2. <b class='flag-5'>面向</b><b class='flag-5'>对象</b>的设计实现

    PyTorch教程14.6之对象检测数据

    电子发烧友网站提供《PyTorch教程14.6之对象检测数据集.pdf》资料免费下载
    发表于 06-05 11:23 0次下载
    <b class='flag-5'>PyTorch</b>教程14.6之<b class='flag-5'>对象</b>检测<b class='flag-5'>数据</b>集

    PyTorch教程之数据处理

    电子发烧友网站提供《PyTorch教程之数据处理.pdf》资料免费下载
    发表于 06-02 14:11 0次下载
    <b class='flag-5'>PyTorch</b>教程之<b class='flag-5'>数据</b>预<b class='flag-5'>处理</b>

    Python面向对象深化(下)

    __call__  方法和可调用对象 凡是可以将 () 直接应用到自身并执行, 都称为可调用对象. 注意: 可调用对象包括自定义的函数、Python 内置函数、以及本节所讲的实例
    的头像 发表于 05-11 17:52 468次阅读

    Python面向对象深化(上)

    前言 哈喽, 大家好, 我是了不起! 欢迎大家来观看了不起的冒险之旅. 为了方便起见, 文中以小知为名. 讲述了不起在Python异世界的冒险之旅. 天空之城是座高耸云端的城堡. 位于西海岸附近
    的头像 发表于 05-11 17:51 402次阅读
    <b class='flag-5'>Python</b><b class='flag-5'>面向</b><b class='flag-5'>对象</b>深化(上)