Tensorflow学习一个输入依赖变量和一个输入自变量
Tensorflow to learn an input dependent and an input independent variable
我正在尝试实施一个物理知识网络来发现汉堡方程 (https://arxiv.org/abs/1711.10561)。这包括 2 个预测。流体速度的预测取决于位置和时间点(它们是输入)以及扩散系数 nu,这在所有剖面中都很常见。
我是这样搭建网络的
def neural_network (train):
inp_1 = Input(shape=(train.shape[1],)) #setting the size of the input layer
initial = 'he_uniform'
x = Dense(20,kernel_initializer= initial, activation = 'tanh', bias_initializer=initial)(inp_1)
x = Dense(20,kernel_initializer= initial, activation = 'tanh', bias_initializer=initial)(x)
x = Dense(20,kernel_initializer= initial, activation = 'tanh', bias_initializer=initial)(x)
x = Dense(20,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
x = Dense(20,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
x = Dense(20,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
x = Dense(1,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
nu = tf.Variable([[1.]], trainable = True, shape=((1,1)))
nu= Dense(1,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(nu)
out = tf.concat([x, nu], 1)
return Model(inputs=inp_1, outputs=out)
model = Sequential()
model = neural_network(xt_train)
model.summary()
然后尝试在一些示例代码上评估我的表达式:
def residualValOfPDE(xt, nu):
x = xt[:, 0:1] # x coordinate
t = xt[:, 1:2] # t coordinate
with tf.GradientTape(persistent=True) as tape:
tape.watch(x)
tape.watch(t)
u, nu = model( tf.stack([x[:, 0], t[:, 0]], axis=1) )[0]
u_x = tape.gradient(u, x)
u_t = tape.gradient(u, t)
u_xx = tape.gradient(u_x, x)
return u_t + u*u_x - nu*u_xx
其中xt_f包含位置和时间作为列,不同的点作为行。
现在,当我尝试计算一个点的表达式时:
print( residualValOfPDE(xt_f[1:2,:], nu))
它工作正常。但是,当我尝试传递多个点时:
print( residualValOfPDE(xt_f[1:3,:], nu))
我收到以下错误:
InvalidArgumentError Traceback (most recent call
last) in
19 return u_t + uu_x - nuu_xx
20 #
---> 21 print( residualValOfPDE(xt_f[1:3,:], nu)) # calculate the residual value at each collection point
in residualValOfPDE(xt, nu)
11 tape.watch(t)
12
---> 13 u, nu = model( tf.stack([x[:, 0], t[:, 0]], axis=1) )[0]
14 u_x = tape.gradient(u, x)
15
~/.local/lib/python3.8/site-packages/keras/utils/traceback_utils.py in
error_handler(*args, **kwargs)
65 except Exception as e: # pylint: disable=broad-except
66 filtered_tb = _process_traceback_frames(e.traceback)
---> 67 raise e.with_traceback(filtered_tb) from None
68 finally:
69 del filtered_tb
~/.local/lib/python3.8/site-packages/tensorflow/python/framework/ops.py
in raise_from_not_ok_status(e, name) 7105 def
raise_from_not_ok_status(e, name): 7106 e.message += (" name: " +
name if name is not None else "")
-> 7107 raise core._status_to_exception(e) from None # pylint: disable=protected-access 7108 7109
InvalidArgumentError: Exception encountered when calling layer
"tf.concat_28" (type TFOpLambda).
ConcatOp : Dimensions of inputs should match: shape[0] = [2,1] vs.
shape[1] = [1,1] [Op:ConcatV2] name: concat
Call arguments received: • values=['tf.Tensor(shape=(2, 1),
dtype=float32)', 'tf.Tensor(shape=(1, 1), dtype=float32)'] • axis=1
• name=concat
有什么解决办法吗?
提前致谢
问题是您正在创建硬编码批量大小为 1 的 nu
变量。这就是为什么它仅适用于 1 的样本大小,而不是更多。很难说你想做什么,但你可以尝试这样的事情:
import tensorflow as tf
class NuLayer(tf.keras.layers.Layer):
def __init__(self, batch_dim, initial='he_uniform'):
super(NuLayer, self).__init__()
self.batch_dim = batch_dim
def build(self, input_shape):
self.nu = tf.Variable(initial_value = tf.ones((self.batch_dim,1)), trainable = True)
def call(self, inputs):
return self.nu
inp_1 = tf.keras.layers.Input(shape=(2,)) #setting the size of the input layer
initial = 'he_uniform'
x = tf.keras.layers.Dense(20,kernel_initializer= initial, activation = 'tanh', bias_initializer=initial)(inp_1)
x = tf.keras.layers.Dense(20,kernel_initializer= initial, activation = 'tanh', bias_initializer=initial)(x)
x = tf.keras.layers.Dense(20,kernel_initializer= initial, activation = 'tanh', bias_initializer=initial)(x)
x = tf.keras.layers.Dense(20,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
x = tf.keras.layers.Dense(20,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
x = tf.keras.layers.Dense(20,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
x = tf.keras.layers.Dense(1,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
nu = NuLayer(batch_dim=4)
nu = nu(inp_1)
out = tf.keras.layers.Concatenate(axis=1)([x, nu])
model = tf.keras.Model(inputs=inp_1, outputs=out)
def residualValOfPDE(xt):
x = xt[:, 0:1] # x coordinate
t = xt[:, 1:2] # t coordinate
with tf.GradientTape(persistent=True) as tape:
tape.watch(x)
tape.watch(t)
u, nu = model(tf.stack([x[:, 0], t[:, 0]], axis=1) )[0]
u_x = tape.gradient(u, x)
u_t = tape.gradient(u, t)
u_xx = tape.gradient(u_x, x)
return u_t + u*u_x - nu*u_xx
xt_f = tf.random.normal((10000, 2))
print( residualValOfPDE(xt_f[1:3,:]))
tf.Tensor(
[[0.5751909]
[0. ]], shape=(2, 1), dtype=float32)
如果您想检查不同的批量大小,请更改 Input
层中的批量大小:
nu = NuLayer(batch_dim=4)
print( residualValOfPDE(xt_f[1:5,:]))
[[-0.51205623]
[ 0. ]
[ 0. ]
[ 0. ]], shape=(4, 1), dtype=float32)
我正在尝试实施一个物理知识网络来发现汉堡方程 (https://arxiv.org/abs/1711.10561)。这包括 2 个预测。流体速度的预测取决于位置和时间点(它们是输入)以及扩散系数 nu,这在所有剖面中都很常见。
我是这样搭建网络的
def neural_network (train):
inp_1 = Input(shape=(train.shape[1],)) #setting the size of the input layer
initial = 'he_uniform'
x = Dense(20,kernel_initializer= initial, activation = 'tanh', bias_initializer=initial)(inp_1)
x = Dense(20,kernel_initializer= initial, activation = 'tanh', bias_initializer=initial)(x)
x = Dense(20,kernel_initializer= initial, activation = 'tanh', bias_initializer=initial)(x)
x = Dense(20,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
x = Dense(20,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
x = Dense(20,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
x = Dense(1,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
nu = tf.Variable([[1.]], trainable = True, shape=((1,1)))
nu= Dense(1,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(nu)
out = tf.concat([x, nu], 1)
return Model(inputs=inp_1, outputs=out)
model = Sequential()
model = neural_network(xt_train)
model.summary()
然后尝试在一些示例代码上评估我的表达式:
def residualValOfPDE(xt, nu):
x = xt[:, 0:1] # x coordinate
t = xt[:, 1:2] # t coordinate
with tf.GradientTape(persistent=True) as tape:
tape.watch(x)
tape.watch(t)
u, nu = model( tf.stack([x[:, 0], t[:, 0]], axis=1) )[0]
u_x = tape.gradient(u, x)
u_t = tape.gradient(u, t)
u_xx = tape.gradient(u_x, x)
return u_t + u*u_x - nu*u_xx
其中xt_f包含位置和时间作为列,不同的点作为行。 现在,当我尝试计算一个点的表达式时:
print( residualValOfPDE(xt_f[1:2,:], nu))
它工作正常。但是,当我尝试传递多个点时:
print( residualValOfPDE(xt_f[1:3,:], nu))
我收到以下错误:
InvalidArgumentError Traceback (most recent call last) in 19 return u_t + uu_x - nuu_xx 20 # ---> 21 print( residualValOfPDE(xt_f[1:3,:], nu)) # calculate the residual value at each collection point
in residualValOfPDE(xt, nu) 11 tape.watch(t) 12 ---> 13 u, nu = model( tf.stack([x[:, 0], t[:, 0]], axis=1) )[0] 14 u_x = tape.gradient(u, x) 15
~/.local/lib/python3.8/site-packages/keras/utils/traceback_utils.py in error_handler(*args, **kwargs) 65 except Exception as e: # pylint: disable=broad-except 66 filtered_tb = _process_traceback_frames(e.traceback) ---> 67 raise e.with_traceback(filtered_tb) from None 68 finally: 69 del filtered_tb
~/.local/lib/python3.8/site-packages/tensorflow/python/framework/ops.py in raise_from_not_ok_status(e, name) 7105 def raise_from_not_ok_status(e, name): 7106 e.message += (" name: " + name if name is not None else "") -> 7107 raise core._status_to_exception(e) from None # pylint: disable=protected-access 7108 7109
InvalidArgumentError: Exception encountered when calling layer "tf.concat_28" (type TFOpLambda).
ConcatOp : Dimensions of inputs should match: shape[0] = [2,1] vs. shape[1] = [1,1] [Op:ConcatV2] name: concat
Call arguments received: • values=['tf.Tensor(shape=(2, 1), dtype=float32)', 'tf.Tensor(shape=(1, 1), dtype=float32)'] • axis=1 • name=concat
有什么解决办法吗? 提前致谢
问题是您正在创建硬编码批量大小为 1 的 nu
变量。这就是为什么它仅适用于 1 的样本大小,而不是更多。很难说你想做什么,但你可以尝试这样的事情:
import tensorflow as tf
class NuLayer(tf.keras.layers.Layer):
def __init__(self, batch_dim, initial='he_uniform'):
super(NuLayer, self).__init__()
self.batch_dim = batch_dim
def build(self, input_shape):
self.nu = tf.Variable(initial_value = tf.ones((self.batch_dim,1)), trainable = True)
def call(self, inputs):
return self.nu
inp_1 = tf.keras.layers.Input(shape=(2,)) #setting the size of the input layer
initial = 'he_uniform'
x = tf.keras.layers.Dense(20,kernel_initializer= initial, activation = 'tanh', bias_initializer=initial)(inp_1)
x = tf.keras.layers.Dense(20,kernel_initializer= initial, activation = 'tanh', bias_initializer=initial)(x)
x = tf.keras.layers.Dense(20,kernel_initializer= initial, activation = 'tanh', bias_initializer=initial)(x)
x = tf.keras.layers.Dense(20,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
x = tf.keras.layers.Dense(20,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
x = tf.keras.layers.Dense(20,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
x = tf.keras.layers.Dense(1,kernel_initializer= initial, activation = 'tanh',bias_initializer=initial)(x)
nu = NuLayer(batch_dim=4)
nu = nu(inp_1)
out = tf.keras.layers.Concatenate(axis=1)([x, nu])
model = tf.keras.Model(inputs=inp_1, outputs=out)
def residualValOfPDE(xt):
x = xt[:, 0:1] # x coordinate
t = xt[:, 1:2] # t coordinate
with tf.GradientTape(persistent=True) as tape:
tape.watch(x)
tape.watch(t)
u, nu = model(tf.stack([x[:, 0], t[:, 0]], axis=1) )[0]
u_x = tape.gradient(u, x)
u_t = tape.gradient(u, t)
u_xx = tape.gradient(u_x, x)
return u_t + u*u_x - nu*u_xx
xt_f = tf.random.normal((10000, 2))
print( residualValOfPDE(xt_f[1:3,:]))
tf.Tensor(
[[0.5751909]
[0. ]], shape=(2, 1), dtype=float32)
如果您想检查不同的批量大小,请更改 Input
层中的批量大小:
nu = NuLayer(batch_dim=4)
print( residualValOfPDE(xt_f[1:5,:]))
[[-0.51205623]
[ 0. ]
[ 0. ]
[ 0. ]], shape=(4, 1), dtype=float32)