2017-07-31 134 views
2

我想用Keras訓練一批訓練數據的多輸入NN,但我無法將一組輸入和輸出樣本傳遞給在模型上執行擬合train_on_batch培訓多輸入Keras NN與批處理訓練數據

我NN被定義爲以下:

i1 = keras.layers.Input(shape=(2,)) 
    i2 = keras.layers.Input(shape=(2,)) 
    i3 = keras.layers.Input(shape=(2,)) 
    i_layer = keras.layers.Dense(2, activation='sigmoid') 
    embedded_i1 = i_layer(i1) 
    embedded_i2 = i_layer(i2) 
    embedded_i3 = i_layer(i3) 

    middle_concatenation = keras.layers.concatenate([embedded_i1, embedded_i2, embedded_i3], axis=1) 

    out = keras.layers.Dense(1, activation='sigmoid')(middle_concatenation) 

    model = keras.models.Model(inputs=[i1, i2, i3], outputs=out) 
    model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy']) 

例如,輸入(成功地用於預測的輸出)的一個實例如下:

[array([[0.1, 0.2]]), array([[0.3, 0.5]]), array([[0.1, 0.3]])]

但是,當我嘗試訓練我的模型:

inputs = [[np.array([[0.1, 0.2]]), np.array([[0.3, 0.5]]), np.array([[0.1, 0.3]])], 
        [np.array([[0.2, 0.1]]), np.array([[0.5, 0.3]]), np.array([[0.3, 0.1]])] 
         ] 
    outputs = np.ones(len(inputs)) 
    model.fit(inputs, outputs) 

我收到此錯誤:

ValueError: Error when checking model input: you are passing a list as input to your model, but the model expects a list of 3 Numpy arrays instead. The list you passed was: [[array([[ 0.1, 0.2]]), array([[ 0.3, 0.5]]), array([[ 0.1, 0.3]])], [array([[ 0.2, 0.1]]), array([[ 0.5, 0.3]]), array([[ 0.3, 0.1]])]] 

我在做什麼錯?
如何使用一批輸入/輸出樣本來訓練多輸入NN?

謝謝!

+0

我想你可能想看看[合併](https:// keras。io/layers/merge /)圖層,並將三個獨立的分支凝聚到一個組合網絡中,否則將您的輸入合併爲一個 – DJK

+0

@ djk47463感謝您的提示!我需要三個輸入來分享他們的權重。因此,我構建了圖層'i_layer',將每個輸入添加到此圖層,然後連接此圖層的三個輸出以構建NN的其餘部分。 注:我只是刪除了一些內部圖層,以簡化代碼。 無論如何,你知道如何解決列車問題嗎? –

+0

對不起我放棄了代碼快,沒有意識到你已經在做 – DJK

回答

1

問題只是格式不正確。你可以不通過列表keras,僅numpy的陣列,所以當你有你的數據結構類似於

inputs = [[np.array([[0.1, 0.2]]), np.array([[0.3, 0.5]]), np.array([[0.1, 0.3]])], 
        [np.array([[0.2, 0.1]]), np.array([[0.5, 0.3]]), np.array([[0.3, 0.1]])] 
         ] 

你需要一個列表元素傳遞到你的模型在同一時間。您還需要一次將一個輸出值傳遞給模型。要做到這一點,結構,你outputs這樣

outputs = [np.ones(1) for x in inputs] 

[array([ 1.]), array([ 1.])] 

然後你可以遍歷這樣

for z in range(0,len(inputs)): 
    model.fit(inputs[z],outputs[z],batch_size=1) 

的擬合函數,你也可以用model.train_on_batch()而不是取代model.fit,看到docs

然而,爲了避免循環,你可以在你的inputs列表中存儲3個numpy數組,並將你單個的outputs作爲一個numpy數組。如果您只想一次進行單批次培訓,則可以設置批量大小來完成此操作。

inputs = [np.array([[0.1, 0.2],[0.2, 0.1]]), np.array([[0.3, 0.5],[0.5, 0.3]]), np.array([[0.1, 0.3],[0.3, 0.1]])] 

outputs = np.ones(inputs[0].shape[0]) 

model.fit(inputs,outputs,batch_size=1) 
1

現在的問題是,你現在使用列表作爲輸入,雖然keras需要一個數組列表。

你需要轉換你的列表中,這樣它看起來像[array_inputs_1, array_inputs_2, array_inputs_3],其中每個輸入數組是輸入數組,你會通過該模型,如果它有隻輸入層,你只要把他們的3名單內。

使用你的數據正確的輸入應該是:

[np.array([[0.1, 0.2], [0.2, 0.1]]), 
np.array([[0.3, 0.5], [0.5, 0.3]]), 
np.array([[0.1, 0.3], [0.1, 0.3]])] 

這樣一來,只要所有3個輸入數組有相同數量的元素,keras會知道如何艾德里安分成批次。

+0

謝謝@gionni。 你是完全正確的。現在它工作了! –