山东大学神经网络与深度学习实验二

实验要求:

学会构建线性回归模型以及模型训练,并使用matplotlib进行可视化

实验步骤:

1. 下载pytorch与matplotlib

2. 将以下代码粘贴并运行

import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt

# 随机生成线性分布数据
def generate_data(nums_data, k=2, if_plot=False):
    x = torch.linspace(0, 1, nums_data)
    x = torch.unsqueeze(x, dim=1)  # 将x变为二维向量
    y = k * x + torch.rand(x.size())  # 线性数据加噪声
    if if_plot:
        plt.scatter(x.numpy(), y.numpy(), c=x.numpy())
        plt.show()
    data = {"x": x, "y": y}
    return data


# 线性回归模型类
class LinearRegressionModel(nn.Module):
    def __init__(self):
        super(LinearRegressionModel, self).__init__()
        self.linear = nn.Linear(1, 1)  # 一维输入一维输出

    def forward(self, x):
        return self.linear(x)

# 训练函数
def train_model(model, data, epochs=50, learning_rate=0.01):
    criterion = nn.MSELoss()  # 损失函数:均方误差
    optimizer = optim.SGD(model.parameters(), lr=learning_rate)  # 优化器:随机梯度下降

    x_train = data["x"]
    y_train = data["y"]

    # 可视化模型函数
    def plot_model(step):
        with torch.no_grad():
            predicted = model(x_train).detach().numpy()
            plt.scatter(x_train.numpy(), y_train.numpy(), c='blue', label='True data')
            plt.plot(x_train.numpy(), predicted, 'r-', label='Fitted line')
            plt.title(f'Model at step {step}')
            plt.legend()
            plt.show()

    # 初始化模型可视化
    plot_model(0)

    # 开始训练
    for epoch in range(epochs):
        for step in range(len(x_train)):
            inputs = x_train[step].unsqueeze(0)  # 取单个数据
            targets = y_train[step].unsqueeze(0)

            outputs = model(inputs)  # 模型预测
            loss = criterion(outputs, targets)  # 计算损失

            optimizer.zero_grad()  # 梯度清零!!!!!
            loss.backward()  # 反向传播
            optimizer.step()  # 优化一步

            if step % 10 == 0 and epoch == 0:  # 每10步可视化一次初期模型
                plot_model(f"epoch_0_step_{step}")

        if epoch == 0 or epoch == epochs // 2:  # 在训练一半时可视化
            plot_model(f"epoch_{epoch}")

    # 最终模型可视化
    plot_model("final")


# 示例生成数据并可视化
data = generate_data(100, if_plot=True)
model = LinearRegressionModel()
train_model(model, data)

3. 得到结果

实验总结: 

该实验让我知道了用pytorch进行一个简单神经网络训练(可能算吧,它也没激活函数)的基本步骤:

1. 处理数据:让数据变成:data = {"x": x, "y": y} 的形式

2. 定义模型:①继承nn.Module类 ②选择模型类别与输入输出形式self.linear = nn.Linear(1, 1) ③定义前向传播计算函数 return self.linear(x)

3. 写训练函数

        1  设定损失函数:criterion = nn.MSELoss() # 损失函数:均方误差

        2  设定优化器:optimizer = optim.SGD(model.parameters(), lr=learning_rate)

            # 优化器:随机梯度下降

        3  描述训练过程:

                ① 根据优化器构建循环,并确定提取的数据,比如随机梯度下降就是二重循环

                ② 模型预测        outputs = model(inputs) # 模型预测

                ③ 计算损失        loss = criterion(outputs, targets) # 计算损失

                ④ 梯度清零        optimizer.zero_grad() # 梯度清零!!!!!

                ⑤ 反向传播        loss.backward() # 反向传播

                ⑥ 更新模型超参数        optimizer.step() # 优化一步

疑惑与解答:

?:

  • loss.backward() # 反向传播  这一步是怎么将自动计算出的梯度传到模型中的呢?

!:

  • 前向传播时,从 inputs 到 loss 的所有操作都被记录下来,形成了一个计算图。

  • 调用 loss.backward() 时,PyTorch 会从 loss 开始,沿着计算图反向传播,计算出所有需要计算梯度的张量的梯度。

  • 正向传播forward是model的一个方法,所以正向传播形成的计算图与model相连,反向传播通过计算图找到模型并将计算出的梯度存储在每个参数的 .grad 属性中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值