赞
踩
一、通过维度变化
梯度下降:采用全部样本
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_gard:tensor有该参数,可设置为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()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。