【问题标题】:Keras functional api multiple input: The list of inputs passed to the model is redundantKeras 功能 api 多输入:传递给模型的输入列表是多余的
【发布时间】:2020-03-13 19:02:35
【问题描述】:

我有一个巨大的网络 (keras-bert),可以很好地进行分类。由于我的数据有两个不同的列,我想为每一列微调一个 BERT 模型,并将它们连接到最后一层。但我收到以下错误:

---> 20 模型 = keras.models.Model(inputs=[inputs1, inputs2], outputs=outputs)

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/network.py in _validate_graph_inputs_and_outputs(self)

1620 """验证图网络的输入和输出。"""

1621 # 检查输入中的冗余。

-> 1622 如果 len(set(self.inputs)) != len(self.inputs):

1623 raise ValueError('传递给模型的输入列表'

1624 ' 是多余的。 '

TypeError: unhashable type: 'list'

在我的代码中,我有两个 bert 模型,model1model2。只有一个模型它工作得很好。我唯一添加的是从检查点和第二个输入层加载了 2 个模型而不是一个模型,以及dense1 和dense2 的串联:

#load_trained_model_from_checkpoint is defined here:
# https://github.com/CyberZHG/keras-bert/blob/master/keras_bert/loader.py
model1 = load_trained_model_from_checkpoint(
    config_path,
    checkpoint_path,
    training=True,
    trainable=True,
    seq_len=SEQ_LEN,
    )
model2 = load_trained_model_from_checkpoint(
    config_path,
    checkpoint_path,
    training=True,
    trainable=True,
    seq_len=SEQ_LEN,
)

inputs1 = model1.inputs[:2] #model 1 for titles
inputs2 = model2.inputs[:2] #model 2 for texts
dense1 = model1.get_layer('NSP-Dense').output
dense2 = model2.get_layer('NSP-Dense').output
outputs = keras.layers.Dense(len(test_title_y[0]), activation='sigmoid')(keras.layers.concatenate([dense1, dense2]))


model = keras.models.Model(inputs=[inputs1, inputs2], outputs=outputs)

我在监督什么?我是否必须以某种方式包装输入?

编辑: 我怀疑这个问题与我的输入是列表列表有关:输入 1 和输入 2 看起来像这样:

[<tf.Tensor 'Input-Token:0' shape=(?, 256) dtype=float32>, <tf.Tensor 'Input-Segment:0' shape=(?, 256) dtype=float32>]
[<tf.Tensor 'Input-Token_1:0' shape=(?, 256) dtype=float32>, <tf.Tensor 'Input-Segment_1:0' shape=(?, 256) dtype=float32>]

我能否以某种方式重塑或连接我的输入来克服这个错误?

编辑:

model1 的摘要看起来像这样,model2 看起来一样,但每个层名称都有 LAYER_2:

层(类型)输出形状参数#连接到


Input-Token (InputLayer) (None, 256) 0


输入段(InputLayer)(无,256)0


Embedding-Token(TokenEmbedding[(None, 256, 768), (23440896 Input-Token[0][0])


Embedding-Segment(嵌入)(None, 256, 768) 1536 Input-Segment[0][0]


...(中间有很多层)


NSP-Dense (Dense) (None, 768) 590592 Extract[0][0]

【问题讨论】:

  • model1model2 是从同一个原始模型创建的吗?他们使用相同的original_model.input吗?
  • 我相应地编辑了我的帖子,两个模型都是从配置构建的,并从检查点加载了预训练的权重。
  • 能否展示一下model1和model2的概要?它们似乎是相同的(相同的配置路径,相同的张量)
  • @DanielMöller 我在我的问题中添加了模型摘要的一部分

标签: python keras


【解决方案1】:

这听起来可能有点复制+粘贴,但是当您注意到输入是列表列表时,我认为您解决了自己的问题。

不要使用[inputs1, inputs2],而是使用inputs1 + inputs2

测试它们是否是带有isinstance(inputs1, list) 的列表。

【讨论】:

  • 是的,它们都是列表,但我仍然不确定如何解决问题。
  • 使用+ 加入列表,就像在答案中一样。
  • 如果它们不是列表怎么办?
  • @DanielMöller 我遇到了同样的错误,但我的输入没有列出,它们是 tensorflow.python.keras.engine.keras_tensor.KerasTensor,有解决此错误的线索吗?
  • @the_learning_child,不可能知道你的问题,它说它是一个列表,然后它是一个列表。你必须找到哪里。
【解决方案2】:

看起来有一个内部检查来寻找模型的等长输入。在这种情况下,两个输入都是[batchSize, 256]。您可以做的一件事是尝试将两个输入打包成一个具有三个维度的输入(即[batchSize, inputs, 256])。您需要在模型中处理一些切片,以确保将正确的输入传递给图层。

这是一个例子:

#load_trained_model_from_checkpoint is defined here:
# https://github.com/CyberZHG/keras-bert/blob/master/keras_bert/loader.py

model1 = load_trained_model_from_checkpoint(
    config_path,
    checkpoint_path,
    training=True,
    trainable=True,
    seq_len=SEQ_LEN,
    )
model2 = load_trained_model_from_checkpoint(
    config_path,
    checkpoint_path,
    training=True,
    trainable=True,
    seq_len=SEQ_LEN,
)

inputs1 = model1.inputs[:2] #model 1 for titles
inputs2 = model2.inputs[:2] #model 2 for texts
# concatenate the inputs into one tensor
concatInputs = keras.backend.concatenate([inputs1, inputs2],axis=0)

dense1 = model1.get_layer('NSP-Dense').output
dense2 = model2.get_layer('NSP-Dense').output

def getModel():
    inputs=keras.layers.Input([2,256])
    # slice inputs into individual tensors
    in1 = keras.layers.Lambda(lambda x: tf.slice(inputs,[0,0],[1,inputs.get_shape()[1]])
    in2 = keras.layers.Lambda(lambda x: tf.slice(inputs,[1,0],[2,inputs.get_shape()[1]])
    d1 = dense1(in1)
    d2 = dense2(in2)
    outputs = keras.layers.Dense(len(test_title_y[0]), activation='sigmoid')(keras.layers.concatenate([d1, d2]))

    return inputs,outputs

ins,outs = getModel()

model = keras.models.Model(inputs=[ins], outputs=[outs])

我没有机会测试,所以语法可能不准确,但这个想法应该可行。

【讨论】:

    【解决方案3】:

    该错误意味着该函数在某处尝试使用列表作为哈希参数。即使用列表作为字典中的键。

    Model(inputs=[input1,input2]) 不能接受列表。

    尝试使用

    np.reshape
    

    首先在 input1 和 input2 上。此外,将列表转换为元组。

    【讨论】:

      猜你喜欢
      • 2021-06-24
      • 1970-01-01
      • 2019-11-17
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2018-02-13
      • 2018-12-23
      相关资源
      最近更新 更多