手动构建线性回归(代码+注释)

手动构建线性回归(代码+注释)

"""
torch:PyTorch 库,用于构建和训练模型。
make_regression:Scikit-learn 中的函数,用于生成回归问题的数据集。
math:Python 数学库,用于数学计算(如向上取整)。
"""
import torch
from sklearn.datasets import make_regression
import math

# 生成数据集
def data_sets():
    # 研究下这个API
    x,y,ceof = make_regression(n_samples=150, n_features=4, bias=3,noise=80, random_state=42,shuffle=True,coef=True)
    print(x.shape,y.shape,ceof)
    return x,y,ceof
"""
make_regression:生成一个回归问题的数据集。
n_samples=150:生成 150 个样本。
n_features=4:每个样本有 4 个特征。
bias=3:线性模型的偏置项为 3。
noise=80:添加噪声,噪声的标准差为 80。
random_state=42:随机种子,确保每次生成的数据相同。
shuffle=True:打乱数据顺序。
coef=True:返回生成数据时使用的真实系数。
# 返回:
x:特征矩阵,形状为 (150, 4)。
y:目标值,形状为 (150,)。
ceof:生成数据时使用的真实系数。
"""
# 定义线性回归模型
def model_regression(x,w,b):
    # print(w.shape,x.shape,(x*w).shape,b.shape)
    return x@w+b    
"""
这是一个简单的线性回归模型:
x:输入特征矩阵。
w:权重参数。
b:偏置参数。
@:矩阵乘法运算符,计算 x 和 w 的点积,然后加上偏置 b。
"""
# 初始化模型参数
def init_w_b(x):
    w = torch.rand(x.shape[1],requires_grad=True,dtype=torch.float32)
    b = torch.rand(1, requires_grad=True,dtype=torch.float32)
    return w,b
"""
初始化权重 w 和偏置 b:
w:形状为 (n_features,),随机初始化。
b:形状为 (1,),随机初始化。
requires_grad=True:表示这些参数需要计算梯度。
dtype=torch.float32:指定数据类型为 32 位浮点数。
"""
# 定义损失函数
def mse(y,y_pred):
    return torch.mean((y-y_pred)**2)
"""
计算均方误差(MSE):
y:真实目标值。
y_pred:模型预测值。
torch.mean:计算平均值。
"""
# 更新模型参数
def step(w,b,lr=0.01):
    w.data = w.data - lr*w.grad
    b.data = b.data - lr*b.grad
"""
使用梯度下降法更新参数:
w.data 和 b.data:直接修改参数的值。
lr:学习率,控制更新步长。
w.grad 和 b.grad:参数的梯度。
"""
# 梯度清零
def my_zero_grad(w,b):
    if w.grad is not None:
        w.grad.zero_()
    if b.grad is not None:
        b.grad.zero_()
"""
在每次反向传播前,将参数的梯度清零,避免梯度累积。
"""
# 模型训练
def train():
    # 加载数据并转换为 PyTorch 张量
    x,y,ceof = data_sets()
    x = torch.tensor(x,dtype=torch.float32)
    y = torch.tensor(y,dtype=torch.float32)

    # 初始化模型参数
    w,b = init_w_b(x)
    print(w.requires_grad,b.requires_grad)

    # 设置训练参数
    # 学习率
    lr = 0.001
    # 训练轮数
    epochs = 100
    # 小批量
    batch_size = 16
    for epoch in range(epochs):
        e=[] # 用于存储每批数据的损失
        for i in range(math.ceil(x.shape[0]/batch_size)):
        	# 获取小批量数据
            x_batch=x[batch_size*i:batch_size*(i+1)]
            y_batch=y[batch_size*i:batch_size*(i+1)]
            # 预测
            y_pred=model_regression(x_batch,w,b)
            # 16条数据的均方误查(计算损失)
            loss=mse(y_batch,y_pred)
            e.append(loss)
            # 梯度清零
            my_zero_grad(w,b)
            # 反向传播(求梯度)
            loss.backward()
            # 更新参数
            step(w,b,lr)
            # 计算平均损失
        mse_loss=torch.tensor(e).mean()
        print(f"{epoch}/{epochs},当前loss:{mse_loss},grad_w:{w.grad},grad_b:{b.grad}")
    pass
train()
"""
!!!!!!循环训练的详细步骤解释!!!!!!
1、外层循环:训练轮数
-for epoch in range(epochs):遍历每一轮训练。
2、内层循环:小批量训练
-for i in range(math.ceil(x.shape[0] / batch_size)):将数据分成小批量进行训练。
-math.ceil(x.shape[0] / batch_size):计算需要多少个小批量。
-x_batch 和 y_batch:获取当前小批量的特征和目标值。
3、预测
-y_pred = model_regression(x_batch, w, b):使用当前参数 w 和 b 对 x_batch 进行预测。
4、计算损失
-loss = mse(y_batch, y_pred):计算预测值 y_pred 和真实值 y_batch 之间的均方误差(MSE)。
-e.append(loss):将当前批次的损失值存储到列表 e 中。
5、梯度清零
-my_zero_grad(w, b):在每次反向传播前,将 w 和 b 的梯度清零,避免梯度累积。
6、反向传播
-loss.backward():计算损失函数对 w 和 b 的梯度。
7、更新参数
-step(w, b, lr):使用梯度下降法更新 w 和 b 的值。
8、计算平均损失
-mse_loss = torch.tensor(e).mean():计算当前轮次所有小批量的平均损失。
-print(f"{epoch}/{epochs}, 当前 loss: {mse_loss}, grad_w: {w.grad}, grad_b: {b.grad}"):打印当前轮次的损失和梯度。
"""

详细步骤:

  • 导入库
  • 生成数据集
  • 定义线性回归模型
  • 初始化模型参数
  • 定义损失函数
  • 定义参数更新函数
  • 定义梯度清零函数
  • 训练模型(包括加载数据、初始化参数、设置训练参数、训练循环)
  • 运行训练
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值