本文目录
  1. 3.1自动微分模块的应用
  2. 4.构建线性损失函数

自动微分与线性模型

步骤:1.定义W旧–标量张量

​ 循环:

​ 2.定义损失函数 – 模拟

​ 3.对损失函数自动微分–得到梯度

​ 4. 自动微分完成后梯度会自动更新 w.grad 梯度

​ 5.利用梯度下降公式求出w新 w.data 当前权重

​ 6.清空上次的梯度,否则会累加 w.grad.zero_

import torch
# 步骤
# 1.定义w旧 标量张量 requires_grad=True表示需要计算梯度
w = torch.tensor(10, requires_grad=True, dtype=torch.float32)
for i in range(20):
    # 2.定义损失函数 -- 模拟
    loss = 2*w**2
    # 每个损失函数只能微分一次,如果要重新计算就要重新定义
    # 3.对损失函数自动微分 --得到梯度
    loss.backward()

    # 自动微分完成后,梯度会自动更新
    # print("新梯度", w.grad)

    # 4.利用梯度下降公式求出w新 -w.data表示当前权重(假设学习率为0.1)
    w.data = w - 0.1 * w.grad
    # 清空上次的w.grad,否则会一直累加
    w.grad.zero_()
    print(f"第{i+1}次迭代后,w的值为:{w.data}")
    
    
# 自动微分后张量不能转numpy,需要detach·()
w.detach().numpy()

3.1自动微分模块的应用

# 思路
# 1.准备数据
# 1.1 准备输入的w x b y
# x 样本数据 2 特征数据 5
import torch
torch.manual_seed(3)
x = torch.ones(2,5)
# y 样本数据 2 标签数据 3
y = torch.randn(2,3)
# w (5,3)  因为要和x相乘,x的形状是(2,5)  所以w的形状是(5,2)
w = torch.randn(5,3,requires_grad=True,dtype=torch.float32)
# b 标量 3,
b = torch.randn(3,requires_grad=True,dtype=torch.float32)
# Z = W @ X + B  (2,3)

# 定义损失函数
loss_fn = torch.nn.MSELoss()
loss = loss_fn(x @ w + b, y)

# 对损失函数自动微分
loss.backward()

# 查看梯度
print('w微分',w.grad)
print('b微分',b.grad)

4.构建线性损失函数

image-20260724100848088

构建线性损失函数的步骤:

1.准备数据 -> sklearn.datasets.make_regression

return x,y.reshape(-1,1),coef

2.训练模型

​ 2.1 数据处理

​ 数据 -> 张量(tensor) - > 数据集(TensorDataset) -> 数据加载器(DataLoader)

​ 2.2 模型训练

​ 2.2.1 模型准备

​ model = torch.nn.Linear(输入特征,输出特征)

​ 2.2.2 优化器准备 – 更新w值

​ optimizer = torch.optim.SGD(模型参数,学习率)

​ 2.2.3 模型预测

​ 训练模型

​ y_pre = model(x_train)

​ 损失函数实例化

​ loss_fn = torch.nn.MEALoss()

​ 计算损失

​ loss = loss_fn(y_pre,y_train)

​ 自动微分–损失函数求导得到梯度

​ loss.backword()

​ 更新w、b值

​ optimizer.step()

​ 梯度清零

​ optimizer.zero_grad()

最终结果

model.state_dict() – w值

coef 原始斜率

import torch
from sklearn.datasets import make_regression
from torch.utils.data import TensorDataset, DataLoader
import matplotlib.pyplot as plt
# 1,创建数据
def creat_data():
    x,y,coef=make_regression(
        n_samples=100,  # 样本数量
        n_features=1,   # 特征数量
        n_targets=1,    # 标签数量
        bias=3,         # 偏执 自定义
        noise=10,       # 噪声比例
        coef=True,       # 是否计算斜率
        random_state=3
    )

    print(type(x),type(y),type(coef))
    return x,y.reshape(-1,1),coef
    # y是[1,-1] 为了与x格式匹配方便后续处理 需要转成[-1,1]


def train(x,y,coef):
    # 1. 数据转张量
    # 返回的数据是numpy格式的数据,需要转成torch格式数据
    x = torch.tensor(x,dtype=torch.float32)
    y = torch.tensor(y,dtype=torch.float32)
    # 2.张量转成数据集
    dataset = TensorDataset(x,y)
    # 3.数据集转成数据加载器 #batch_size 批次训练数据量 shuffle 表示是否随机
    # 可以划分数据集,把原始数据集划分x_train,y_train
    dataloader = DataLoader(dataset,batch_size=16,shuffle=True)
    # 4.模型创建
    #4.1 准备模型
    model = torch.nn.Linear(in_features=1,out_features=1)
    #4.2 优化器创建 -- 更新w值 传入model的参数和学习率
    optimizer = torch.optim.SGD(model.parameters(),lr=0.01)
    # 记录数据
    loss_list = []
    loss_total,train_count=0,0
    #5. 训练
    #5.1 模型预测
    for i in range(100):
        for x_train,y_train in dataloader:
            y_pre = model(x_train)
            #5.2 损失函数
            loss_fn = torch.nn.MSELoss()
            loss = loss_fn(y_pre,y_train)
            # loss_list.append(loss.item())
            loss_total += loss.item()
            train_count += 1
            # 5. 3 自动微分
            loss.backward()
            # 5.4  更新数据
            optimizer.step()
            # 5.5  梯度清零
            optimizer.zero_grad()
        # print(f"第{train_count}次训练,平均损失:{loss_total/train_count}")
        loss_list.append(loss_total/train_count)
#    打印最终结果
    print(f"loss_list:{len(loss_list)}")
    print(model.state_dict())
    print(coef)

    # 绘制图像
    # 1.绘制损失函数曲线
    # plt.plot(range(len(loss_list)),loss_list)
    # plt.show()
    # 2.绘制样本点
    plt.scatter(x,y)
    # numpy数据不能和tensor数据进行计算,但是tensor可以和numpy进行计算,所以要把x写前面,coef写前面会报错
    # 不能用y画因为有噪声
    plt.plot(x,x*coef+3,'r')
    # tensor数据不能和numpy数据进行绘制,需要把tensor转为numpy,但是x自动微分过,所以tensor转为numpy需要使用detach()方法
    # 这里的model已经获得了最后计算的w、b值
    plt.plot(x,[i.detach().numpy() for i in model(x)],'g')
    plt.title("Linear Regression")
    plt.xlabel("x")
    plt.ylabel("y")
    plt.legend(["Data","Linear Regression","Predict"])
    plt.show()


if __name__ == '__main__':
    x,y,coef=creat_data()
    train(x,y,coef)