簡體   English   中英

Training Multiple Input and Output Keras Model (ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type list))

[英]Training Multiple Input and Output Keras Model (ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type list))

我有六個不同Sequnstial Keras 模型,我希望將它們連接起來,如下所示:

楷模

activation = 'tanh'
model1 = Sequential()
model1.add(Dense(3, input_dim=3, activation=activation))
model1.add(Dense(3, activation=activation))
model1.add(Dense(1))

model2 = Sequential()
model2.add(Dense(3, input_dim=3, activation=activation))
model2.add(Dense(3, activation=activation))
model2.add(Dense(1))

model3 = Sequential()
model3.add(Dense(1, input_dim=1, activation=activation))
model3.add(Dense(1, activation=activation))
model3.add(Dense(1))

model4 = Sequential()
model4.add(Dense(6, input_dim=6, activation=activation))
model4.add(Dense(3, activation=activation))
model4.add(Dense(1))

model5 = Sequential()
model5.add(Dense(2, input_dim=2, activation=activation))
model5.add(Dense(2, activation=activation))
model5.add(Dense(1))

model6 = Sequential()
model6.add(Dense(6, input_dim=6, activation=activation))
model6.add(Dense(4, activation=activation))
model6.add(Dense(1))

級聯

model_concat = concatenate([model1.output, model2.output, model3.output, model4.output, model5.output, model6.output])

composed_model = Model(
    inputs=[model1.input, model2.input, model3.input, model4.input, model5.input, model6.input],
    outputs=model_concat
)
composed_model.compile(optimizer=SGD(lr=0.001), loss='mse')

所有型號的output尺寸均為1,但型號的輸入尺寸不同。 上面的代碼將完全運行,沒有任何錯誤。

現在,問題在於訓練 model。 我將嘗試運行以下代碼,用一個數據實例訓練 model(每個子數組的維度等於相應模型的輸入維度):

x_input = [[[-50.0, -50.0, 10.0], [-10.0, -20.0, 30.0], \
            [20.0], [10.0, 10.0, 10.0, 10.0, 10.0, 10.0], [50.0, 50.0],\
            [10.0, 10.0, 10.0, 10.0, 10.0, 10.0]]]

y_output = [[1.0, 1.0, 1.0, 1.0,1.0,1.0]]
composed_model.fit(x_input, y_output)

但是,我有以下錯誤:

ValueError:無法將 NumPy 數組轉換為張量(不支持的 object 類型列表)。

我找到了一個相關的帖子,但它並沒有解決我的問題。

據我所知,我們不能將所有可變大小的輸入一起傳遞以fit多輸入 model。 將訓練對傳遞給 model 的方式,它肯定無法解包關注輸入層。 您提到的相關帖子也是需要考慮的重要事實。

但是,在tensorflow中,我們可以將tf.ragged.RaggedTensor用於可變長度輸入序列,在此處討論。 但不確定是否可以通過轉換為參差不齊的張量來解決任何問題。 如果單個輸入層采用不同長度的輸入序列,這可能是可能的。

如果您閱讀fit 方法的訓練對輸入,您會看到keras期望x參數如下:

Arguments

x: Input data. It could be:
    1. A Numpy array (or array-like), or a list of arrays (in case the model 
       has multiple inputs).
    2. A TensorFlow tensor, or a list of tensors (in case the model 
       has multiple inputs).
    3. A dict mapping input names to the corresponding array/tensors, 
       if the model has named inputs.
...
...

對於您的情況,選項 3 的選擇非常方便,它將字典映射的輸入名稱與訓練對一起傳遞。 這是我們可以做到這一點的一種方法。 首先為每個model的輸入層設置一些名稱。 我們設置model1model2 ,...等。

from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense 

activation = 'tanh'
model1 = Sequential()
model1.add(Dense(3, input_dim=3, activation=activation, name='model1'))
model1.add(Dense(3, activation=activation))
model1.add(Dense(1))

