目录
1. 准备数据
首先,还是先定义我们的数据集,这里我们定义20个样本
然后真实值y近似等于 1 + 2x + x^2 ,为了不是完全符合多项式,添加了一些随机噪声
2. 随机初始化参数
因为我们打算建立一个y = a + bx + cx^2 的多项式模型去预测,所以我们需要三个参数,因为平方项乘积已经很大了,为了防止梯度爆炸,这里学习率先设置小一点
3. 训练数据
训练的过程较为简单,还是遵循几个步骤
- 前向传播,网络模型的预测值
- 定义损失函数
- 反向传播
- 梯度下降
- 梯度清零
- 然后一直重复前面的步骤
4. 可视化
最后一步打印学习到的参数
然后将样本点和预测曲线绘制出来就行了
5. code
import torch
import matplotlib.pyplot as plt
import numpy as np
def train_data(batch_size = 20): # 定义数据集
x = torch.rand(batch_size) * 10
y = x**2 + 2*x + 1 + torch.randn(batch_size) # 随机噪声
return x,y # y = 1 + 2x + x^2 近似
x_data, y_data = train_data() # 取出数据
a = torch.randn(1,requires_grad=True)
b = torch.randn(1,requires_grad=True)
c = torch.randn(1,requires_grad=True)
lr = 0.0001 # 学习率
for epoch in range(1000):
for x,y in zip(x_data,y_data):
y_pred = a + b * x + c * x * x # y = a + bx + cx^2 去预测
loss = (y-y_pred).pow(2) # 损失函数
loss.backward() # 反向传播
a.data -= a.grad.data * lr # 更新参数
b.data -= b.grad.data * lr
c.data -= c.grad.data * lr
a.grad.data.zero_() # 梯度清零
b.grad.data.zero_()
c.grad.data.zero_()
if epoch % 100 ==0:
print(epoch, loss.item())
print(a.data, b.data, c.data) # 打印网络学习到的参数
with torch.no_grad(): # 不需要计算梯度
x = np.linspace(0, 11, 30)
y = a.data + b.data * x + c.data * x * x
plt.scatter(x_data, y_data)
plt.plot(x, y)
plt.show()
样本点和我们预测的多项式曲线基本拟合
损失值