八、加载数据集

一、通过维度变化

        梯度下降:采用全部样本

        随机梯度下降:

二、Mini-Batch

        1)DataSet 是抽象类,不能实例化对象,主要是用于构造我们的数据集

        2)DataLoader 需要获取DataSet提供的索引[i]和len;用来帮助我们加载数

        3)对应参数:

epoch:对全部训练样本实现一次前馈和反馈

Batch-Size:一次前馈和反馈包含的训练样本数量

Iterations: Batch分成了多少份,内部循环的次数

三、DataLoader : Batch-Size = 2 ,shuffle = True(随机打乱)

3.1 步骤

        1)需要提供样本数量和样本长度

        2)随机打乱顺序

        3)样本分组形成迭代Loader

四、数据集划分

x_train,x_test,y_train,y_test=sklearn.model_selection.train_test_split(x_data,y_target,test_size=0.4, random_state=0, stratify=y_train)

        1)x_data :所要划分的样本特征数据集()数据集

        2)y_data :所要划分的样本标签

        3)test_size :测试集样本占比

        4)random_state:随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。控制随机状态,固定random_state后,每次构建的模型是相同的、生成的数据集是相同的、每次的拆分结果也是相同的。

        5)stratify是为了保持split前类的分布:

比如有100个数据,80个属于A类,20个属于B类。如果train_test_split(… test_size=0.25, stratify = y_all), 那么split之后数据如下:

training: 75个数据,其中60个属于A类,15个属于B类。

testing: 25个数据,其中20个属于A类,5个属于B类。

用了stratify参数,training集和testing集的类的比例是 A:B= 4:1,等同于split前的比例(80:20)。通常在这种类分布不平衡的情况下会用到stratify。

将stratify=X就是按照X中的比例分配

将stratify=y就是按照y中的比例分配

五、代码实现

代码说明:

        1)需要mini_batch 就需要import DataSet和DataLoader

        2)继承DataSet的类需要重写init,getitem,len魔法函数。分别是为了加载数据集,获取数据索引,获取数据总量。

        3)DataLoader对数据集先打乱(shuffle),然后划分成mini_batch。

        4)len函数的返回值 除以 batch_size 的结果就是每一轮epoch中需要迭代的次数。

        5)inputs, labels = data中的inputs的shape是[32,8],labels 的shape是[32,1]。也就是说mini_batch在这个地方体现的

#dataset and dataloader
import numpy as np
import torch
from torch.utils.data import Dataset  #数据工具,为抽象类不可实例化只可用子类继承
from torch.utils.data import DataLoader  #可用来加载数据,可实例化
import matplotlib.pyplot as plt
import os
os.environ['KMP_DUPLICATE_LIB_OK']='True'

#___________________________________Prepare dataset___________________________________#
'''
Dataset是一个抽象函数,不能直接实例化,所以我们要创建一个自己类,继承Dataset
继承Dataset后我们必须实现三个函数:
__init__()是初始化函数,之后我们可以提供数据集路径进行数据的加载
__getitem__()帮助我们通过索引找到某个样本
__len__()帮助我们返回数据集大小
'''

class DiabetesDataset(Dataset):  #继承Dataset
    def __init__(self,filepath):  #输入文件地址
        xy = np.loadtxt(filepath,delimiter = ',',dtype = np.float32) #下载文件,分割,读取32浮点数
        self.len = xy.shape[0]  #取xyshape[0] 数据集为N*9 取第0元素得到数据集的个数N
        #shape本身是一个二元组(x,y)对应数据集的行数和列数,这里[0]我们取行数,即样本数
        self.x_data = torch.from_numpy(xy[:, :-1])
        self.y_data = torch.from_numpy(xy[:, [-1]])
    def __getitem__(self, index):  #支持下标索引
        return self.x_data[index], self.y_data[index]
    def __len__(self):  #获取数据集  
        return self.len
loss_list = []
dataset = DiabetesDataset('D:\\anaconda3\\Lib\\site-packages\\sklearn\\datasets\\data\\diabetes.csv.gz')
train_loader = DataLoader(dataset = dataset, #传递数据集
                          batch_size =32, 
                          shuffle = True, 
                          num_workers = 0) #读取mini-batch进行的线程提高读取效率
#___________________________________Design model using class___________________________________#
class Model(torch.nn.Module):
    def __init__(self):
        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)  #输入维度为8  输出维度为1

       # self.linear4 = torch.nn.Linear(2,1)
        
        self.sigmoid = torch.nn.Sigmoid() #添加激活函数模块作为计算模块,添加非线性变换
