训练一个简单的线性回归模型

训练一个简单的线性回归模型,在代码实现上分成了几个部分,构建数据集,构建数据加载器,假设函数,损失函数,优化方法。对一个模型来说,损失值越小,模型就越好,也就是说训练模型的过程其实就是不断改变模型本身而减少损失值的过程,这里我们使用梯度下降法使得损失值减少

我们使用sklearn中的函数make_regression()生成回归数据 来构建一个数据集 

from sklearn.datasets import make_regression
X, y, coef = make_regression(n_samples=200, n_features=1, n_informative=1, n_targets=1,
                       bias = 0, effective_rank=None, noise = 20,
                        tail_strength=0,random_state=0, coef = True)

属性默认值说明
n_samplesint, optional (default=100)样本数量
n_featuresint, optional (default=100)特征数量
n_informativeint, optional (default=10)对回归有效的特征数量
n_targetsint, optional (default=1)y的维度
biasfloat, optional (default=0.0)底层线性模型中的偏差项。相当于y的中位数
effective_rankint or None, optional (default=None)有效等级
noisefloat, optional (default=0.0)设置高斯噪声的标准偏差加到数据上。
shuffleboolean, optional (default=True)是否洗牌
coefboolean, optional (default=False)如果为真,则返回权重值
random_stateint,设置随机种子

 使用matplotlib来绘图:

scatter函数绘制散点图

  plot函数绘制折线图

import torch
from sklearn.datasets import make_regression
import matplotlib.pyplot as plt
import random


# 构建数据集
def create_data():
    x, y, coef = make_regression(n_samples=100, n_features=1, noise=20, coef=True, bias=14.5, random_state=0)
    x = torch.tensor(x)
    y = torch.tensor(y)
    return x, y, coef


# 构建数据加载器
def data_loader(x, y, size):
    data_len = len(y)
    data_index = list(range(data_len))
    random.shuffle(data_index)  # 打乱顺序
    num = data_len // size

    for idx in range(num):
        start = idx * size
        end = start + size
        train_x = x[start:end]
        train_y = y[start:end]
        yield train_x, train_y  # yield会保存循环中的值到集合里然后循环结束后一起返回


w = torch.tensor(0.1, requires_grad=True, dtype=torch.float64)
b = torch.tensor(0.0, requires_grad=True, dtype=torch.float64)


# 假设函数
def linear_regression(x):
    return w * x + b


# 损失函数 模型越好损失越小
def loss_function(y_suppose, y_true):
    return (y_suppose - y_true) ** 2


# 优化方法
def sgd(lr=0.01):
    # 除以16是因为使用的是批次样本的平均梯度值(size是16)
    w.data = w.data - lr * w.grad.data / 16
    b.data = b.data - lr * b.grad.data / 16


# 训练函数
def train():
    x, y, coef = create_data()  # 加载数据集
    epochs = 100  # 定义训练参数次数
    learning_rate = 0.01  # 学习率

    for _ in range(epochs):
        for x_train, y_train in data_loader(x, y, size=16):
            y_suppose = linear_regression(x_train)  # 将样本送入模型进行训练
            loss = loss_function(y_suppose, y_train.reshape(-1, 1)).sum()  # 计算平方损失值

            if w.grad is not None:  # 梯度清0
                w.grad.data.zero_()
            if b.grad is not None:  # 梯度清0
                b.grad.data.zero_()

            loss.backward()  # 将loss进行自动微分是因为训练模型其实就是使得损失函数降低的过程

            sgd(learning_rate)
    # 绘图
    plt.scatter(x, y)
    x = torch.linspace(x.min(), x.max(), 1000)
    y1 = torch.tensor([w * v + 14.5 for v in x])
    y2 = torch.tensor([w * v + b for v in x])

    plt.plot(x, y1, label='真实')
    plt.plot(x, y2, label='训练')
    plt.grid()
    plt.show()


if __name__ == '__main__':
    train()

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值