pytorch08_加载数据集

引入:

前面学过的batch(全部样本,计算速度快,性能上可能有问题)和随机梯度下降(解决按点问题,随机性好,但没法利用gpu/cpu,训练时间长),由此mini-batch

如下图,在外层循环中,每一层是一个epoch(训练周期,即这一批要训练几次);在内层循环中,每一次是一个mini-batch(batch的迭代)

#training cycle
for epoch in range (trsining-batch):
    #mini-batch    
    for i in range(total-batch)

相关概念:

Epotch:即所有样本都参与了训练,有前馈和反向传播。

batch-size:每次训练所用的样本数量/批量大小。。

iteration:内层执行了几次,就是分为几个mini-batch

eg.10000个Epotch,mini-batch为1000,每次拿1000个样本来训练,即batch-size为1000,则iteration=10。

DataLoader

这里batch-size为2,shuffle=True,[这里shuffle是把它打乱顺序,增加随机性]

功能:1.支持索引; 2.知道dataset的长度。从而对自动生成小批量数据集。

shuffle打乱顺序 ——> batch_size=2,两个为一组 ——>从而形成可迭代Loader

 定义数据集:

1.如果数据本身不大且结构化,可以直接All Data [i]

2.如果 数据很大(eg图像、语音等非结构化),通过文件。


 具体代码:

import torch
import numpy as np
from torch.utils.data import Dataset    #抽象类,只能由子类来继承
from torch.utils.data import DataLoader #可实例化

filepath  = 'C:\\Users\\jiwenting\\Desktop\\diabetes.csv'
class DiabetsDataset(Dataset):  #自定义类
    #魔法
    def __init__(self,filepath):
            xy = np.loadtxt(filepath,delimiter=',',dtype=np.float32)
            self.len = xy.shape[0]  #用shape[0]输出列的长度,即N
            self.x_data = torch.from_numpy(xy[:,:-1])   #x_data为前八列
            self.y_data = torch.from_numpy(xy[:,[-1]])  #y_data为最后一列
    def __getitem__(self, index) :    #通过索引调出数据
            return self.x_data[index],self.y_data[index]
    def __len__(self):
            return self.len

dataset = DiabetsDataset(filepath)  #通过自定义类实例化
#传入定义的数据集,然后输入 batch-size 和 shuffle 来进行loader; 而num-wokers表示几个并行的进程来读取数据
train_loader = DataLoader(dataset=dataset,batch_size=32,shuffle=True,num_workers=0)   

#model
class Model(torch.nn.Module):
    def __init__(self) -> None:
        super(Model,self).__init__()
        self.linear1 = torch.nn.Linear(8,6)#构造对象,八维到六维
        self.linear2 = torch.nn.Linear(6,4)
        self.linear3 = torch.nn.Linear(4,1)
        self.activate = torch.nn.Sigmoid()
    def forward(self,x):
        x = self.activate(self.linear1(x))
        x = self.activate(self.linear2(x))
        x = self.activate(self.linear3(x))
        return x
model = Model()
#loss & optimizer
criterion = torch.nn.BCELoss(reduction='mean')
optimzer = torch.optim.SGD(model.parameters(),lr=0.01)


#training circle
if __name__ == '__main__':
    for epoch in range(100):
        '''
        用enumerate获得当前为第几次迭代,0为起始位置 :直接对train_loader做迭代 
        从train_loader拿出Dataset自己实现的__getitem__的返回值即(x,y)元组放入data中 

        在这里loader自动的把xy构成的矩阵转化为Tensor类型的计算图,所以直接传进去就好了
        '''
        for i,(input,labels) in enumerate(train_loader,0):  
            #forward
            y_pred = model(input)
            loss = criterion(y_pred,labels)
            print(epoch,i,loss.item())  

            optimzer.zero_grad()
            loss.backward()
            optimzer.step()   

遇到的问题:

1.Dataset 是一个抽象类,无法实例化。

定义抽象类时用到了魔法方法

在Python中,所有以双下划线__包起来的方法,统称为Magic Method(魔术方法),它是一种的特殊方法,普通方法需要调用,而魔术方法不需要调用就可以自动执行。

2.关于enumerate

4.关于shape        推荐博客https://blog.csdn.net/likeyou1314918273/article/details/89510234

直接用.shape可以快速读取矩阵的形状,使用shape[0]读取矩阵第一维度的长度

5.关于划分训练集和测试集:

推荐博客:https://zhuanlan.zhihu.com/p/248634166


import torch
import numpy as np
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
from sklearn.model_selection import train_test_split
 
 
# 读取原始数据,并划分训练集和测试集
raw_data = np.loadtxt('diabetes.csv', delimiter=',', dtype=np.float32)
X = raw_data[:, :-1]
y = raw_data[:, [-1]]
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3)
Xtest = torch.from_numpy(Xtest)
Ytest = torch.from_numpy(Ytest)

6.关于多线程num_workers=2

train_loader = DataLoader(dataset=dataset,batch_size=32,shuffle=True,num_workers=0)   

表示mini-batch的数据读取是否并行。

但注意如下图,在windows中直接调用loader迭代会报错。所以在调用loader迭代时必须要把它封装(比如封装到if语句或者函数)

 

·

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值