繁体   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