繁体   English   中英

Keras 功能 api 多输入:传递给 model 的输入列表是冗余的

[英]Keras functional api multiple input: The list of inputs passed to the model is redundant

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

---> 20 model = keras.models.Model(输入=[输入1,输入2],输出=输出)

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

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

1621 # 检查输入中的冗余。

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

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

1624'是多余的。 '

类型错误:不可散列类型:“列表”

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

#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:

层(类型)Output Shape Param # Connected to


输入令牌(InputLayer)(无,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-密集(密集)(无,768)590592 提取物[0][0]

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

这是一个例子:

#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])

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

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

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

测试它们是否是带有isinstance(inputs1, list)

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

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

尝试使用

np.reshape

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

暂无
暂无

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

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