【pytorch练习】使用pytorch神经网络架构拟合余弦曲线

在本篇博客中,我们将通过一个简单的例子,讲解如何使用 PyTorch 实现一个神经网络模型来拟合余弦函数。本文将详细分析每个步骤,从数据准备到模型的训练与评估,帮助大家更好地理解如何使用 PyTorch 进行模型构建和训练。

一、背景

在机器学习中,拟合曲线是一个常见的任务,尤其是在函数预测和回归问题中。今天,我们使用一个简单的神经网络模型来拟合余弦曲线,具体步骤包括:

准备训练数据;

构建神经网络模型;

训练模型;

可视化预测结果与真实数据。

本例通过 PyTorch 实现了整个流程,我们将逐步展开。

二、代码解析

  1. 导入必要的库
python 复制代码
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
from torch.utils.data import TensorDataset
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False

首先,我们导入了PyTorch相关的库 torch、torch.nn,以及用于数据加载的 DataLoader 和 TensorDataset。为了可视化结果,我们还引入了 matplotlib。

此外,为了避免某些系统环境下的警告信息,我们设置了 os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE",这有助于避免在多线程计算中遇到一些潜在的错误。

  1. 准备拟合数据
python 复制代码
# 准备拟合数据
x = np.linspace(-2 * np.pi, 2 * np.pi, 400)  # 生成从 -2π 到 2π 的 400 个点
y = np.cos(x)  # 计算对应的余弦值

# 绘制生成的数据的散点图
plt.figure(figsize=(7, 5), dpi=160)
plt.scatter(x, y, color='red', label='生成数据')
plt.title('x 和 cos(x) 数据散点图', fontsize=15)
plt.xlabel('x', fontsize=12)
plt.ylabel('cos(x)', fontsize=12)
plt.legend(fontsize=12)
plt.grid(True)
plt.show()

使用 numpy.linspace 生成一个包含 400 个点的 x 轴数据,范围从 -2π 到 2π,然后计算对应的 y 值,这里 y = cos(x)。

  1. 接下来,将数据整理成 PyTorch 能够接受的格式
python 复制代码
# 将数据做成数据集的模样
X = np.expand_dims(x, axis=1)  # 使 X 变为二维数组
Y = y.reshape(400, -1)  # Y 为一列的数组
dataset = TensorDataset(torch.tensor(X, dtype=torch.float), torch.tensor(Y, dtype=torch.float))
dataloader = DataLoader(dataset, batch_size=10, shuffle=True)

通过 TensorDataset 将 x 和 y 数据捆绑成一个数据集,并使用 DataLoader 来批量加载数据,设置 batch_size=10,并启用数据打乱(shuffle=True)以增加模型训练的随机性。

  1. 构建神经网络
    接下来,我们将构建一个简单的神经网络来拟合这些数据。在这个例子中,我们使用了一个全连接的神经网络,并采用了 ReLU 激活函数。网络的结构如下:

输入层:1 个神经元(因为我们的输入是一个 1D 数值)。

隐藏层 1:10 个神经元,使用 ReLU 激活函数。

隐藏层 2:100 个神经元,使用 ReLU 激活函数。

隐藏层 3:10 个神经元,使用 ReLU 激活函数。

输出层:1 个神经元,输出拟合的结果。

python 复制代码
import torch.nn as nn

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.net = nn.Sequential(
            nn.Linear(in_features=1, out_features=10), nn.ReLU(),
            nn.Linear(10, 100), nn.ReLU(),
            nn.Linear(100, 10), nn.ReLU(),
            nn.Linear(10, 1)
        )

    def forward(self, input: torch.FloatTensor):
        return self.net(input)

# 创建模型实例
net = Net()
net 
python 复制代码
Net(
  (net): Sequential(
    (0): Linear(in_features=1, out_features=10, bias=True)
    (1): ReLU()
    (2): Linear(in_features=10, out_features=100, bias=True)
    (3): ReLU()
    (4): Linear(in_features=100, out_features=10, bias=True)
    (5): ReLU()
    (6): Linear(in_features=10, out_features=1, bias=True)
  )
)

