簡體   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