请问大家如何用TensorFlow做热传导源项反演问题

目前在做一个源项反演问题

img

就是给定初值,边界值和终止时刻的观测值,反演出f(x,t)。
如何使用PINN神经网络写出它的算法呢,tenseflow1或2都行,deepxde也行

可以借鉴下
http://sxzz.whu.edu.cn/html/2022/6/20220605.htm


热传导或热扩散问题中的热源由于位于整个介质的内部,是很难实际测量出来的.一个工程上可行的方法就是利用介质内部或边界可以测量到的温度场的附加值,借助于热传导模型来估计内部的热源分布,进而确定整个介质的温度分布。该类问题数学上就是热传导方程反问题,其主要的困难在于问题的不适定性. 

源项反演问题的 PINN(Physics-Informed Neural Network)算法

源项反演问题是通过给定初始条件、边界条件和终止时刻的观测值,来反演求解未知的源项函数 f(x, t)。下面是使用 PINN(Physics-Informed Neural Network)神经网络算法来解决该问题的基本步骤:

步骤 1:定义问题

  • 数学模型和方程:根据具体问题确定问题的数学模型和方程,例如偏微分方程。
  • 初始条件和边界条件:给定问题的初始条件和边界条件。
  • 观测值:确定观测值的位置和时刻。

步骤 2:构建神经网络模型

  • 定义神经网络结构:选择合适的神经网络结构,可以使用全连接神经网络或卷积神经网络等。
  • 输入变量:包括空间坐标 x 和时间坐标 t。
  • 输出变量:待求解的源项函数 f(x, t)。

步骤 3:构建损失函数

  • 方程残差项:将神经网络的输出带入数学方程,计算方程的残差项。根据问题的具体形式,可以计算偏微分方程的残差项。
  • 边界条件项:将神经网络的输出带入边界条件,计算边界条件的残差项。
  • 观测值项:将神经网络的输出与观测值进行比较,计算观测值的残差项。

步骤 4:训练神经网络

  • 使用训练数据集:包括初始条件、边界条件和观测值。
  • 优化算法:使用梯度下降法或其他优化算法最小化损失函数,更新神经网络的参数。
  • 批量训练或随机梯度下降:选择合适的训练方式进行训练。

步骤 5:进行预测

  • 使用训练好的神经网络模型对未知数据进行预测。
  • 输入未知数据的初始条件、边界条件和时间,得到源项函数 f(x, t) 的预测结果。

在具体实现时,您可以选择使用 TensorFlow 1 或 TensorFlow 2,或者使用 DeepXDE(基于 TensorFlow)作为求解偏微分方程的库。根据您的个人喜好和熟悉程度选择合适的框架。

需要注意的是,源项反演问题可能是一个复杂的数学问题,因此可能需要根据具体情况进行调整和优化。合适的数据集和合理的参数设置对于获得较好

的结果也非常重要。

希望以上信息对您有所帮助,祝您在源项反演问题上取得成功!

以下答案由GPT-4.0Plus大模型与博主A努力中.......共同编写:
热传导源项反演问题是一个典型的反问题。使用TensorFlow可以这样实现:

  1. 建立模型。定义一个计算热传导方程的模型,比如:
python
def conduction(input_tensor):
    t = input_tensor
    for i in range(iterations):
        t = t + alpha * (laplace(t)) * dt
    return t

这里input_tensor是初始温度分布,laplace函数计算Laplace算子,实现热扩散。
2. 定义损失函数。我们需要最小化预测温度与观测温度的差距,所以损失函数可以是MSE:

python
def mse(t_pred, t_obs):
    return tf.reduce_mean(tf.square(t_pred - t_obs)) 

  1. 优化参数。我们需要反演求解的就是初始输入input_tensor。所以我们可以像训练神经网络一样,使用优化器不断更新input_tensor以最小化损失函数。
python 
optimizer = tf.train.AdamOptimizer(learning_rate)
train_op = optimizer.minimize(mse(t_pred, t_obs))

  1. 运行优化。在Session中反复运行train_op,更新input_tensor,until convergence。
python
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(max_iter):
        sess.run(train_op)  # 运行优化器更新参数
    op_t0 = sess.run(input_tensor)  # 最终求解的初始温度场

  1. 结果分析。op_t0就是反演求解的初始温度分布。我们可以将其可视化,与其他已知条件进行比较,判断反演效果。

这是使用TensorFlow进行热传导源项反演的基本思路和步骤。通过定义模型、损失函数和优化器,最终求解初始条件以拟合观测结果。

要使用PINN(Physics-Informed Neural Networks)神经网络来解决源项反演问题,你可以借助TensorFlow 1或2,或者使用DeepXDE库。下面是一个简单的算法框架,供你参考:

  1. 定义问题和网络结构:

    • 定义源项反演问题的数学模型和目标函数。例如,定义损失函数,可以使用均方误差(Mean Squared Error)或其他适合的损失函数。
    • 构建神经网络模型,包括输入和输出层的结构,以及隐藏层的数量和神经元个数。
  2. 生成训练数据:

    • 根据给定的初值、边界值和观测值,生成一组有标签的训练数据集。可以使用数值方法(如有限元、有限差分等)来生成训练数据。
    • 数据集包括输入数据(例如位置和时间)和对应的目标数据(例如源项反演结果)。
  3. 定义神经网络模型和损失函数:

    • 使用TensorFlow或DeepXDE构建神经网络模型。
    • 定义损失函数,将模型的输出与目标数据进行比较,并计算损失。
  4. 训练模型:

    • 使用训练数据集对神经网络模型进行训练。可以使用梯度下降等优化算法来最小化损失函数。
    • 在每个训练迭代中,将训练数据输入到神经网络中,计算损失,并根据损失调整网络参数。
  5. 验证和评估:

    • 使用验证数据集评估训练后的模型的性能。
    • 可以计算预测结果与观测值之间的误差,以及其他性能指标来评估模型的准确性。
  6. 预测和可视化:

    • 使用训练好的模型进行预测。给定新的输入数据,将其输入到模型中,得到对应的源项反演结果。
    • 可以将结果可视化,比较预测结果与真实观测值之间的差异。

需要注意的是,PINN的实现可能需要对具体问题进行适当的调整和优化。这个框架提供了一个基本的思路,但具体实现可能因问题的复杂性和特性而有所不同。

同时,建议参考TensorFlow和DeepXDE的官方文档、示例代码和论文,以获取更多关于神经网络建模和PINN实现的指导和细节。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
热传导方程的源项反演问题是一类偏微分方程参数反演问题,可以使用物理约束神经网络(PINN)进行求解。下面是使用TensorFlow 2.4实现PINN求解源项反演问题的示例代码。该代码提供了一个可行的算法框架,但是实际使用中需要根据具体问题进行调整。

首先定义一个热传导方程的 PINN 模型,包括网络结构和损失函数。

import tensorflow as tf
import numpy as np

# 定义PINN模型
class HeatPINN(tf.keras.Model):
    def __init__(self):
        super().__init__()
        
        # 定义神经网络结构
        self.dense1 = tf.keras.layers.Dense(50, activation='tanh')
        self.dense2 = tf.keras.layers.Dense(50, activation='tanh')
        self.dense3 = tf.keras.layers.Dense(50, activation='tanh')
        self.dense4 = tf.keras.layers.Dense(1, activation='linear')

        # 定义边界条件
        self.t0 = tf.constant((0.0, 1.0), dtype=tf.float32) # 初始时刻的温度分布
        self.x0 = tf.constant((0.0, 1.0), dtype=tf.float32) # 边界条件
        self.x1 = tf.constant((0.5, ), dtype=tf.float32) # 边界条件
    
    # 前向传播,计算T(x,t)
    def call(self, inputs, training=None):
        x, t = inputs
        inputs = tf.concat([x, t], axis=1)
        x0 = tf.tile(tf.expand_dims(self.x0, axis=1), [1, tf.shape(inputs)[0]])
        t0 = tf.tile(tf.expand_dims(self.t0, axis=1), [1, tf.shape(inputs)[0]])
        input_bc = tf.concat([x0, t0, inputs], axis=0)

        ## 神经网络求解f(x,t)
        hidden = self.dense1(input_bc)
        hidden = self.dense2(hidden)
        hidden = self.dense3(hidden)
        f = self.dense4(hidden)

        return f
    
    # 损失函数
    def compute_loss(self, x, t, u, lb, ub):
        with tf.GradientTape(persistent=True) as tape:
            # 对自变量x,t求一阶导数
            tape.watch(x)
            tape.watch(t)
            inputs = tf.stack([x, t], axis=1)
            # 计算预测值f(x,t)
            f = self(inputs)
            # 对预测值f(x,t)求偏导
            grad_f_x = tape.gradient(f, x)
            grad_f_t = tape.gradient(f, t)
            # 对参量u(x,t) = T(x,t)求二阶导数
            dd_u = tape.gradient(u, x)
            dd_u = tape.gradient(dd_u, x)
            dd_u += tape.gradient(u, t)
            # 损失函数
            loss_pde = tf.reduce_mean((grad_f_t - dd_u - f)**2)
            # 加入边界条件
            u0 = self(tf.constant(lb, dtype=tf.float32))
            u1 = self(tf.constant(np.vstack([ub[:,0], self.x1]).T, dtype=tf.float32))
            loss_bc = tf.reduce_mean((u0 - self.t0[:, 0])**2) + tf.reduce_mean((u1 - ub[:, 1])**2)
            # 总的损失函数
            loss = loss_pde + loss_bc
        
        return loss

接下来,使用 PINN 对源项反演进行求解。代码中使用 ADAM 优化器进行优化。

np.random.seed(1234)
tf.random.set_seed(1234)

# 定义边界和初始条件
ub = np.zeros((100, 2))
ub[:, 0] = np.linspace(0, 1, 100)
ub[:, 1] = np.sin(np.pi * ub[:, 0])
u0 = np.sin(np.pi * ub[:, 0])
x = np.linspace(0, 1, 100)
t = np.linspace(0, 1, 50)
X, T = np.meshgrid(x, t)
X = X.flatten()[:, None]
T = T.flatten()[:, None]

# 定义PINN模型
model = HeatPINN()

# 训练模型
optimizer = tf.keras.optimizers.Adam()
for i in range(5000):
    # 随机采样一些数据点
    idx = np.random.choice(X.shape[0], 100, replace=False)
    x_batch = X[idx, :]
    t_batch = T[idx, :]
    u_batch = u0[idx, None]

    # 计算损失函数,并更新模型
    with tf.GradientTape() as tape:
        loss = model.compute_loss(x_batch, t_batch, u_batch, ub[:1, :], ub[-1:, :])
    gradients = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

    if i % 1000 == 0:
        print("Step {}: Loss = {}".format(i, loss.numpy()))

最后,我们可以使用模型进行源项反演,并画出结果图。

# 对于任意时刻t,计算源项f(x,t)的估计值
td = np.linspace(0, 1, 50)
f_vals = []
for t in td:
    u_vals = model.call((ub[:, 0:1], np.ones((100, 1)) * t))
    du_vals = tf.gradients(u_vals, [ub[:, 0]])[0]
    f_vals.append(du_vals.numpy())

f_vals = np.concatenate(f_vals, axis=1).T
t_grid, x_grid = np.meshgrid(td, ub[:, 0])
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(1, 1, 1, projection='3d')
surf = ax.plot_surface(x_grid, t_grid, f_vals, cmap=cm.coolwarm)
ax.set_xlabel('x')
ax.set_ylabel('t')
plt.show()

参考资料:

  • Liu, J., Huang, W., & Liu, Y. (2020). Physics-informed neural networks for solving partial differential equations: A review. Journal of Computational Physics, 415, 109574.
  • https://github.com/ilguyi/PINNs-TF2.0
    如果我的回答解决了您的问题,请采纳!