深度学习项目---线性表示

Qwen3-32B-Chat 私有部署镜像 | RTX4090D 24G 显存 CUDA12.4 优化版

Qwen3-32B-Chat 私有部署镜像 | RTX4090D 24G 显存 CUDA12.4 优化版

Qwen
文本生成
Qwen3

本镜像基于 RTX 4090D 24GB 显存 + CUDA 12.4 + 驱动 550.90.07 深度优化,内置完整运行环境与 Qwen3-32B 模型依赖,开箱即用。


前言

深度学习项目之预测项目


一、导入库函数

import torch 
import matplotlib.pyplot as plt  # 画图的 深度学习和张量运算的强大工具

import random #生成随机数据

二、定义生成数据的函数

def create_data(w, b, data_num): #生成数据

定义一个函数名为:create_data的函数,其中:
w : 通常为权重(weigh)用于线性模型中的系数
b : 表示偏置(bias)用于线性模型中的截距。
data_num : 表示要生成的数据样本数量。

然后要书写函数内容如下:

def create_data(w, b, data_num):
	x = torch.normal(0, 1, (data_num, len(w)) #使用torch.normal从正态分布中生成一个数据
	y = torch.matmul(x, w) + b

	noise = torc.normal(0, 0.01, y.shape)
	y += noise

	return x, y

使用torch.normal从正态分布中生成一个数据
0:均值(mean)为0
1:标准差(std)为1

(data_num,lem(w)):生成的张量形状为:(data_num,lem(w));
即生成data_num行,每行有lem(w)个数值

torch.matmul(x,w):执行矩阵 乘法,将输入数据x与权重w相乘+b:加上偏置值b,

noise作用:生成一个噪声张量,用于模拟数据中的随机噪声。

0:均值为0
0.01:标准差为0.01

y.shape:噪声的形状与y相同,可以确保对每个输出值添加噪声

作用:将生成的噪声加到原本计算好的y上

意义:这样生成的y不是严格的线性结果,而是有一定的随机性,更符合数据中常见的噪声数据

三、生成模型数据

num = 500
true_w = torch.tensor([8.1, 2, 2, 4])
true_b = torch.tensor(1.1)

torch.tensor函数创建一个张量,内容为【8.1,2,2,4】用于数据生成或模型训练中作为参考值

torch.tensor函数创建一个标准张量数值为1.1,用于线性表示的截距,即当所有输入特征值为0时,输出截距

X, Y = create_data(true_w, true_b, num)

调用之前定义的creat_data函数,传入数据true_w, true_b, num
利用creat_data函数给定的权重和截距生成一组数据

x:生成输入的数据张量生成其形状为 (500, 4)(500 行,每行 4 个特征)。

y:根据线性关系y = x*ture_w+ture_b计算得到目标值,并加入少量噪声,使得数据更符合真实情况。

plt.scatter(X[:, 3], Y, 1)
plt.show()

使用 Matplotlib 的 scatter 函数绘制散点图。

x[:,3]:从输入数据x中取出所有样本的第四列(因为样本的列是从0开始的,所有x[:,3]表示所有样本的第四个特征

y:作为每个样本的特征值,作为图的纵坐标

四、定义数据提供器函数

def data_provider(data, label, batchsize):
# 每次访问这个函数,就能提供一批数据

函数名为data_provider;

data:表示输入的数据(例如特征矩阵)。

lable:对应的数据标签或目标值(例如回归或分类问题中的真实值)。

batchsize:每个批次的样本数量,也可表示为步长

length = len(label)

计算lable的长度得到样本总数

indices = list(range(length)) 
random.shuffle(indices)

通过length的长度生成一个0到length-1长度的线性表,并通过使用 random.shuffle 对索引列表 indices 进行原地随机打乱。

for each in range(0, length, batchsize):

从0到length遍历数据索引,以batchsize为步长

get_indices = indices[each:each+batchsize]

根据当前起始位置each,从打乱的indices列表中切片出当前批次的索引,范围为[each:each+batchsize]

 get_data = data[get_indices]
 get_label = lable[get_indices]

get_data = data[get_indices]:利用前面的获取的索引,从数据data中选取对应的样本

get_label = lable[get_indices]:从标签lable中选取对应的标签

yield get_data,get_label
batchsize = 16#步长为16

yield为有存档点的return,意味着函数在执行到 yield 时会保存当前状态,下一次迭代时从此处继续执行。

五、定义模型函数

def fun(x, w, b):
    pred_y = torch.matmul(x, w) + b
    return pred_y

定义一个函数名为fun的函数,传入数据张量x,以及权重w,再加上偏置值b

torch.matmul(x, w)表示对数据和权重进行矩阵乘法运算,再加上偏置值b,即为标准的y=x*w+b的线性运算

六、定义 MAE(平均绝对误差)损失函数

def meaLoss(pred_y, y):
    return torch.sum(abs(pred_y - y)) / len(y)

定义一个函数名为maeLoss的函数,用于计算模型损失

pre_y:为模型预测的输出

y:实际的标签和预测值

abs (pre_y - y):计算真实值与模拟值之间的绝对误差,绝对误差表示两个值之间的距离,没有正负区别

abs(pre_y - y) / len(y):将绝对误差除以样本数量,目的是为了对误差求平均,得到平均绝对误差(MAE)。

torch.sum(…):对所有经过除法处理后的误差求和,从而计算出总的平均绝对误差。

七、定义随机梯度下降(SGD)优化器函数

def sgrad(paras, lr): # 参数和学习率 随机梯度下降,更新参数
    with torch.no_grad(): #属于这句代码的部分,不计算梯度
        for para in paras:
            para -= para.grad * lr  # 不能写成 para = para - para.grad * lr
            para.grad.zero_() # 使用过的梯度 归0

参数paras:一个可迭代参数,包含了所有需要更新的参数

参数lr:学习率,用于控制更新步长

with torch.no_grad():开启一个上下文管理器告诉PyTorch代码块内不需要记录梯度信息,避免在更新参数时,影响自动求导机制,从而节省内存和计算开销

para -= para.grad * lr:对当前参数进行原地更新

    para.grad 是参数对应的梯度。用梯度乘以学习率得到参数更新后的步长

注:不能写成para = para - para.grad * lr因为这样创建一个新的参数para,导致原来的参数引用丢失,从而影响模型参数的更新。

zero():是Pytorch中的in-place操作,用于将梯度张量的所有元素置为 0。

八、开始训练

epochs = 50 #训练的次数
for epoch in range(epochs):

每次循环作为一次完整的训练轮次(epoch),在每个轮次中会遍历所有数据

data_loss = 0

在每个轮次(epoch)开始前会先清零累计损失,以便后续将每个批次的损失累加起来。

for batch_x, batch_y in data_provider(X, Y, batchsize):

调用data_provider(x, y, batchsize):生成器,每次迭代返回一批数据。每次循环batch_x为当前批次输入数据,batch_y为当前真实标签

pred_y = fun(batch_x, w_0, b_0)

调用函数fun来计算当前批次的预测值,fun实现了线性模型:计算公式为

pred_y= batch_x*w_0

loss = meaLoss(pred_y, batch_y)

使用定义的函数maeLoss计算平均绝对误差

loss.backward()

Pytorch会通过计算图计算w_0,b_0对loss的梯度,并将梯度存储在对应的参数.grad()中

sgrad([w_0, b_0], lr)
        data_loss += loss

参数 [w_0, b_0] 是一个列表,包含需要更新的参数。lr为学习率,用于控制每次参数更新的步长。

在sgd函数中会在不记录梯度的上下文中,利用当前梯度对参数进行 in-place 更新,并将梯度清

零,为下次迭代作准备

idx = 0
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()

绘制拟合结果图

九、代码总结

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    # matmul表示矩阵相乘

    noise = torch.normal(0, 0.01, y.shape)  # 噪音要加到y上
    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[:, 3], Y, 1)
plt.show()

def data_provider(data, label, batchsize):    # 每次访问这个函数,就能提供一批数据
    length = len(label)
    indices = list(range(length))   # 0-500的列表存入list

    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

batchsize = 16
# for batch_x, batch_y in data_provider(X, Y, batchsize):
#     print(batch_x, batch_y)


def fun(x, w, b):
    pred_y = torch.matmul(x, w) + b
    return pred_y

def meaLoss(pred_y, y):
    return torch.sum(abs(pred_y - y)) / len(y)


def sgrad(paras, lr): # 参数和学习率 随机梯度下降,更新参数
    with torch.no_grad(): #属于这句代码的部分,不计算梯度
        for para in paras:
            para -= para.grad * lr  # 不能写成 para = para - para.grad * lr
            para.grad.zero_() # 使用过的梯度 归0

lr = 0.03
w_0 = torch.normal(0, 0.01, true_w.shape, requires_grad=True) # 这个w需要计算梯度
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 = meaLoss(pred_y, batch_y)
        loss.backward()
        sgrad([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 = 0
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()

总结

在这里插入图片描述

您可能感兴趣的与本文相关的镜像

Qwen3-32B-Chat 私有部署镜像 | RTX4090D 24G 显存 CUDA12.4 优化版

Qwen3-32B-Chat 私有部署镜像 | RTX4090D 24G 显存 CUDA12.4 优化版

Qwen
文本生成
Qwen3

本镜像基于 RTX 4090D 24GB 显存 + CUDA 12.4 + 驱动 550.90.07 深度优化,内置完整运行环境与 Qwen3-32B 模型依赖,开箱即用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏目浅石.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值