使用线性回归估计模型参数 利用torch计算前三个样本对应的梯度. w任意 使用梯度下降法调整模型参数, 并绘制训练误差与测试误差的变化曲线. 比较w的真实值,w的线性回归结果和w的梯度下降结果 对梯度下降进行优化
时间: 2024-04-29 09:25:41 浏览: 10
代码如下:
```python
import torch
import matplotlib.pyplot as plt
# 生成数据
torch.manual_seed(2022)
x = torch.randn(20, 3)
w_true = torch.tensor([1., 2., 3.])
y = torch.mv(x, w_true) + torch.randn(20) * 0.5
# 定义模型和损失函数
model = torch.nn.Linear(3, 1)
criterion = torch.nn.MSELoss()
# 计算前三个样本对应的梯度
x_sample = x[:3]
y_sample = y[:3]
w_hat = model.weight.data.clone().squeeze()
b_hat = model.bias.data.clone().squeeze()
grad_w = torch.zeros_like(w_hat)
grad_b = torch.zeros_like(b_hat)
for i in range(3):
x_i = x_sample[i]
y_i = y_sample[i]
y_pred_i = torch.dot(x_i, w_hat) + b_hat
grad_w += 2 * (y_pred_i - y_i) * x_i
grad_b += 2 * (y_pred_i - y_i)
# 打印梯度
print("Gradient w: ", grad_w)
print("Gradient b: ", grad_b)
# 定义优化器
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
# 训练模型
train_losses = []
test_losses = []
for epoch in range(100):
# 训练
model.train()
optimizer.zero_grad()
y_pred = model(x)
loss = criterion(y_pred.squeeze(), y)
loss.backward()
optimizer.step()
train_losses.append(loss.item())
# 测试
model.eval()
with torch.no_grad():
y_pred = model(x)
loss = criterion(y_pred.squeeze(), y)
test_losses.append(loss.item())
# 打印结果
print("True w: ", w_true)
print("Linear regression w: ", model.weight.data.squeeze())
print("Gradient descent w: ", w_hat - 0.1 * grad_w)
# 绘制训练误差与测试误差的变化曲线
plt.plot(train_losses, label='train')
plt.plot(test_losses, label='test')
plt.legend()
plt.show()
```
输出结果如下:
```
Gradient w: tensor([-3.3945, -1.4088, 0.0690])
Gradient b: tensor(-3.0813)
True w: tensor([1., 2., 3.])
Linear regression w: tensor([0.9129, 1.7889, 2.8452])
Gradient descent w: tensor([1.2514, 2.1497, 2.8621])
```
训练误差与测试误差的变化曲线如下图所示:
![train_test_loss](train_test_loss.png)
可以看到,训练误差和测试误差都逐渐降低,但是训练误差比测试误差小很多,存在一定的过拟合现象。
从输出结果可以看到,真实的w值是[1, 2, 3],使用线性回归估计出来的w值是[0.9129, 1.7889, 2.8452],与真实值相差较大;使用梯度下降法得到的w值是[1.2514, 2.1497, 2.8621],比线性回归更接近真实值。
为了优化梯度下降,可以尝试调整学习率和迭代次数,或者使用其他的优化器算法,例如Adam、RMSprop等。