提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
一、线性回归的完整训练流程
包括数据生成、批量数据加载、模型定义、损失计算、梯度更新,以及最后的训练结果可视化。以下是详细的解释:
二、步骤
1.数据生成
代码如下(示例):
def create_data(w,b,data_num):
x=torch.normal(0,1,(data_num,len(w))) # 随机生成特征 x,服从标准正态分布
y=torch.matmul(x,w)+b # 按线性关系生成目标值 y
noise=torch.normal(0,0.01,y.shape) # 添加噪声,模拟真实数据的不确定性
y+=noise # 将噪声加到目标值上
return x,y
num=500 true_w=torch.tensor([8.1,2,2,4]) #权重 true_b=torch.tensor(1.1) #偏置值
- 生成特征:
x是一个服从正态分布的二维张量,行数为样本数量,列数为特征数量(由w的长度决定)。 - 生成目标值:通过公式 y=xw+by = xw + by=xw+b 计算真实值。
- 添加噪声:为目标值加入小幅随机噪声,增加数据的随机性。
2.数据加载器
代码如下(示例):
def data_provider(data,label,batchsize):
length=len(label)
indices=list(range(length)) # 生成样本索引
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 # 使用生成器逐批返回数据
功能
- 数据分批:将完整的数据集分成小批量(
batchsize),用于梯度下降训练。 - 随机性:每次迭代随机打乱数据,减少过拟合风险。
- 生成器:用
yield按需返回小批量数据,节省内存。
3.线性模型 (fun) 和 损失函数 (maeloss)
def fun(x, w, b):
pred_y = torch.matmul(x, w) + b # 模型预测公式:y = xw + b
return pred_y
def maeloss(pre_y, y):
return torch.sum(abs(pre_y - y)) / len(y) # 平均绝对误差(MAE)
功能
fun:定义线性回归模型。maeloss:计算预测值和真实值的平均绝对误差(MAE),衡量模型性能。
4.随机梯度下降 (sgd)
def sgd(paras, lr):
with torch.no_grad(): # 禁用梯度计算,避免影响训练过程
for para in paras:
para -= para.grad * lr # 使用学习率 lr 更新参数
para.grad.zero_() # 清除梯度,避免累积
功能
- 实现随机梯度下降(SGD)算法。
- 按梯度值和学习率更新模型参数。
5.模型训练
lr=0.03 #learning rate
w_0 = torch.normal(0, 0.01, true_w.shape, requires_grad=True) # 初始化权重
b_0 = torch.tensor(0.01, requires_grad=True) # 初始化偏置
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))
训练过程
- 初始化参数:权重
w_0和偏置b_0,用小值随机初始化。 - 多轮训练:
- 对每个批次数据:
- 计算预测值和损失。
- 反向传播计算梯度。
- 使用 SGD 更新参数。
- 累加每轮的总损失,监控训练进展。
- 对每个批次数据:
6.参数对比
print("真实的函数值是", true_w, true_b)
print("训练的函数值是", w_0, b_0)
比较训练得到的参数(w_0, b_0)与真实值(true_w, true_b),评估模型拟合的准确性。
7.可视化结果
idx = 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_0[idx]和b_0,绘制第idx个特征的拟合直线。
- 使用训练得到的模型参数
- 数据点:
- 将真实数据点绘制在图上,比较拟合效果。
import torch
import matplotlib.pyplot as plt
import random
def create_data(w,b,data_num):
x=torch.normal(0,1,(data_num,len(w)))
y=torch.matmul(x,w)+b
noise=torch.normal(0,0.01,y.shape)
y+=noise
return x,y
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)
# plt.scatter(x[:,2],y,1)
# plt.show()
def data_provider(data,label,batchsize):
length=len(label)
indices=list(range(length))
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
batchsize =16
# for batch_x,batch_y in data_provider(x,y,batchsize):
# print(batch_x,batch_y)
# # break
def fun(x , w , b):
pred_y=torch.matmul(x,w)+b
return pred_y
def maeloss(pre_y,y):
return torch.sum(abs(pre_y-y))/len(y)
def sgd(paras,lr):
with torch.no_grad():
for para in paras:
para-=para.grad*lr
para.grad.zero_()
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)
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))
print("真实的函数值是",true_w,true_b)
print("训练的函数值是",w_0,b_0)
idx = 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()
总结
- 代码实现了完整的线性回归过程:
- 数据生成、加载、训练、评估和可视化。
- 训练目标:
- 拟合真实参数
true_w和true_b。
- 拟合真实参数
- 代码设计特点:
- 简单直观,手动实现各部分功能(如梯度下降和批量加载)。
- 可优化点:
- 增加学习率衰减机制,提高收敛速度。
- 使用
torch.utils.data.DataLoader简化数据加载过程。
94



被折叠的 条评论
为什么被折叠?



