神经网络求解二阶常微分方程(代码)

相关的理论推导请参考: 神经网络求解二阶常微分方程.
在这里展示我使用Tensorflow设计的,求解二阶常微分方程的程序结果。二阶常微分方程式由以下方程给出:
在这里插入图片描述

二阶微分方程的初始值:
在这里插入图片描述

该微分方程的解析解:
在这里插入图片描述

使用设计的程序,仿真出的结果如图所示:
在这里插入图片描述
其中,解析解和神经网络解之间的差值用下图可以看出:
在这里插入图片描述
可以看到,这个拟合结果还是非常不错的,误差数量级控制在10^-4以下。

以下是程序分享

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
#若使用tf V2.0以上版本,将上面的那一行注释掉,改为这两行
#import tensorflow.compat.v1 as tf
#tf.compat.v1.disable_eager_execution()

import matplotlib.pyplot as plt
import numpy as np
import math
x_train = np.linspace(0, 2, 400)#生成[0,2]区间400个点
y_trail = np.exp(-0.2*x_train)*np.sin(x_train)#已知解析解用于比较
x_t = np.zeros((len(x_train), 1))
for i in range(len(x_train)):
    x_t[i] = x_train[i]
x1 = tf.placeholder("float", [None, 1])
W = tf.Variable(tf.zeros([1, 10]))
b = tf.Variable(tf.zeros([10]))
y1 = tf.nn.sigmoid(tf.matmul(x1, W)+b)#sigmoid激活函数y1的形状[10,10]
W1 = tf.Variable(tf.zeros([10, 1]))
b1 = tf.Variable(tf.zeros([1]))
y = tf.matmul(y1, W1)+b1#网络的输出[10,1]
lq = tf.exp(-0.2*x1)*tf.cos(x1)

dif1 = tf.matmul(tf.multiply(y1*(1-y1),W),W1)#dy/dx,dif形状[100,1],即对应点的一阶导数值
dif2 = tf.matmul(tf.multiply((y1*(1-y1)*(1-y1)-y1*y1*(1-y1))*W, W),W1)#对应点的二阶导数值
t_loss = (dif2+0.2*dif1+y+0.2*lq)**2#常微分方程F的平方
# loss = tf.reduce_mean(t_loss)+(y[0]-0)**2+(y[199]-math.sin(1)*math.exp(-0.2))**2#每点F平方求和后取平均再加上边界条件
loss = tf.reduce_mean(t_loss)+(y[0]-0)**2+(dif1[0]-1)**2
train_step = tf.train.AdamOptimizer(0.0001).minimize(loss)#Adam优化器训练网络参数
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    for i in range(50000):#训练50000次
        sess.run(train_step,feed_dict={x1: x_t})
        if i%50 == 0:
            total_loss = sess.run(loss,feed_dict={x1: x_t})
            print("loss={}".format(total_loss))
            print(sess.run(y[0], feed_dict={x1: x_t}))
    # saver = tf.train.Saver(max_to_keep=1)#保存模型,训练一次后可以将训练过程注释掉
    # saver.save(sess,'ckpt/nn.ckpt',global_step=50000)
    # saver = tf.train.Saver(max_to_keep=1)
    # model_file="ckpt/nn.ckpt-50000"
    # saver.restore(sess, model_file)
    output = sess.run(y,feed_dict={x1:x_t})
    output1 = sess.run(t_loss,feed_dict={x1:x_t})
    y_output = x_train.copy()
    y_output1 = x_train.copy()
    for i in range(len(x_train)):
        y_output[i] = output[i]
        y_output1[i] = output1[i]
    fig = plt.figure("预测曲线与实际曲线")
    L1, = plt.plot(x_train,y_trail, c = 'b')
    L2, = plt.plot(x_train,y_output, c = 'g')
    plt.legend([L1,L2],["analytic solution","network solution"], loc='upper right')
    plt.title('Comparison of results')
    fig2 = plt.figure("y_-y")#画实际值与预测值得偏差
    plt.title('y_-y')
    plt.plot(x_train,y_trail-y_output)
    fig3 = plt.figure("loss")#画出每一点对Loss的贡献
    plt.title('loss')
    plt.plot(x_train,y_output1+(y_output[0]-1)**2)
    plt.show()

最后说明,本程序参考了以下博主提供的代码,在其基础上开发了二阶常微分求解的方法。在此对其表示感谢
Tensorflow一个很简单的神经网络求解常微分及偏微分方程.

你可能感兴趣的:(神经网络,tensorflow,偏微分方程,深度学习)