EP8 加载数据集

1、Dataset        

1.1 定义好这个项目的x和y是什么

官方文档:

class Dataset(object):
    """An abstract class representing a Dataset.
    All other datasets should subclass it. All subclasses should override
    ``__len__``, that provides the size of the dataset, and ``__getitem__``,
    supporting integer indexing in range from 0 to len(self) exclusive.
    """
 
    def __getitem__(self, index):
        raise NotImplementedError
 
    def __len__(self):
        raise NotImplementedError
 
    def __add__(self, other):
        return ConcatDataset([self, other])

__getitem__就是获取样本对,模型直接通过这一函数获得一对样本对{x:y}

__len__是指数据集长度。

(46条消息) Pytorch中的dataset类——创建适应任意模型的数据集接口_木盏的博客-CSDN博客

(46条消息) PyTorch 入门实战(三)——Dataset和DataLoader_一株草的世界的博客-CSDN博客

import torch
import torch.utils.data.dataset as Dataset
import numpy as np

#创建子类
class subDataset(Dataset.Dataset):#因为Dataset是module模块,不是class类,所以需要调用module里的class才行,因此是Dataset.Dataset!
    #初始化,定义数据内容和标签
    def __init__(self, Data, Label):
        self.Data = Data
        self.Label = Label
    #返回数据集大小
    def __len__(self):
        return len(self.Data)
    #得到数据内容和标签,作用是接收一个索引, 返回一个样本
    def __getitem__(self, index):
        data = torch.Tensor(self.Data[index])
        label = torch.Tensor(self.Label[index])
        return data, label

抽象类不能实例化,因此我们需要构造这个抽象类的子类来创建数据集

补充:python中的类与模块

类:一种抽象的概念,将数据和操作进行封装,以便将来的复用;

模块:一个python文件就可以认为是一个模块,模块名就是去掉.py后缀

1.2 if __name__ == '__main__':的作用

__name__:当该模块被直接执行的时候,__name__ 等于文件名(包含后缀 .py );如果该模块 import 到其他模块中,则该模块的 __name__ 等于模块名称(不包含后缀.py)。

“__main__” 始终指当前执行模块的名称(包含后缀.py)。进而当模块被直接执行,__name__ == 'main' 结果为真,继续执行后面的代码。

(46条消息) Python中if __name__ == ‘__main__‘:的作用和原理_if name =main python_农村詹姆斯的博客-CSDN博客

2、Dataloader

数据集(dataset) + 采样器(sampler),并在数据集上提供单线程或多线程(num_workers )的可迭代对象

参数意义:

1. epoch:所有的训练样本输入到模型中称为一个epoch; 
 2. iteration:一批样本输入到模型中,成为一个Iteration;
 3. batchszie:批大小,决定一个epoch有多少个Iteration;
 4. 迭代次数(iteration)=样本总数(epoch)/批尺寸(batchszie)
 5. dataset (Dataset) – 决定数据从哪读取或者从何读取;
 6. batch_size (python:int, optional) – 批尺寸(每次训练样本个数,默认为1)
 7. shuffle (bool, optional) –每一个 epoch是否为乱序 (default: False);
 8. num_workers (python:int, optional) – 是否多进程读取数据(默认为0);
 9. drop_last (bool, optional) – 当样本数不能被batchsize整除时,最后一批数据是否舍弃(default: False)
 10. pin_memory(bool, optional) - 如果为True会将数据放置到GPU上去(默认为false) 

  • Epoch: 所有训练样本都已输入到模型中,称为一个Epoch
  • Iteration: 一批样本输入到模型中,称为一个Iteration
  • Batchsize: 一批样本的大小, 决定一个Epoch有多少个Iteration

循环嵌套

 for epoch in range(100):#100次训练

        for i in range(total_batch):#每一次iteration,就是从DataLoader中获取一个batch_size大小的数据的。

(46条消息) PyTorch学习笔记(4)--DataLoader的使用_我这一次的博客-CSDN博客

  1. 读哪些数据? 我们每一次迭代要去读取一个batch_size大小的样本,那么读哪些样本呢?
  2. 从哪读数据? 也就是在硬盘当中该怎么去找数据,在哪设置这个参数。
  3. 怎么读数据?

 3、代码

import torch
import numpy as np
from sklearn.model_selection import train_test_split#分割数据集
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt




# prepare dataset


class DiabetesDataset(Dataset):#定义子类,为后续实例化做准备
    def __init__(self, filepath):#从哪读
        xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32)
        self.len = xy.shape[0]  # shape(多少行,多少列);shape[0]可以得到有多少个样本
        self.x_data = torch.from_numpy(xy[:, :-1])#除了最后一列
        self.y_data = torch.from_numpy(xy[:, [-1]])#只要最后一列


    def __getitem__(self, index):#给一个索引,返回一个样本(x,y)
        return self.x_data[index], self.y_data[index]

    def __len__(self):
        return self.len

# 读取数据集,读什么
dataset = DiabetesDataset('diabetes.csv')#子类实例化,传入的参数

# 构建读取器,如何读
train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=0)  # train_loader迭代器,num_workers 多线程 怎么读
# print(len(dataset))#759

# design model using class


class Model(torch.nn.Module):#继承torch.nn.Module
    def __init__(self):#这个方法会在创建类的实例的时候自动执行
        super(Model, self).__init__()#子类把父类的__init__()放到自己的__init__()当中,这样子类就有了父类的__init__()的那些东西
        self.linear1 = torch.nn.Linear(8, 6)
        self.linear2 = torch.nn.Linear(6, 4)
        self.linear3 = torch.nn.Linear(4, 1)
        self.sigmoid = torch.nn.Sigmoid()

    def forward(self, x):
        x = self.sigmoid(self.linear1(x))
        x = self.sigmoid(self.linear2(x))
        x = self.sigmoid(self.linear3(x))
        return x

epoch_list = []
loss_avg_list = []
loss_list = []
model = Model()

# construct loss and optimizer
criterion_each = torch.nn.BCELoss(reduction='mean')
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)

# training cycle forward, backward, update
if __name__ == '__main__':
    for epoch in range(100):
        for i, data in enumerate(train_loader, 0):  # train_loader 是迭代器,从0开始,先shuffle后mini_batch i=759/32=23 enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标
            inputs, labels = data
            y_pred = model(inputs)
            loss_each = torch.mean(criterion_each(y_pred, labels))
            #print(epoch, i, data, loss_each.item())


            optimizer.zero_grad()
            loss_each.backward()

            optimizer.step()
        loss = torch.mean(loss_each)  # 每个样本的损失
        loss_list.append(loss.item())  # 整个batch的平均损失

        epoch_list.append(epoch)
# print(len(loss_list))
# print(len(epoch_list))
plt.figure(1)
plt.plot(epoch_list, loss_list)
plt.ylabel('loss')
plt.xlabel('epoch')
plt.show()

3.1 lr=0.01, batch=32

排查问题:

lossfunction 一直震荡,先降低学习率

lr=0.001

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值