我正在使用 PINN 求解阻尼振荡器微分方程,并同时找到后者的摩擦参数,给定阻尼振荡器的噪声观测值作为输入。我写道...
我正在使用 PINN 来求解阻尼振荡器微分方程,同时找到后者的摩擦参数,给定阻尼振荡器的噪声观测作为输入。我使用自定义训练程序使用 Tensorflow 编写了代码。问题是我定义的可训练参数并没有接近我从噪声观测中知道的正确值。最终,PINN 的解决方案完全不正确。但是,我的代码运行良好,无需寻找可训练参数(即此处的摩擦参数)的附带任务。
以下功能解释:
-
振荡器系统数据损失:振荡器系统作为神经网络的实现,其中可学习参数 mu 被传递给 NN_osc_func 中实现的 ODE
-
train_NN_data_loss:自定义训练程序
-
plot_epochs_with_noise:与问题无关,但用于训练时的监控
def oscillator_system_data_loss(t, net, func, params, mu, bc, t_data, u_data, lambda1):
t = t.reshape(-1,1)
t = tf.constant(t, dtype = tf.float32)
t_0 = tf.zeros((1,1))
with tf.GradientTape() as outer_tape:
outer_tape.watch(t)
with tf.GradientTape() as inner_tape:
inner_tape.watch(t)
x = net(t)
dx_dt = inner_tape.gradient(x, t) # 1st derivative
d2x_dt2 = outer_tape.gradient(dx_dt, t) # 2nd derivative
bc_loss_1 = tf.square(net(t_0) - bc[0])
bc_loss_2 = tf.square(dx_dt[0] - bc[1])
ode_loss = d2x_dt2 - func(x, dx_dt, params[0], mu, params[2])
data_loss = u_data - net(t_data)
square_loss = tf.square(ode_loss) + lambda1*tf.square(data_loss) + bc_loss_1 + bc_loss_2
total_loss = tf.reduce_mean(square_loss)
return total_loss, mu
def train_NN_data_loss(epochs, optm, NN, func, bc, lambda1, train_t, train_u, data_t, data_u,
data_u_noised, test_t_plot, true_u_plot, testing_t):
train_loss_record = []
loss_tracker = plotting_points(epochs)
mu = tf.Variable(initial_value=tf.ones((1,1)), trainable=True, dtype=tf.float32)
mu_list = []
early_stop = 0
for itr in range(epochs):
with tf.GradientTape() as tape:
train_loss, mu = oscillator_system_data_loss(train_t, NN, func, params, mu, bc, data_t, data_u_noised, lambda1)
train_loss_record.append(train_loss)
grad_w = tape.gradient(train_loss, NN.trainable_variables + [mu])
optm.apply_gradients(zip(grad_w, NN.trainable_variables + [mu]))
if itr in loss_tracker:
print(train_loss.numpy())
print(mu.numpy())
plot_epochs_with_noise(train_t, train_u, data_t, data_u_noised, test_t_plot, true_u_plot, testing_t, itr, NN)
mu_list.append(mu.numpy())
return train_loss_record, mu_list, early_stop
NN_osc_func = lambda x, dx_dt, k, d, m: -k/m*x - d/m*dx_dt
您可以在此处看到 6000 个 epoch 后的结果。神经网络收敛到一条水平线,误差为 5.76,参数估计为 0.84,尽管正确值为 4。这是我的阻尼振荡器设置:
k = 400
d = 4
m = 1
y0 = np.array([1.0, 0.0])
错误的结果。
相应损失。
不幸的是,目前我不知道问题可能出在哪里。我尝试更改 NN_osc_func
在这两个函数中 tape.gradient()
尝试了
我的一些想法是,要么训练更长时间,要么我可能会遇到 PINN 容易出现的一些高频问题。
训练 PINN 来反演未知参数
下载声明:
本站所有软件和资料均为软件作者提供或网友推荐发布而来,仅供学习和研究使用,不得用于任何商业用途。如本站不慎侵犯你的版权请联系我,我将及时处理,并撤下相关内容!