[英]Import tensorflow.python.keras instead of 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.diff
从W
创建dW
。 我还假设u0
和z0
是标量(所有批次通用)。
考虑到所有这些,您可以子类化基本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.