![](/img/trans.png)
[英]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的輸入層設置一些名稱。 我們設置model1
, model2
,...等。
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.