- 一、问题
- 二、求解
- 步骤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虽然是深度学习常用库,但是对于求解非线性的拟合问题还是非常可靠的。
首先分析方程,有两个未知数,分别是 θ 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()



