【神经网络学习日记(5)】数据加载器(DataLoader)的调用

本文是笔者进行神经网络学习的个人学习日记

图片和链接均源自网络,侵删

1 torch的调用

在深度学习中,数据的量级通常是十分庞大的,一般情况下,我们无法将所有数据同时加载到内存中。因此,在训练模型之前,我们会对数据集进行分批——既是分训练集与测试集,也是分批载入。

为了实现上述功能,我们使用torch库中的Dataset类和DataLoader类来实现数据的加载和存储。同时,我们也需要一些其他的辅助方法来将数据读取,分批和储存,所有需要使用的库如下:

import os

import numpy as np
import pandas as pd
import torch
from sklearn.model_selection import train_test_split
from torch.utils.data import DataLoader
from torch.utils.data import Dataset

其中,os库以及numpy和pandas库主要用于数据的读取,处理和储存,在我的实例中,我会先将数据储存在DataFrame中方便读取和修改。而sklearn库在这里主要用于分训练集和测试集,其train_test_split方法可以方便将数据集分开。

下面我们先来定义我们用来储存数据的MyDataset类。

2 MyDataset类的定义

这是我们自行定义的类,它继承于torch库的Dataset类,在定义时需要注意:除了__init__方法外,还需要重写 __len____getitem__类,用于获取数据长度以及输入输出。我们来看一看MyDataset类的实现代码(我在这里顺便进行了数据的归一化和分类操作,也可以不进行):

class MyDataset(Dataset):
    def __init__(self, path, iCols, oCols, normalize, coding='utf-8', is_train=True):
        """
        Dataset类,读取数据并归一化后分成训练集和测试集
        :param str path: 文件路径
        :param list[str] iCols: 输入列名
        :param list[str] oCols: 输出列名
        :param Any normalize: 归一化方法(StandardScale)
        :param str coding: 文件编码方式
        :param bool is_train: 用于分训练集和测试集
        """
        self.path = path
        self.iCols = iCols
        self.oCols = oCols
        self.normalize = normalize
		
        # 数据读取,由于我的数据存在不同文件中,故读取一个文件夹中的所有文件
        fileNames = os.listdir(self.path)
        dfs = [pd.read_csv(os.path.join(self.path, fileName), names=[iCols + oCols], encoding=coding) for fileName in fileNames]
        allDf = pd.concat(dfs, ignore_index=True)  # 将不同文件中的数据整合
        
        # 归一化
        allDf[:] = self.normalize.fit_transform(allDf[:])
        
        # 分类
        x, y = allDf[iCols], allDf[oCols]
        x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=22)
        
        # 将输入(data)和输出(labels)转化格式并储存
        self.data = torch.Tensor(np.array(x_train if is_train else x_test))
        self.labels = torch.Tensor(np.array(y_train if is_train else y_test))
        
    def __len__(self):
        return len(self.labels)

    def __getitem__(self, idx):
        """
        获取输入和输出
        :param int idx: 索引值
        :return: tuple[tensor[float], tensor[float]]
        """
        return self.data[idx], self.labels[idx]

我将数据进行了归一化,按照8:2的比例分成了训练集和测试集(random_state的作用类似随机种子,固定后每次随机都相同),并将输入和输出分到了datalabels两个Tensor变量中,方便__getitem__方法对他们进行调用。其他的,代码中注释都讲的比较清楚了,就不再赘述。

数据储存的容器有了,那么下面就要对数据进行加载。

3 myDataLoader方法的定义

数据加载器的调用其实非常简单,就一个函数DataLoader就可以解决了。之所以定义一个自己的方法,主要是为了装逼主要是为了把MyDataset的定义和DataLoader方法的调用放在一个函数里,方便后续调用。话不多说了,直接上代码。

def myDataLoader(path, batch_size, iCols, oCols, normalize, coding='utf-8'):
    """
    将Dataset数据和参数储存到DataLoader中,返回DataLoader和各项参数
    :param str path: 文件路径
    :param int batch_size: 批量归一数
    :param list[str] iCols: 输入列名
    :param list[str] oCols: 输出列名
    :param Any normalize: 归一化方法
    :param str coding: 文件编码方式
    :return: tuple[DataLoader, DataLoader, list[float], list[float], int]
    """
    # 实例化MyDataset
    train_dataset = MyDataset(path, iCols, oCols, normalize, coding, True)
    test_dataset = MyDataset(path, iCols, oCols, normalize, coding, False)

    # 创建DataLoader
    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
    test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

    return train_loader, test_loader

batch_size是批量归一数,可以理解为一次加载的数据数量,一般为2的次方(64,128等)。在定义完MyDataset类之后,直接用DataLoader将整个数据集加载到加载器中。shuffle可以通俗理解为将数据打乱,在训练时有一定程度上强化训练效果的作用,但是测试集中显然用不到。

以上就是全部数据加载器的使用了,至于如何使用这个数据加载器,可以看我的另一篇博客:神经网络学习日记(二)——全连接神经网络及Pytorch代码实现

个人神经网络学习日记:
【神经网络学习日记(1)】神经网络基本概念
【神经网络学习日记(2)】全连接神经网络(FCNN)及Pytorch代码实现
【神经网络学习日记(3)】卷积神经网络(CNN)
【神经网络学习日记(4)】循环神经网络(RNN、LSTM、BiLSTM、GRU)
【神经网络学习日记(5)】数据加载器(DataLoader)的调用
【神经网络学习日记(6)】Transformer结构详解
【神经网络学习日记(7)】Transformer的应用(BERT、Longformer、LLM)
【神经网络学习日记(8)】一些图神经网络的简单介绍(GCN、GAT、rGCN)

文中引用部分都尽可能写出了,如果有侵犯其他人文章版权的问题,请务必联系我,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值