PyTorch非线性函数拟合

1. 线性函数

线性函数用于拟合线性的曲线

2. 非线性函数

非线性函数怎么拟合呢?

  • 使用非线性函数拟合
  • 使用线性函数+非线性函数(激活函数去拟合)
    为了和神经网络相统一,用线性函数+激活函数去拟合非线性函数

3.搭建网络

在这里插入图片描述
分两路进行全连接层,然后将输出拼接,再经过三个全连接层

4.代码实现

使用Tensorboard查看数据

from numpy.core.function_base import linspace
import torch
import numpy as np 
import matplotlib.pyplot as plt
from torch import nn, optim
import torch.nn.functional as F
from matplotlib.animation import FuncAnimation
import threading
from torch.utils.data import Dataset, DataLoader
from torch.utils.tensorboard import SummaryWriter

xx = linspace(0, 2, 3000)
class Data(Dataset):
    def __init__(self):
        super(Data, self).__init__()
        self.x = linspace(0, 3.14, 3000)
        self.y = []
        for i in self.x:
            '''
            # 阶梯函数
            if i <=1:
                self.y.append(0)
            else:
                self.y.append(1)
            # 方波函数
            if i <=0.5 or i >= 1.5:
                self.y.append(0)
            else:
                self.y.append(1)
            # 正弦函数
            self.y = np.sin(self.x*2)
            '''
            self.y = np.sin(self.x*2)
            
    def __len__(self):
        return len(self.x)
    def __getitem__(self, index):
        x = self.x[index]
        y = self.y[index]
        x = torch.tensor(x).unsqueeze(dim=0).float()
        y = torch.tensor(y).unsqueeze(dim=0).float()
        return x, y

train = Data()
train_data = DataLoader(train, batch_size=3000, shuffle=False)

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(1, 10)
        self.fc2 = nn.Linear(1, 10)
        self.fc3 = nn.Linear(20, 100)
        self.fc4 = nn.Linear(100, 50)
        self.fc5 = nn.Linear(50, 1)
    def forward(self, x):
        x1 = F.relu(self.fc1(x))
        x2 = F.relu(self.fc2(x))
        x3 = torch.cat((x1, x2), dim=1)
        x = self.fc3(x3)
        x = F.relu(self.fc4(x))
        x = self.fc5(x)
        return x

net = Net()
optimizer = optim.Adam(net.parameters(), lr=0.001)
loss_fn = nn.MSELoss()

for epoch in range(10000):
    for x, y in train_data:
        y_pred = net(x)
        loss = loss_fn(y_pred, y)
        print(f"\r第{epoch}个epoch的损失为{loss.item()}", end="")
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    if epoch%50 == 0:
        fig = plt.figure()
        subfig1 = fig.add_subplot(1,2,1)
        subfig1.plot(x.detach().numpy(), y_pred.detach().numpy())
        subfig1 = fig.add_subplot(1,2,2)
        subfig1.plot(x.detach().numpy(), y.detach().numpy())
        writer = SummaryWriter()
        writer.add_figure('figure', fig, global_step=None, close=True, walltime=None)
        writer.add_scalar('Loss', loss.item(), epoch)
        # plt.show()

使用Matplotlib查看变化动画

from numpy.core.function_base import linspace
import torch
import numpy as np 
import matplotlib.pyplot as plt
from torch import nn, optim
import torch.nn.functional as F
from matplotlib.animation import FuncAnimation
import threading
from torch.utils.data import Dataset, DataLoader
from torch.utils.tensorboard import SummaryWriter
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

xx = linspace(0, 2, 3000)
class Data(Dataset):
    def __init__(self):
        super(Data, self).__init__()
        self.id = 1
        self.x = linspace(0, 3.14, 3000)
        self.y = []
        for i in self.x:
            if self.id ==0 :
                # 阶梯函数
                if i <=1:
                    self.y.append(0)
                else:
                    self.y.append(1)
            elif self.id == 1:
                # 方波函数
                if i <=0.5 or i >= 1.5:
                    self.y.append(0)
                else:
                    self.y.append(1)
            elif self.id == 2:
                # 正弦函数
                self.y = np.sin(self.x*2)
                self.y = np.sin(self.x*2)
            
    def __len__(self):
        return len(self.x)
    def __getitem__(self, index):
        x = self.x[index]
        y = self.y[index]
        x = torch.tensor(x).unsqueeze(dim=0).float()
        y = torch.tensor(y).unsqueeze(dim=0).float()
        return x, y