#添加激活函数模块作为网络的一层,计算模块,添加非线性变换,无参数无需训练
#可采用多种激活函数,最常用ReLU,但是采用ReLU的过程中需要考虑,当x<0,ln(ReLU(x))错误
#可以改为:
        self.activate = torch.nn.ReLU()
    #def forward (self,x):
        #x = self.activate(self.linear1(x))   
        #x = self.activate(self.linear2(x))
        #x = self.activate(self.linear3(x))
        #x = self.activate(self.linear4(x))
        
    def forward (self,x):
        x = self.activate(self.linear1(x))   #调用非线性函数做变换
        x = self.activate(self.linear2(x))
        x = self.sigmoid(self.linear3(x))
       
        return x
model = Model()
#___________________________________construct loss and optimizer___________________________________#
criterion = torch.nn.BCELoss(reduction='sum')  
optimizer = torch.optim.Adam(model.parameters(),lr = 0.05)   
#___________________________________Training cycle___________________________________#


#if __name__ == '__main__':
for epoch in range(100):
    for i, (inputs,labels) in enumerate (train_loader ,0):  #遍历索引并得到索引值


        y_pred = model(inputs)
        loss = criterion(y_pred, labels)
        print(epoch , i,loss.item())
            #backward
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        loss_list.append(loss.item())

plt.plot(range(100*(dataset.__len__()//32+1)), loss_list)
plt.ylabel('loss')
plt.xlabel('epoch')
plt.show()

六、拓展

        with torch.no_gard()和requires_gard

requires_gardtensor有该参数,可设置为True,在进行反向传播的过程中,该tensor会自动求导。设置为False节省时间

        with torch.no_gard():在该模块下计算的tensor.requires_gard =False

将数据集分为训练集和测试集,采用Mini-Batch,并对测试集的准确率进行评估

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
import matplotlib.pyplot as plt
import os
os.environ['KMP_DUPLICATE_LIB_OK']='True'

xy_data = np.loadtxt('D:\\anaconda3\\Lib\\site-packages\\sklearn\\datasets\\data\\diabetes.csv.gz',delimiter = ',',dtype = np.float32)
x = xy_data[:, :-1]
y = xy_data[:,[-1]]
x_train ,x_test,y_train,y_test = train_test_split(x,y,test_size = 0.3)
x_test = torch.from_numpy(x_test)
y_test = torch.from_numpy(y_test)

#nimi_batch
class DiabetesDataset(Dataset):
    def __init__(self, data,label):
        self.x_data = torch.from_numpy(data)
        self.y_data = torch.from_numpy(label)
        self.len = data.shape[0]
    def __getitem__(self,index):
        return self.x_data[index] ,self.y_data[index]
    def __len__(self):
        return self.len
#实例化对象
train_dataset = DiabetesDataset(x_train,y_train)
train_loader = DataLoader(dataset=train_dataset, batch_size=32, shuffle=True, num_workers=0)
#数据batch
class Model(torch.nn.Module):
    def __init__(self):
        super(Model,self).__init__()
        self.linear1 = torch.nn.Linear(8,6)
        self.linear2 = torch.nn.Linear(6,4)
        self.linear3 = torch.nn.Linear(4,2)
        self.linear4 = torch.nn.Linear(2,1)
        
        self.activate = torch.nn.ReLU()
        self.sigmoid = 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))
        x = self.sigmoid(self.linear4(x))
        return x
model =Model()

#优化器和损失函数
criterion = torch.nn.BCELoss(reduction = 'sum')
optimizer = torch.optim.SGD(model.parameters(),lr =0.01)

loss_list = []
acc_list = []
count =0
for epoch in range(5000):
    for i,data in enumerate(train_loader,0):
        inputs ,labels =data
        y_preds =model(inputs)
        loss = criterion(y_preds, labels)
        print('Epoch = ',epoch,'i = ',i)
        print('\t',loss.item())
            #backward
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        loss_list.append(loss.item())
    if epoch%200 == 0:
        with torch.no_grad():
            count +=1
            y_pred = model(x_test)
            y_pred_label = torch.where(y_pred>=0.5,torch.tensor([1.0]),torch.tensor([0.0]))
            acc = torch.eq(y_pred_label, y_test).sum().item() / Ytest.size(0)
            acc_list.append(acc)
            print("\t test acc : ", acc)


plt.plot(range(5000*(train_dataset.__len__()//32+1)), loss_list)
plt.ylabel('loss')
plt.xlabel('epoch')
plt.show() 

plt.plot(range(count), acc_list)
plt.ylabel('Acc')
plt.xlabel('epoch')
plt.show() 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_43952858

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值