这段代码定义了一个简单的神经网络类 Net,它继承自 nn.Module。通过 nn.Sequential 来堆叠多个层,使得网络的结构更加简洁和易于理解。每一层都紧跟着一个 ReLU 激活函数,用于引入非线性特征。

  1. 训练模型
    接下来,我们开始训练模型。我们选择 Adam 优化器,并使用均方误差(MSE)作为损失函数。在每个 epoch 中,我们都会迭代一次所有的训练数据,通过反向传播更新模型参数。
python 复制代码
# 设置优化器和损失函数
optim = torch.optim.Adam(net.parameters(), lr=0.001)
Loss = nn.MSELoss()

# 训练模型
for epoch in range(100):
    loss = None
    for batch_x, batch_y in dataloader:
        # 前向传播
        y_predict = net(batch_x)
        
        # 计算损失
        loss = Loss(y_predict, batch_y)
        
        # 清空梯度
        optim.zero_grad()
        
        # 反向传播
        loss.backward()
        
        # 更新参数
        optim.step()
    
    # 每10步打印一次训练日志
    if (epoch + 1) % 10 == 0:
        print(f"训练步骤: {epoch+1}, 模型损失: {loss.item()}")
python 复制代码
训练步骤: 10, 模型损失: 0.12506699562072754
训练步骤: 20, 模型损失: 0.024437546730041504
训练步骤: 30, 模型损失: 0.08189699053764343
训练步骤: 40, 模型损失: 0.03138166293501854
训练步骤: 50, 模型损失: 0.00651053711771965
训练步骤: 60, 模型损失: 0.0032562180422246456
训练步骤: 70, 模型损失: 0.00018047125195153058
训练步骤: 80, 模型损失: 0.005476313643157482
训练步骤: 90, 模型损失: 0.0014593529049307108
训练步骤: 100, 模型损失: 0.0008746677194721997
  1. 可视化
    训练完成后,我们可以使用训练好的模型来进行预测,并将预测结果与真实数据进行比较。
python 复制代码
# 绘制真实数据与预测数据的对比
plt.figure(figsize=(12, 7), dpi=160)
plt.plot(x, y, label="实际值", marker="X")
plt.plot(x, predict.detach().numpy(), label="预测值", marker='o')
plt.xlabel("x", size=15)
plt.ylabel("cos(x)", size=15)
plt.xticks(size=15)
plt.yticks(size=15)
plt.legend(fontsize=15)
plt.show()

通过绘制图表,我们可以清楚地看到,训练好的神经网络已经很好地拟合了余弦函数,并且与真实数据非常接近。

** 通过本篇教程,我们了解了如何使用 PyTorch 从零开始构建神经网络,并使用该网络拟合一个简单的余弦曲线。我们逐步演示了数据准备、网络构建、模型训练以及预测可视化的过程。希望通过这篇文章,你能够掌握神经网络的基本操作,并能够将其应用于其他任务中。**

如果你有任何问题或建议,欢迎在评论区留言交流!

相关推荐
深情不及里子2 分钟前
AI Agent | Coze 插件使用指南:从功能解析到实操步骤
人工智能·coze·插件配置
pk_xz1234567 分钟前
实现了一个结合Transformer和双向LSTM(BiLSTM)的时间序列预测模型,用于预测温度值(T0),并包含了物理约束的损失函数来增强模型的物理合理性
深度学习·lstm·transformer
代码的乐趣9 分钟前
支持selenium的chrome driver更新到136.0.7103.94
chrome·python·selenium
2201_7549184131 分钟前
OpenCV 光流估计:从原理到实战
人工智能·opencv·计算机视觉
渴望技术的猿33 分钟前
Windows 本地部署MinerU详细教程
java·windows·python·mineru
RockLiu@80535 分钟前
自适应稀疏核卷积网络:一种高效灵活的图像处理方案
网络·图像处理·人工智能
落樱弥城1 小时前
角点特征:从传统算法到深度学习算法演进
人工智能·深度学习·算法
StarRocks_labs1 小时前
StarRocks MCP Server 开源发布:为 AI 应用提供强大分析中枢
数据库·starrocks·人工智能·开源·olap·mcp
Aliano2171 小时前
TestNGException ClassCastException SAXParserFactoryImpl是Java自带的Xerces解析器——解决办法
java·开发语言·python
漫谈网络1 小时前
回调函数应用示例
开发语言·python·回调函数