train = Data()
train_data = DataLoader(train, batch_size=3000, shuffle=False)

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(1, 10)
        self.fc2 = nn.Linear(1, 10)
        self.fc3 = nn.Linear(20, 100)
        self.fc4 = nn.Linear(100, 50)
        self.fc5 = nn.Linear(50, 1)
    def forward(self, x):
        x1 = F.relu(self.fc1(x))
        x2 = F.relu(self.fc2(x))
        x3 = torch.cat((x1, x2), dim=1)
        x = self.fc3(x3)
        x = F.relu(self.fc4(x))
        x = self.fc5(x)
        return x

net = Net()
optimizer = optim.Adam(net.parameters(), lr=0.001)
loss_fn = nn.MSELoss()
xx, yy, y_pred = None, None, None

def train():
    global xx, yy, y_pred
    for epoch in range(10000):
        for x, y in train_data:
            xx = x
            yy = y
            y_pred = net(x)
            loss = loss_fn(y_pred, y)
            print(f"\r第{epoch}个epoch的损失为{loss.item()}", end="")
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
thread1 = threading.Thread(target=train)
thread1.start()


fig, ax = plt.subplots()
ln, = plt.plot([], [], 'red')

# 初始化函数
def init():
    ax.set_xlim(0, np.pi)
    ax.set_ylim(-1, 1)
    return ln,

# 更新函数
def update(frame):
    ln.set_data(xx.detach().numpy(), y_pred.detach().numpy())
    return ln,

# 播放动画函数
ani = FuncAnimation(fig, update, frames=50,
                    init_func=init, interval=200, blit=True)
plt.show()

5.拟合效果

左侧为拟合图,右侧为实际图

在这里插入图片描述

  1. 方波函数
    在这里插入图片描述

  2. 三角函数
    在这里插入图片描述

参考

