4.5 PyTorch批量梯度下降
Posted 王小小小草
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4.5 PyTorch批量梯度下降相关的知识,希望对你有一定的参考价值。
欢迎订阅本专栏:《PyTorch深度学习实践》
订阅地址:https://blog.csdn.net/sinat_33761963/category_9720080.html
- 第二章:认识Tensor的类型、创建、存储、api等,打好Tensor的基础,是进行PyTorch深度学习实践的重中之重的基础。
- 第三章:学习PyTorch如何读入各种外部数据
- 第四章:利用PyTorch从头到尾创建、训练、评估一个模型,理解与熟悉PyTorch实现模型的每个步骤,用到的模块与方法。
- 第五章:学习如何利用PyTorch提供的3种方法去创建各种模型结构。
- 第六章:利用PyTorch实现简单与经典的模型全过程:简单二分类、手写字体识别、词向量的实现、自编码器实现。
- 第七章利用PyTorch实现复杂模型:翻译机(nlp领域)、生成对抗网络(GAN)、强化学习(RL)、风格迁移(cv领域)。
- 第八章:PyTorch的其他高级用法:模型在不同框架之间的迁移、可视化、多个GPU并行计算。
在实际应用中,数据集往往是非常大的,如果每次迭代都对所有样本进行前向-后向计算从而更新依次参数,就会非常慢,因此常用的方式是将总样本分割为多批样本,每计算一批样本就更新一次参数。PyTorch提供了每次产生一批数据的迭代器,提升了效率。
来看看具体做法,先创建一批数据x,y
import torch
# 创建了50个样本
x = torch.unsqueeze(torch.linspace(1,10,50), dim=1)
y = x.pow(2)
将数据转换为TensorDataset
dataset = Data.TensorDataset(x, y)
将TensorDataset转换成dataloader,设置参数batch_size,dataloader是一个迭代器,它会每次都吐出batch_size个样本
dataloader = Data.DataLoader(dataset=dataset, batch_size=10)
print(dataloader)
for inp, out in dataloader:
print(inp.shape)
print(out.shape)
print()
<torch.utils.data.dataloader.DataLoader object at 0x000001C262A235C0>
torch.Size([10, 1])
torch.Size([10, 1])
torch.Size([10, 1])
torch.Size([10, 1])
torch.Size([10, 1])
torch.Size([10, 1])
torch.Size([10, 1])
torch.Size([10, 1])
torch.Size([10, 1])
torch.Size([10, 1])
使用dataloader,以训练一个简单的线性模型为例,完整的代码如下:
import torch
import torch.nn as nn
import torch.utils.data as Data
class RegressionModel(nn.Module):
def __init__(self, n_input, n_hidden, n_output):
super(RegressionModel, self).__init__()
self.linear1 = nn.Linear(n_input, n_hidden)
self.relu = nn.ReLU()
self.linear2 = nn.Linear(n_hidden, n_output)
def forward(self, input):
hidden = self.linear1(input)
activate = self.relu(hidden)
output = self.linear2(activate)
return output
# # 数据
# 原始数据,x与y
x = torch.unsqueeze(torch.linspace(1,10,50), dim=1)
y = x.pow(2)
# 转换成TensorDataset
dataset = Data.TensorDataset(x, y)
# 转换成dataloader
dataloader = Data.DataLoader(dataset=dataset, batch_size=10)
# # 模型
# 模型结构
model = RegressionModel(1, 10, 1)
# 优化器
optim = torch.optim.SGD(model.parameters(), lr=0.0001)
# scheduler = torch.optim.lr_scheduler.StepLR(optim, 1000/)
# 损失
loss_f = nn.MSELoss(reduce=True)
# # 训练
for e in range(5000):
epoch_loss = 0
for i, (inp, out) in enumerate(dataloader):
optim.zero_grad()
predict = model(inp)
loss = loss_f(predict, out)
loss.backward()
optim.step()
epoch_loss += loss.data
# scheduler.step()
if e % 500 == 0:
print('the loss of %d batch is : %f' % (e, epoch_loss / (50/10)))
# # 保存与加载模型
# 方式1
model_path = 'data/regression_model.pkl'
torch.save(model, model_path)
reload_model = torch.load(model_path)
print(reload_model(torch.Tensor([2])))
# # 保存与加载模型
# 方式2
model_path2 = 'data/regression_model2.pkl'
torch.save(model.state_dict(), model_path2)
reload_model = RegressionModel(1,10,1)
reload_model.load_state_dict(torch.load(model_path2))
print(reload_model(torch.Tensor([2])))
C:\\Users\\CC\\Anaconda3\\lib\\site-packages\\torch\\nn\\functional.py:52: UserWarning: size_average and reduce args will be deprecated, please use reduction='elementwise_mean' instead.
warnings.warn(warning.format(ret))
the loss of 0 batch is : 2166.915283
the loss of 500 batch is : 32.224888
the loss of 1000 batch is : 8.669624
the loss of 1500 batch is : 4.125319
the loss of 2000 batch is : 2.358487
the loss of 2500 batch is : 1.470182
the loss of 3000 batch is : 1.147537
the loss of 3500 batch is : 0.912313
the loss of 4000 batch is : 0.862902
the loss of 4500 batch is : 0.790936
tensor([4.3891], grad_fn=<ThAddBackward>)
tensor([4.3891], grad_fn=<ThAddBackward>)
C:\\Users\\CC\\Anaconda3\\lib\\site-packages\\torch\\serialization.py:241: UserWarning: Couldn't retrieve source code for container of type RegressionModel. It won't be checked for correctness upon loading.
"type " + obj.__name__ + ". It won't be checked "
以上是关于4.5 PyTorch批量梯度下降的主要内容,如果未能解决你的问题,请参考以下文章
翻译: 3.2. 从零开始实现线性回归 深入神经网络 pytorch
谷歌机器学习速成课程---降低损失 (Reducing Loss):随机梯度下降法
随机梯度下降(Stochastic gradient descent)和 批量梯度下降(Batch gradient descent )的公式对比