《PyTorch深度学习实践》学习笔记(2)

一 数据集的加载

前文主要是自定义的小批量数据集,这里主要介绍加载外部开源的数据集方法

数据集加载常用的工具:
    1)Dataset:主要用于构造数据集,该数据集应该能够支持索引结构;
    2)DataLoader:主要用于加载数据集,支持训练时的Mini-Batch(分批进行训练)形式。

1.1 Dataset的构造

import torch
from torch.utils.data import Dataset
from torch.utils.data import DataLoader

//准备数据,自定义数据集类,用以继承Dataset抽象类
//在torch.utils.data中有Dataset抽象类,我们需要根据自己的需要继承这个抽象类,来实现自己的数据集类
class DiabetesDataset(Dataset):
    def __init__(self):          #init:对数据集类进行初始化    
        pass 
    def __getitem__(self, item): #该方法的实现是为了实例化后的数据集对象支持下标操作dataset[index]
        pass
    def __len__(self):           #该方法的实现是为了方便我们输出数据集每一个batch的数据项条目数
        
        pass      
dataset = DiabetesDataset()#实例化这个数据集类
数据集的数据加载方式(init和getitem的实现)
1)若数据集本身规模不是很大,可以直接将原数据集全部加载到内存中,则getitem方法只需要从内存中顺序读出即可;
2)若数据集本身规模较大,则可以将数据在磁盘中按照文件夹分装,将输入出的各个文件夹名以列表的形式载入内存中;则getitem的方法就是按照文件夹路径从磁盘中索引并读出文件。

1.2 DataLoader的构造

train_loader = DataLoader(dataset=dataset,batch_size=32,shuffle=True,num_workers=2)
'''
dataset:数据集对象
batch_size:批量训练的大小
shuffle:是否要进行随机打乱
num_workers:使用多少个线程对数据进行载入操作;使用并行化可以提高数据读取的效率
'''
1)首先DataLoader类需要传入一个支持索引操作的数据集兑现Dataset
2)对原始数据集中的各个数据项进行随机打乱操作(Shuffle)
3)使用Loader工具,按照给定的Batch-Size大小将原始的数据集划分成以Batch-Size为基本大小的,Batch为基本单位的数据单元

1.3 具体实例的实现

import numpy as np
import torch
from torch.utils.data import Dataset,DataLoader
import matplotlib.pyplot as plt

#准备数据,自定义数据集类,用以继承Dataset抽象类
class DiabetesDataset(Dataset):
    def __init__(self):
        #xy = np.loadtxt(filepath,delimiter=' ',dtype = np.float32)
        self.x_data = torch.from_numpy(np.loadtxt('diabetes_data.csv.gz',delimiter=' ',dtype=np.float32))
        self.y_data = torch.from_numpy(np.loadtxt('diabetes_target.csv.gz',dtype=np.float32))
        self.len = self.y_data.shape[0]
    def __getitem__(self, index):
        #该方法的实现是为了实例化后的数据集对象支持下标操作
        return self.x_data[index],self.y_data[index]
    def __len__(self):
        #该方法的实现是为了方便我们输出数据集每一个batch的数据项条目数
        return self.len

# x_data = torch.from_numpy(np.loadtxt('diabetes_data.csv.gz',delimiter=' ',dtype=np.float32))
# y_data = torch.from_numpy(np.loadtxt('diabetes_target.csv.gz',dtype=np.float32))
dataset = DiabetesDataset()#实例化这个数据集类
train_loader = DataLoader(dataset=dataset,batch_size=32,shuffle=True)
'''
dataset:数据集对象
batch_size:批量训练的大小
shuffle:是否要进行随机打乱
num_workers:使用多少个线程对数据进行载入操作;使用并行化可以提高数据读取的效率
'''

#自定义多层模型
class Model(torch.nn.Module):
    def __init__(self):
        super(Model,self).__init__()
        self.linear1 = torch.nn.Linear(10,8)
        self.linear2 = torch.nn.Linear(8,6)
        self.linear3 = torch.nn.Linear(6,4)
        self.linear4 = torch.nn.Linear(4,1)
        self.sigmoid = torch.nn.Sigmoid() #增加非线性映射

    def forward(self,x):
        #在多隐层的网络中书写前向计算的逻辑时,只用一个变量x串联整个输入输出
        #这是一种习惯
        x = self.sigmoid(self.linear1(x))
        x = self.sigmoid(self.linear2(x))
        x = self.sigmoid(self.linear3(x))
        x = self.sigmoid(self.linear4(x))
        return x

model = Model()

#构建损失函数的计算和优化器
criterion = torch.nn.BCELoss(size_average = True)#逻辑回归模型适用二分类交叉熵损失函数
op = torch.optim.SGD(model.parameters(),lr = 0.01)

epochs = []
costs = []
#训练过程,包括前向计算和反向传播
for epoch in range(100):
    epochs.append(epoch)
    loss_sum = 0.0
    for i,data in enumerate(train_loader,0):
        inputs,labels = data
        #从train_loader中取出数据data
        #从数据data中提取属性x和标签y
        #并且自动转换成tensor张量传给inputs和data两个变量

        y_pred = model(inputs)
        loss = criterion(y_pred,labels)
        loss_sum += loss.item()
        print(epoch,i,loss.item())

        op.zero_grad()
        loss.backward()

        op.step()
    costs.append(loss_sum/(i+1))
    
# 训练过程可视化
plt.ylabel('Cost')
plt.xlabel('Epoch')
plt.plot(epochs, costs)
plt.show()

猜你喜欢

转载自blog.csdn.net/t28383993/article/details/122687107