【问题标题】:Tensorflow to learn an input dependent and an input independent variableTensorflow 学习输入依赖和输入独立变量
【发布时间】:2021-12-06 14:00:37
【问题描述】:

我正在尝试实现一个基于物理的网络来发现汉堡方程的方程 (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(最近调用 最后)在 19 返回 u_t + uu_x - nuu_xx 20# ---> 21 print(residualValOfPDE(xt_f[1:3,:], nu)) # 计算每个采集点的残差

inresidualValOfPDE(xt, nu) 11tape.watch(t) 12 ---> 13 u, nu = model( tf.stack([x[:, 0], t[:, 0]], axis=1) )[0] 14 u_x = 磁带.渐变(u,x) 15

~/.local/lib/python3.8/site-packages/keras/utils/traceback_utils.py 在 error_handler(*args, **kwargs) 65 例外为 e: # pylint: disable=broad-except 66 filters_tb = _process_traceback_frames(e.traceback) ---> 67 从无提升 e.with_traceback(filtered_tb) 68最后: 69 删除过滤_tb

~/.local/lib/python3.8/site-packages/tensorflow/python/framework/ops.py 在 raise_from_not_ok_status(e, name) 7105 def raise_from_not_ok_status(e, name): 7106 e.message += (" name: " + name 如果 name 不是 None else "") -> 7107 raise core._status_to_exception(e) from None # pylint: disable=protected-access 7108 7109

InvalidArgumentError: 调用层时遇到异常 “tf.concat_28”(类型 TFOpLambda)。

ConcatOp :输入的尺寸应该匹配:shape[0] = [2,1] vs. shape[1] = [1,1] [Op:ConcatV2] 名称:concat

收到的调用参数: • values=['tf.Tensor(shape=(2, 1), dtype=float32)', 'tf.Tensor(shape=(1, 1), dtype=float32)'] • 轴=1 • 名称=连接

任何想法如何解决它? 提前致谢

【问题讨论】:

  • xt_fnu的形状是什么?
  • xtf_f 有 (10000, 2) 并且 nu 应该有形状 1
  • 我将 nu 的代码更改为具有 xt_f 的形状并且始终具有相同的值,但随后我得到 OperatorNotAllowedInGraphError: itating over tf.Tensor is not allowed: AutoGraph 确实转换了这个函数。这可能表明您正在尝试使用不受支持的功能。
  • 抱歉,这是一种类型,现已更正
  • 嗯,很奇怪。我得到了 nu 的形状 ()

标签: python tensorflow keras deep-learning tensorflow2.0


【解决方案1】:

问题是您正在创建硬编码批量大小为 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)

【讨论】:

  • 这与我想要的非常接近。几个问题:1)是否可以动态地设置批量大小? 2)是否可以只返回 self.nu 并使其可训练?
  • 问题 1:您必须重新排列整个模型。目前,没有。问题2:是的。检查更新的答案。
  • 谢谢!我只是堆叠了 nu 而不是动态地设置批量大小,它似乎可以工作。可悲的是,它还没有完全训练,但我会继续戳,看看会发生什么:-D
猜你喜欢
  • 2017-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 2017-04-14
  • 1970-01-01
  • 2018-10-08
相关资源
最近更新 更多