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

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

相关推荐
AI赛奇23 分钟前
【清华出品】deepseek进阶版教程
人工智能·ai写作
byxdaz26 分钟前
OpenCV实现图像分割与无缝合并
人工智能·opencv·计算机视觉
九鼎创展科技38 分钟前
“全志V821:智能玩具的理想之选”——科技赋能,乐趣升级
人工智能·嵌入式硬件·ai
Firmin12345641 分钟前
使用Flask和OpenCV 实现树莓派与客户端的视频流传输与显示
python·opencv·flask
时光旅人01号1 小时前
神经网络微调技术解析
人工智能·深度学习·神经网络
rockmelodies1 小时前
基于Python的端口扫描器和目录扫描工具实现方案,结合机器学习进行指纹识别
人工智能·python·机器学习
灵动小溪1 小时前
Deepseek 本地部署
人工智能
DB_UP1 小时前
浅谈数据分析及数据思维
大数据·人工智能·数据分析
是十一月末1 小时前
Opencv之掩码实现图片抠图
人工智能·python·opencv·计算机视觉·图片识别
阿_星_1 小时前
解决pip install 出现error: subprocess-exited-with-error的问题
开发语言·python·pip