【深度学习】学习笔记:PyTorch两种方式实现线性回归模型

前言

用Torch库实现线性回归模型通常是学习神经网络基础及熟悉pytorch的有效方式。这里用自定义LinearRegressionModel类 和 使用nn.Sequential容器进行模型构建两种方式演示了线性回归的实现方式。

class定义模型

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

# 生成数据
np.random.seed(0)
torch.manual_seed(0)

# 真实参数
true_w = 2.0
true_b = 3.0

# 数据量
n_samples = 100
X = np.random.rand(n_samples, 1) * 10  # 随机生成X值
y = true_w * X + true_b + np.random.randn(n_samples, 1)  # 生成y值,添加一些噪声

# 转换为 PyTorch 张量
X_tensor = torch.FloatTensor(X)
y_tensor = torch.FloatTensor(y)

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

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


# 初始化模型
model = LinearRegressionModel()

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

# 优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)  # 随机梯度下降

# 训练轮次
num_epochs = 100

for epoch in range(num_epochs):
    # 调为训练模式
    model.train()

    # 前向传播
    outputs = model(X_tensor)
    loss = criterion(outputs, y_tensor)

    # 反向传播和优化
    optimizer.zero_grad()  # 清空之前的梯度
    loss.backward()  # 计算梯度
    optimizer.step()  # 更新参数

    if (epoch + 1) % 10 == 0:
        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')

# 可视化
with torch.no_grad():
    predicted = model(X_tensor).detach().numpy()  # 禁用梯度计算以进行取值操作

plt.scatter(X, y, label='Data', color='blue')
plt.plot(X, predicted, label='Fitted line', color='red')
plt.legend()
plt.xlabel('X')
plt.ylabel('y')
plt.title('Linear Regression with PyTorch')
plt.show()

其中的一点理解:

nn.Sequential容器构建模型

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

# 设置随机种子以确保可重复性
torch.manual_seed(0)

# 生成一些线性数据,与前面类似
X = np.random.rand(100, 1) * 10          # 输入特征值 (100 个样本)
y = 2.5 * X + np.random.randn(100, 1)    # 目标值 (带噪声的线性关系)

# 转换为张量
X_tensor = torch.FloatTensor(X)
y_tensor = torch.FloatTensor(y)

# 使用 nn.Sequential 定义线性回归模型
model = nn.Sequential(
    nn.Linear(1, 1)  # 输入特征维度和输出维度均为 1
)

# 损失函数
criterion = nn.MSELoss()

# 优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练模型
num_epochs = 100
for epoch in range(num_epochs):
    model.train()  # 设置模型为训练模式

    # 前向传播
    outputs = model(X_tensor)
    loss = criterion(outputs, y_tensor)

    # 反向传播和优化
    optimizer.zero_grad()  # 清空梯度
    loss.backward()  # 计算梯度
    optimizer.step()  # 更新参数

    if (epoch + 1) % 10 == 0:  # 每 10 个 epoch 打印一次损失
        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')

# 评估模型
model.eval()  # 设置模型为评估模式
with torch.no_grad():
    predicted = model(X_tensor).detach().numpy()

# 可视化结果
plt.scatter(X, y, label='Original Data')  # 原始数据
plt.plot(X, predicted, color='red', label='Fitted Line')  # 预测线
plt.xlabel('Input Feature')
plt.ylabel('Target Value')
plt.legend()
plt.show()

两者对比

下面两个图片展示了两种方式的使用对比:

自定义模型类:

  • 结构:通过自定义 nn.Module 的子类,显式地定义了每一层的参数和激活函数。
  • 可扩展性:这种方式使得你可以更方便地添加复杂的逻辑或其他操作,例如在 forward 方法中实现条件逻辑、循环等。
  • 清晰性:当模型较为复杂时,这种方式有助于提高代码的清晰度和可读性。

使用 nn.Sequential:

  • 结构:利用 nn.Sequential 简洁地按顺序定义层,每一层以列表形式呈现。
  • 简便性:这种方式适合于简单的线性堆叠结构,非常容易编写和阅读,特别是在层数不多的情况下。
  • 限制性:对于复杂模型(例如需要跳跃连接、并行分支等结构)来说,使用 nn.Sequential 会受到限制,因为它只能直接处理线性的层级关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值