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 "
©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页