栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

(python)利用pytorch拟合法求解非线性方程组

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

(python)利用pytorch拟合法求解非线性方程组

(python)利用pytorch拟合法求解非线性方程组
  • 一、问题
  • 二、求解
    • 步骤1:确定变量
    • 步骤2:设置模型
    • 步骤3:初始化变量
    • 步骤4:设置目标函数
    • 步骤5:常规训练过程
    • 步骤6:查看结果
  • 三、完整的代码

一、问题

比如要求解非线性方程组

(1) sin ⁡ i + sin ⁡ θ = 1.2 sin i+sin theta =1.2 sini+sinθ=1.2
(2) θ − i = 3 3 ° theta -i=33^° θ−i=33°

如果直接去求解会非常困难,但是可以尝试使用拟合的方式
pytorch虽然是深度学习常用库,但是对于求解非线性的拟合问题还是非常可靠的。

二、求解 步骤1:确定变量

首先分析方程,有两个未知数,分别是 θ theta θ和 i i i,并且它们都是角度制的

于是将它们写在一个字典中,用于存放 角度变量

'''
角度变量
'''
cfg_rad = {
    "i":30,
    "theta":40,
}

另外一般变量,或者弧度制的可以放到一般变量中比如没有出现角度的情况
但是此例子没有用到一般变量

'''
一般变量
'''
cfg_constant = {

}
步骤2:设置模型

这一步不用多看,其实就是将cfg中的变量,加载到模型中,也不需要修改,使用的时候直接复制就行了

class model(nn.Module):
    def __init__(self):
        super(model, self).__init__()
        for key,value in cfg_rad.items():
            setattr(self,key,nn.Parameter(torch.tensor(value)/180*np.pi))
        for key,value in cfg_constant.items():
            setattr(self,key,nn.Parameter(torch.tensor(value)))
    def rt_cfg(self):
        return *cfg_rad.keys(), *cfg_constant.keys()
    def forward(self):
        return [getattr(self,tmp) for tmp in self.rt_cfg()]
步骤3:初始化变量

只需要在定义变量最佳值加入 best_i、best_theta就行

net = model()
    optimizer = torch.optim.SGD(net.parameters(), lr=0.001)
    epoch = 1000
    best_loss = 10 ** 5

    '''
    变量最佳值
    '''
    best_i = None
    best_theta = None
步骤4:设置目标函数

这里就是输入我们的目标方程
对于 sin ⁡ i + sin ⁡ θ = 1.2 sin i+sin theta =1.2 sini+sinθ=1.2,我们可以写成 ( sin ⁡ i + sin ⁡ θ − 1.2 ) 2 (sin i+sin theta -1.2)^2 (sini+sinθ−1.2)2
对于 θ − i = 3 3 ° theta -i=33^° θ−i=33°,写成 θ − i − 33 / 180 ∗ π theta -i-33/180*pi θ−i−33/180∗π -----------------------因为传入模型的时候对角度变量手动转换成弧度制了

loss = (torch.sin(i) + torch.sin(theta) - 1.2) ** 2 + (theta - i - torch.tensor(33 / 180 * np.pi)) ** 2
步骤5:常规训练过程

注意当损失比较大难以收敛的时候,可以调整学习率参数lr

optimizer = torch.optim.SGD(net.parameters(), lr=0.001)
步骤6:查看结果

可以看到误差达到了小数点后4位
以及求解的 i i i和 θ theta θ

三、完整的代码

只需要修改加注释的部分即可

import torch
import numpy as np
from torch import nn


'''
角度变量
'''
cfg_rad = {
    "i":30,
    "theta":40,
}

'''
一般变量
'''
cfg_constant = {

}

class model(nn.Module):
    def __init__(self):
        super(model, self).__init__()
        for key,value in cfg_rad.items():
            setattr(self,key,nn.Parameter(torch.tensor(value)/180*np.pi))
        for key,value in cfg_constant.items():
            setattr(self,key,nn.Parameter(torch.tensor(value)))
    def rt_cfg(self):
        return *cfg_rad.keys(), *cfg_constant.keys()
    def forward(self):
        return [getattr(self,tmp) for tmp in self.rt_cfg()]

def train():
    net = model()
    optimizer = torch.optim.SGD(net.parameters(), lr=0.001)
    epoch = 1000
    best_loss = 10 ** 5

    '''
    变量最佳值
    '''
    best_i = None
    best_theta = None

    for _ in range(epoch):
        '''
        变量值 
        '''
        i, theta = net()
        # theta = i+torch.tensor(33/180*np.pi)

        '''
        目标方程
        '''
        loss = (torch.sin(i) + torch.sin(theta) - 1.2) ** 2 + (theta - i - torch.tensor(33 / 180 * np.pi)) ** 2


        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        if loss < best_loss:
            '''
            修改
            '''
            best_loss = loss

            best_i = i
            best_theta = theta
        print(loss)


    '''
    输出变量值
    '''
    print("i:", best_i / np.pi * 180)
    print("theta:", best_theta / np.pi * 180)


if __name__ == '__main__':
    train()
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/315918.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号