深度学习-线性回归

import torch  # 深度学习框架
import matplotlib.pyplot as plt  # 画图的
import random  # 随机


# 一.生成数据
# 1.创建数据集
# 此函数接收w,b,data_num三个参数,其中w为权重值,b为偏置值,data_num为数据数量
def create_data(w, b, data_num):  # 生成数据
    x = torch.normal(0, 1, (data_num, len(w)))
    # 生成形状为(data_num,len(w))的张量,此张量代表了data_num个样本,每个样本有len(w)个特征,
    # 且其中每个元素都服从标准正太分布(均值为0,标准差为1)
    y = torch.matmul(x, w) + b  # matmul表示矩阵相乘,y=wx+b
    noise = torch.normal(0, 0.01, y.shape)  # 生成噪声(需要加到y上)
    y += noise
    return x, y


# 2.传入真实值(权重,偏置与数据量),生成数据并且绘制散点图
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[:, 3], Y, 1)  # 绘制散点图,选择X的第4列(索引为3)作为x轴,Y作为y轴,1为点面积大小
plt.show()  # 显示散点图


# 3.获取小批量数据
# 此函数接收data,label,batchsize三个参数,其中data为输入的数据,label为数据对应的标签,batchsize为一个批次的数据量
def data_provider(data, label, batchsize):  # 每次访问这个函数就能提供一批数据
    length = len(label)  # 获取标签总量(数据总量)
    indices = list(range(length))
    # 创建从0到length-1的整数列表,其中每个元素代表相应样本的索引
    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  # yield相当于有存档点的return,下次调用时从中断的地方继续


batchsize = 16  # 确定一个批次的数据量


# 二.定义基本函数

# 接收输入的x,权重w与偏置b,计算并返回预测的y值
def fun(x, w, b):
    pred_y = torch.matmul(x, w) + b
    return pred_y


# 损失函数,衡量模型的准确性,接收预测的y值与真实的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 = para - para.grad*lr,会创建新的张量对象
            para.grad.zero_()  # 使用过的梯度,归零,避免梯度累积


lr = 0.01  # 定义学习率
w_0 = torch.normal(0, 0.01, true_w.shape, requires_grad=True)
# 从均值为0,标准差为0.01的正太分布中随机初始化权重,并保证w_0与true_w形状相同,且需要计算梯度
b_0 = torch.tensor(0.01, requires_grad=True)  # 初始化偏置值,同样需要计算梯度
print(w_0, b_0)  # 打印初始化的w_0,b_0的值,以便于检查

# 三.训练模型
epochs = 50  # 训练轮数
for epoch in range(epochs):
    data_loss = 0  # 初始化每个epoch的总损失
    for batch_x, batch_y in data_provider(X, Y, batchsize):
        # 每次迭代生成小批量数据
        pred_y = fun(batch_x, w_0, b_0)  # 调用fun函数,计算y的预测值
        loss = maeloss(pred_y, batch_y)  # 调用maeloss函数,计算平均绝对误差(损失)
        loss.backward()  # 反向传播
        sgd([w_0, b_0], lr)  # 更新模型参数w_0与b_0
        data_loss += loss  # 将当前批次的损失累加到data_loss中

    print("epoch %03d: loss:%.6f" % (epoch, data_loss))  # 打印每个批次的损失值

print("真实的函数值是", true_w, true_b)
print("训练得到的参数值是", w_0, b_0)

# 四.线性回归可视化分析  想画出来的是x和通过对x预测出来的一条线是一个二维图
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].detach().numpy(), Y, 1)
plt.show()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值