李哥深度学习第二节 linear代码
·
这段代码实现了一个完整的线性回归模型,从数据生成、数据加载、模型定义、损失函数、优化器到训练和可视化。
我们使用随机梯度下降(SGD)优化器,通过最小化平均绝对误差(MAE)来学习线性模型的参数(权重和偏置)。
最终,我们比较了训练得到的参数和真实参数,并可视化了其中一个特征与标签的关系以及模型预测的直线。
1.导入必要的库
import torch
import matplotlib.pyplot as plt #画图的
import random #随机函数
2.定义生成数据的函数
def create_data(w, b, data_num): #生成数据
x = torch.normal(0, 1, (data_num, len(w)))
y = torch.matmul(x, w) + b #matmul表示矩阵相乘
noise = torch.normal(0, 0.01, y.shape)#噪声要加到y上
y +=noise
return x, y
3.设置参数并生成数据
num = 500
true_w = torch.tensor([8.1, 2, 2, 4])
true_b = torch.tensor(1.1)
X, Y = create_data(true_w, true_b, num)
4.绘制散点图
plt.scatter(X[:, 3], Y, 1)
plt.show()
5.定义数据提供器 data_provider
def data_provider(data, label, batchsize): #每次访问这个函数, 就能提供一批数据
length = len(label)
indices = list(range(length))
#range(length):生成一个从 0 到 length-1 的整数序列
#list():将 range 对象转换为 Python 列表
random.shuffle(indices)#我不能按顺序取 把数据打乱
for each in range(0, length, batchsize):
get_indices = indices[each: each+batchsize] # 获取一个批次的索引
get_data = data[get_indices] # 获取批次数据
get_label = label[get_indices] # 获取批次标签
yield get_data, get_label #有存档点的return, 以生成器的方式返回,避免一次性加载所有数据
6.设置批次大小并测试数据提供器
batchsize = 16
# for batch_x, batch_y in data_provider(X, Y, batchsize):
# print(batch_x, batch_y)
#
7.定义模型函数 fun
def fun(x, w, b):#这就是我们的线性模型:y = xw + b。
pred_y = torch.matmul(x, w) + b
return pred_y
8.定义损失函数 maeLoss
def maeLoss(pre_y, y):
return torch.sum(abs(pre_y - y))/len(y)
9.定义优化器 sgd(随机梯度下降)
def sgd(paras, lr):
with torch.no_grad():
for para in paras:
para -= para.grad * lr # 更新参数
para.grad.zero_() # 将梯度归零
10.设置学习率和初始化参数
lr = 0.03 # 学习率
w_0 = torch.normal(0, 0.01, true_w.shape, requires_grad= True) # 初始化权重,需要计算梯度
b_0 = torch.tensor(0.01, requires_grad=True) # 初始化偏置,需要计算梯度
print(w_0, b_0)
11.训练模型
epochs = 50
for epoch in range(epochs):
data_loss = 0
for batch_x, batch_y in data_provider(X, Y, batchsize):
pred_y = fun(batch_x, w_0, b_0) # 前向传播
loss = maeLoss(pred_y, batch_y) # 计算损失
loss.backward()# 反向传播,计算梯度
sgd([w_0, b_0], lr) # 更新参数
data_loss += loss # 累计损失
print("epoch %03d: loss: %.6f"%(epoch, data_loss))
12.打印训练得到的参数和真实参数
print("真实的函数值是", true_w, true_b)
print("训练得到的参数值是", w_0, b_0)
13.绘制训练结果
idx = 3 # 选择第3个特征进行绘制
plt.plot(X[:,idx].detach().numpy(),X[:,idx].detach().numpy()*w_0[idx].detach.numpy()+b_0.detach.numpy())
plt.scatter(X[:, idx],Y, 1)
plt.show()
真实参数(w_true, b_true)
↓
生成数据(X, Y) = X * w_true + b_true + 噪声
↓
分批加载 → (batch_X, batch_Y)
↓
模型预测 → pred_Y = batch_X * w_0 + b_0
↓
计算损失 → MAE(pred_Y, batch_Y)
↓
反向传播 → 计算梯度(grad_w, grad_b)
↓
参数更新 → w_0 = w_0 - lr * grad_w
b_0 = b_0 - lr * grad_b
更多推荐
所有评论(0)