PyTorch文档

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当前非线性拟合和多元拟合的工具较少,这是针对常用的拟合算法,开发的一款数据拟合为主的软件。包括线性拟合的各种算法,非线性拟合的各种算法,以及多元拟合的各种算法。其中提供了很多非线性方程的模型,以满足不同的需求,也可以制定自己所需要的指定非线性方程模型的,采用最先进的初始值估算算法,无需初始值就可以拟合自己想要的非线性方程模型各个模块的介绍如下。 1.线性拟合算法模块 根据最小二乘拟合算法,对输入的数据进行变量指定次方的拟合。同时可对自变量或因变量进行自然对数和常用对数的转换后再拟合。根据实际情况,开发了单调性拟合以针对各种定量分析的用途。同时开发了,针对一组数据,得到最高相关系数的自动拟合功能,由程序自动选择拟合次数以及自变量和因变量的数据格式。 2.非线性拟合算法模块 根据非线性方程的特点,开发了最先进的智能初始值估算算法,配合LM迭代算法,进行非线性方程的拟合。只需要输入自变量和因变量,就可以拟合出所需要的非线性方程。拟合相关系数高,方便快捷。并借助微粒群算法,开发了基于微粒群的智能非线性拟合算法,拟合出方程的相关系数相当高,甚至会出现过拟合现象。 3.多元拟合算法模块 根据最小二乘算法的原理开发了多元线性拟合算法,同时开发了能够指定变元次数的高次多元线性拟合。由于多元变量的情况下函数关系复杂,采用高次多元线性拟合能有效提高拟合效果而不会出现过拟合现象。同时针对每个变元可能最合适的拟合次数不一定都一样,开发了自适应高次多元拟合算法。
### 回答1: 好的,这是一个 PyTorch 程序例子,它拟合一段非线性函数: ```python import torch import matplotlib.pyplot as plt # 定义非线性函数 def func(x): return x**2 + 10*torch.sin(x) # 生成训练数据 X = torch.unsqueeze(torch.linspace(-5, 5, 100), dim=1) y = func(X) # 定义模型 class Net(torch.nn.Module): def __init__(self): super(Net, self).__init__() self.hidden = torch.nn.Linear(1, 20) self.predict = torch.nn.Linear(20, 1) def forward(self, x): x = torch.relu(self.hidden(x)) x = self.predict(x) return x net = Net() # 定义损失函数和优化器 criterion = torch.nn.MSELoss() optimizer = torch.optim.SGD(net.parameters(), lr=0.2) # 训练模型 for epoch in range(100): prediction = net(X) loss = criterion(prediction, y) optimizer.zero_grad() loss.backward() optimizer.step() # 可视化结果 plt.figure() plt.scatter(X.data.numpy(), y.data.numpy(), label='Original data') plt.plot(X.data.numpy(), prediction.data.numpy(), label='Fitting Line') plt.legend() plt.show() ``` 祝你好运! ### 回答2: import torch import torch.nn as nn import torch.optim as optim from torch.autograd import Variable import numpy as np import matplotlib.pyplot as plt # 创建一个非线性函数 def nonlinear_function(x): y = 0.5 * (x ** 2) + 2 * x + 1 return y # 生成训练数据 x_train = torch.unsqueeze(torch.linspace(-5, 5, 100), dim=1) y_train = nonlinear_function(x_train) + torch.randn(x_train.size()) * 0.1 # 定义神经网络模型 class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.hidden = nn.Linear(1, 10) self.relu = nn.ReLU() self.output = nn.Linear(10, 1) def forward(self, x): x = self.hidden(x) x = self.relu(x) x = self.output(x) return x # 实例化模型 model = Net() # 定义损失函数和优化器 criterion = nn.MSELoss() optimizer = optim.Adam(model.parameters(), lr=0.01) # 开始训练 num_epochs = 1000 for epoch in range(num_epochs): inputs = Variable(x_train) targets = Variable(y_train) # 向前传播 output = model(inputs) loss = criterion(output, targets) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() if (epoch+1) % 100 == 0: print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, loss.item())) # 显示拟合结果 model.eval() x_test = torch.unsqueeze(torch.linspace(-6, 6, 200), dim=1) y_pred = model(Variable(x_test)) plt.plot(x_train.data.numpy(), y_train.data.numpy(), 'ro', label='Original data') plt.plot(x_test.data.numpy(), y_pred.data.numpy(), 'b-', label='Fitted line') plt.legend() plt.show() ### 回答3: import torch import torch.nn as nn import torch.optim as optim import numpy as np # 定义非线性函数 def non_linear_func(x): return torch.sin(x) # 创建训练数据 x_train = np.random.uniform(-10, 10, size=(1000, 1)) y_train = non_linear_func(torch.Tensor(x_train)).numpy() # 转换为Tensor x_train = torch.Tensor(x_train) y_train = torch.Tensor(y_train) # 定义神经网络模型(单层全连接网络) class NonLinearRegression(nn.Module): def __init__(self): super(NonLinearRegression, self).__init__() self.fc = nn.Linear(1, 1) # 输入维度为1,输出维度为1 def forward(self, x): x = self.fc(x) return x # 初始化模型和优化器 model = NonLinearRegression() optimizer = optim.SGD(model.parameters(), lr=0.01) loss_func = nn.MSELoss() # 训练模型 for epoch in range(100): y_pred = model(x_train) loss = loss_func(y_pred, y_train) optimizer.zero_grad() loss.backward() optimizer.step() if (epoch+1) % 10 == 0: print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, 100, loss.item())) # 预测并可视化结果 import matplotlib.pyplot as plt x_test = np.arange(-10, 10, 0.1) x_test = torch.Tensor(x_test.reshape(-1, 1)) y_pred = model(x_test) plt.scatter(x_train.numpy(), y_train.numpy(), color='b', label='Actual') plt.plot(x_test.numpy(), y_pred.detach().numpy(), color='r', label='Predicted') plt.legend() plt.xlabel('x') plt.ylabel('y') plt.title('Nonlinear Regression') plt.show()

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值