[英]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.