【神经网络+数学】——(5)神经网络求解二元方程组问题
背景求解方程组问题(线性非线性均可,不带微积分)问题描述xy+x3+y3=11yxy+x^3+y^3=11yxy+x3+y3=11yx2y2+x2+2y2=10x^2y^2+x^2+2y^2=10x2y2+x2+2y2=10不限制xy范围,实际解为x=2 y=1注意俩方程也可能解出来多套解,我只是先设定了实际解的一组解,然后构造的方程组,所以还可能存在其他解神经网络思路:参考遗传算法求解方程组的思
背景
求解方程组问题(线性非线性均可,不带微积分)
问题描述
x
y
+
x
3
+
y
3
=
11
y
xy+x^3+y^3=11y
xy+x3+y3=11y
x
2
y
2
+
x
2
+
2
y
2
=
10
x^2y^2+x^2+2y^2=10
x2y2+x2+2y2=10
不限制xy范围,实际解为x=2 y=1
注意俩方程也可能解出来多套解,我只是先设定了实际解的一组解,然后构造的方程组,所以还可能存在其他解
神经网络
思路:参考遗传算法求解方程组的思路,将评估函数设定为每个方程移项(将等号右侧变为0)后等号左侧的平方和(遗传算法需要构造平方和的倒数,因为适应度函数需要越大越好),所以输入模型的feature就是初值(实验发现不能是全0)
输出的y是平方和,损失值拿y和0计算均方误差或绝对值误差(其实直接拿y_pred作为损失值即可,y_true任意给,不过需要写自定义损失函数,麻烦些),和一般网络训练的不同在于:feature只有一个样本,label是全0。
有论文将输出的y作为solution,即在本任务中是两维,然后损失值拿平方和计算(自定义损失函数,y_true任意给,loss通过y_pred来计算)
构建模型:
inputs = Input(shape=(2,))
x = inputs
# x = Dense(6, activation=activation)(x)
# x = Dense(16, activation=activation)(x)
x = Dense(2, activation=activation,name='solve')(x)
x = func(x)
model = Model(inputs=inputs,outputs=x)
本想通过三层来拟合,实际理论推导发现,输入是初值,在solve层是输出solution,即:
[ x 0 y 0 ] [ w 1 w 2 ; w 3 w 4 ] = [ x s o l v e y s o l v e ] [x_0\ y_0][w_1\ w_2;w_3\ w_4]=[x_{solve}\ y_{solve}] [x0 y0][w1 w2;w3 w4]=[xsolve ysolve]
通过
x
0
和
y
0
x_0和y_0
x0和y0的线性组合得到solution解向量,所以也没必要使用非线性激活函数以及多层,所以最后只用了一层。
训练代码:
model.compile(optimizer=Adam(lr),
loss='mse')
model.fit(feature,label,batch_size,epochs)
model.save("pinn2d.h5")
model_solve = Model(inputs=model.input,outputs=model.get_layer(name='solve').output)
solve = model_solve.predict(feature)
print("solve:",solve)
loss = func_np(solve)
print("loss:",loss)
结果:
这个解是事先不知道的,代入原方程验证loss:
说明这确实存在一个负的解,选的初值不同会导致最后的收敛结果不同,可能通过遍历一个初值的list来扫描全部解集是一个较好的解决方法,这就对初值list的选择带来了挑战性。
结论
神经网络求解方程组的工作已完成,不足是全部解集元素的寻找工作。
更多推荐
所有评论(0)