繁体   English   中英

Python 中带有 Tensorflow.keras 的全局深度神经网络

[英]Global deep neural network with Tensorflow.keras in Python

我正在实现一种近似于偏微分方程解的算法。 这背后的主要思想是,我从时间 0 开始猜测解 u[0] 及其梯度 z[0],然后使用递归公式近似计算直到 a 中最后一个时间点的解前进的方式。 公式看起来像这样

u[i+1] = u[i] + f(t[i],x[i],u[i],z[i])*dt + z[i]*dW[i]

其中给出了函数 f、时间时间离散化、时间步长 dt 和布朗运动的增量 dW。 时间点 i 处的梯度 z[i] 由具有输入 x[i] 的深度神经网络来近似,我已经使用具有两个隐藏密集层的 tf.keras 实现了该深度神经网络。 这些网络表现得相当好。 到目前为止,我有 N(时间点数)独立神经网络,分别为每个时间点逼近 z[i]。

我的任务是形成一个具有输入 (x, W) 的全局神经网络,其中 (u[0], z[0]) 将作为网络参数提供给该网络,以便该网络可以通过以下方式优化其参数最小化 uN 的输出/近似的预期二次损失和偏微分方程 g(x) 的给定终端条件。 u[0] 将成为 PDE 的解。 因此,虽然我的近似神经网络每个都有 2 个隐藏层,但全局网络总共应该有 2*(N-1) 层。

我的梯度神经网络如下所示:

# Input dimension
d = 1
# Output dimension
d_1 = 1
# Number of neurons
m = d + 10
# Batch size
batch_size = 32
# Training data
x_tr = some_simulation()
z_tr = calculated_given(x_tr)
# Test data
x_te = some_simulation()
z_te = calculated_given(x_te)

model = tf.keras.Sequential()
    model.add(tf.keras.Input(shape=(d,), dtype=tf.float32))
    model.add(tf.keras.layers.Dense(m, activation=tf.nn.tanh))
    model.add(tf.keras.layers.Dense(m, activation=tf.nn.tanh))
    model.add(tf.keras.layers.Dense(d_1, activation=tf.keras.activations.linear))

    model.compile(optimizer='adam',
            loss='MeanSquaredError',
            metrics=[])
    model.fit(x_tr, z_tr, batch_size=batch_size, epochs=10)
    val_loss = model.evaluate(x_te, z_te)
    print(val_loss)

所以我训练了其中的 N 个,并使用

model.save(path_to_model)

所以给定梯度的近似值,我现在想将所有子网络堆叠在一起形成一个全局深度神经网络,它基于上面的递归公式,它只将 N 维向量 x 和 W 作为输入数据,并给出最终输出 u[N] 作为输出,并使用 (u[0], z[0]) 作为参数。 但是我试图用两天时间来思考如何使用 Tensorflow.keras 在 Python 中实现这样一个全局神经网络,所以也许有人可以给我一个正确的方向或一记耳光。 谢谢!

我假设您将元组(x, dW, t)作为输入传递给您的模型,因为t也被索引。 此外,您始终可以使用np.diffW创建dW 我还假设u0z0是标量(所有批次通用)。

考虑到所有这些,您可以子类化基本Model并覆盖其call()如下

class GlobalModel(tf.keras.models.Model):
    def __init__(self, u0, z0, dt, subnet_list, **kwargs):
        super().__init__(**kwargs)
        self.u0 = tf.Variable(u0, trainable=True, dtype=tf.float32)
        self.z0 = tf.Variable(z0, trainable=True, dtype=tf.float32)
        self.dt = tf.constant(dt, dtype=tf.float32)
        self.subnet_list = subnet_list

        # Freeze the pre-trained subnets
        for subnet in subnet_list:
            subnet.trainable = False  

    def f(t, x, u, z):
        # code of your function f() goes here

    def step_update(t, x, u, z, dW):
        return u + self.f(t, x, u, z) * self.dt + z * dW

    def call(inputs, training=None):
        x, dW, t = inputs
        u_i = self.u0

        for i, subnet in enumerate(self.subnet_list):
            x_i = tf.gather(x, i, axis=1)
            dW_i = tf.gather(dW, i, axis=1)
            t_i = tf.gather(t, i, axis=1)
            z_i = tf.cond(tf.equal(i, 0), lambda: self.z0, lambda: subnet(x_i, training=False))
            u_i = step_update(t_i, x_i, u_i, z_i, dW_i)

        return u_i
            

您通过以下方式初始化此模型

global_model = GlobalModel(init_u0, init_z0, dt, subnet_list)

其中subnet_list是您的预训练子网列表,按时间索引排序。 也就是说,负责预测z_i的子网应该在这个列表中的索引i-1处。

编译后,在模型上调用fit()

global_model.fit(x=(x_tr, dW_tr, t_tr), y=y_tr, batch_size=batch_size, epochs=epochs)

其中y_tr是您的目标。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM