目录
1 Mini-Batch基本知识
在先前我们学习的内容中,一种情况是采用Full-Batch来训练数据;还有一种情况是在随机梯度下降中,只随机取其中一个数据来计算梯度。其中随机梯度下降可以很好的解决训练数据时遇到的鞍点问题,但是会导致训练时间过长。所以,接下来我们要学习的是采用Mini-Batch的方法来训练数据,这种方法的优点是可以均衡性能和训练时间上的需求。
采用Mini-Batch的方法来训练数据时,需要使用Dataset和DataLoader两个工具类:
- Dataset:用来构造数据集,使数据集可以通过索引快速取出
- DataLoader:取出一个Mini-Batch,一组数据
采用Mini-Batch训练数据需要掌握的三个概念:
- Epoch:1次epoch表示把所有的训练样本都进行了一次前馈和反馈的训练;
- Batch-Size:表示一次前馈和反馈所使用的样本数量;
- Iteration:将样本一共分成了几个Mini-Batch。
例:10000个样本,其中Batch-size=1000,则Iteration=10000/1000=10。
2 DataLoader的工作原理:
使用DataLoader时需要两个基本参数:
- shuffle :是否打乱数据顺序
- batch-size:每个Mini-Batch需要的数据量
如图所示,是 batch-size=2,shuffle=true 时的运行原理,首先将dataset中的数据打乱,而后进行分组,分成一个一个的Mini-batch。
3 具体代码实例
案例依然按照上一章所讲的糖尿病数据集,具体获取数据集方法见以下链接:Pytorch深度学习——处理多维度特征的输入(B站刘二大人P7学习笔记)_Learning_AI的博客-CSDN博客
采用Mini-Batch训练数据的全部代码以及注释如下:
import numpy as np
import torch
from torch.utils.data import Dataset, DataLoader
# 自定义一个类并继承自Dataset类,此类用来封装数据
class DiabetesDataset(Dataset):
def __init__(self, filepath):
xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32)
# xy是一个N行9列的矩阵,所以xy.shape拿到的就是(N,9)这样一个元组,取索引0位的数字就可以得到数据的条数。
self.len = xy.shape[0]
self.x_data = torch.from_numpy(xy[:, :-1])
self.y_data = torch.from_numpy(xy[:, [-1]])
# getitem函数,可以使用索引拿到数据
def __getitem__(self, index):
return self.x_data[index], self.y_data[index]
# 返回数据的条数/长度
def __len__(self):
return self.len
# 实例化自定义类,并传入数据地址
dataset = DiabetesDataset('diabetes.csv.gz')
# num_workers是否要进行多线程服务,num_worker=2 就是2个进程并行运行
train_loader = DataLoader(dataset=dataset,
batch_size=32,
shuffle=True,
num_workers=2)
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)
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
model = Model()
criterion = torch.nn.BCELoss(reduction='mean')
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# 防止报错
if __name__=='__main__':
# 采用Mini-Batch的方法训练要采用多层嵌套循环
# 所有数据都跑100遍
for epoch in range(100):
# enumerate可以获得当前是第几次迭代,内部迭代每一次跑一个Mini-Batch
for i, data in enumerate(train_loader, 0):
# data从train_loader中取出数据(取出的是一个元组数据)
# inputs获取到data中的x的值,labels获取到data中的y值
inputs, labels = data
y_pred = model(inputs)
loss = criterion(y_pred, labels)
print(epoch, i, loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
运行结果部分截图如下:
第8节作业如下链接:Pytorch深度学习——Kaggle网站中泰坦尼克号作业(B站刘二大人P8作业)_Learning_AI的博客-CSDN博客