model2 = Sequential()
model2.add(Dense(3, input_dim=3, activation=activation, name='model2'))
model2.add(Dense(3, activation=activation))
model2.add(Dense(1))

model3 = Sequential()
model3.add(Dense(1, input_dim=1, activation=activation, name='model3'))
model3.add(Dense(1, activation=activation))
model3.add(Dense(1))

model4 = Sequential()
model4.add(Dense(6, input_dim=6, activation=activation, name='model4'))
model4.add(Dense(3, activation=activation))
model4.add(Dense(1))

model5 = Sequential()
model5.add(Dense(2, input_dim=2, activation=activation, name='model5'))
model5.add(Dense(2, activation=activation))
model5.add(Dense(1))

model6 = Sequential()
model6.add(Dense(6, input_dim=6, activation=activation, name='model6'))
model6.add(Dense(4, activation=activation))
model6.add(Dense(1))

現在,構建最終的 model ,我們還設置了最后一層名稱,這里設置為target_concatenate

import tensorflow as tf 

model_concat = tf.keras.layers.concatenate(
    [
     model1.output, model2.output, model3.output, 
     model4.output, model5.output, model6.output
    ], name='target_concatenate')

composed_model = tf.keras.Model(
    inputs=[model1.input, model2.input, model3.input, 
            model4.input, model5.input, model6.input],
    outputs=model_concat
)
composed_model.compile(optimizer='sgd', loss='mse')

數據集

您提供的樣本數據對於我們上面提到的 model 訓練是不合法的。 首先它不應該是一個list ,而是numpy ,其次,對於多輸入可變大小,分別傳遞它們很方便。

import numpy as np 

# Six Inputs 
one = np.random.randint(-50, 10, size=(1, 3))
two = np.random.randint(-10, 30, size=(1, 3))
thr = np.random.randint(20, size=(1))
fur = np.random.randint(10, size=(1, 6))
fiv = np.random.randint(50, size=(1,2))
six = np.random.randint(10, size=(1, 6))

# One Target
tar = np.random.randint(2, size=(1, 6))

print(one, one.shape)
print(two, two.shape)
print(thr, thr.shape)
print(fur, fur.shape)
print(fiv, fiv.shape)
print(six, six.shape)
print(tar, tar.shape)

[[-42   9 -34]] (1, 3)
[[28 22  7]] (1, 3)
[19] (1,)
[[4 4 1 7 4 7]] (1, 6)
[[40 35]] (1, 2)
[[3 6 1 1 3 8]] (1, 6)
[[0 0 1 1 0 0]] (1, 6)

當我們調用.fit時,我們會將這些數據集作為 dict 映射模型的輸入和 output 名稱傳遞給相應的數組。 因此,讓我們檢查一下組合 model 的名稱。

# viewing the model shapes and layers name 
# tf.keras.utils.plot_model(composed_model, 
#                            show_shapes=True, show_layer_names=True)
composed_model.input_names, composed_model.output_names

(['model1_input',
  'model2_input',
  'model3_input',
  'model4_input',
  'model5_input',
  'model6_input'],
 ['target_concatenate'])

太好了,現在我們可以很方便地通過訓練 Paris 到fit方法了。

composed_model.fit(
    {
         "model1_input": one, "model2_input": two, "model3_input": thr,
         "model4_input": fur, "model5_input": fiv, "model6_input": six
     },
     {
         "target_concatenate": tar
     },
    epochs=10,
    batch_size=32,
    verbose=2
)
Epoch 1/10
496ms/step - loss: 0.6022
Epoch 2/10
5ms/step - loss: 0.5428
Epoch 3/10
7ms/step - loss: 0.4888
Epoch 4/10
16ms/step - loss: 0.4426
Epoch 5/10
8ms/step - loss: 0.4041
Epoch 6/10
8ms/step - loss: 0.3719
Epoch 7/10
9ms/step - loss: 0.3448
Epoch 8/10
5ms/step - loss: 0.3215
Epoch 9/10
7ms/step - loss: 0.3011
Epoch 10/10
5ms/step - loss: 0.2830

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM