【问题标题】:Failed to convert a NumPy array to a Tensor (Unsupported object type numpy.ndarray) - Already have converted the data to numpy array无法将 NumPy 数组转换为张量(不支持的对象类型 numpy.ndarray) - 已经将数据转换为 numpy 数组
【发布时间】:2021-10-11 19:06:00
【问题描述】:

尝试为基于文本的多标签分类问题训练单层神经网络。

model= Sequential()
model.add(Dense(20, input_dim=400, kernel_initializer='he_uniform', activation='relu'))
model.add(Dense(9, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam')

model.fit(x_train, y_train, verbose=0, epochs=100)

得到错误:

ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type numpy.ndarray).

x_train 是一个 300 维 word2vec 矢量化文本数据,每个实例填充到 400 长度。包含462条记录。

对训练数据的观察如下:

print('#### Shape of input numpy array #####')
print(x_train.shape)
print('#### Shape of each element in the array #####')
print(x_train[0].shape)
print('#### Object type for input data #####')
print(type(x_train))
print('##### Object type for first element of input data ####')
print(type(x_train[0]))

#### Shape of input numpy array #####
(462,)
#### Shape of each element in the array #####
(400, 300)
#### Object type for input data #####
<class 'numpy.ndarray'>
##### Object type for first element of input data ####
<class 'numpy.ndarray'>

【问题讨论】:

  • 我打赌x_traindtypeobject。这通常是从形状不同的数组列表中创建一个数组的结果。您显示第一个元素的形状。但这是所有 462 的形状吗? np.stack(x_train) 是做什么的?
  • print(type(x)) 通常不是很有用。 print(x.dtype) 提供更多信息。如果dtypeobject,那么它包含对象,例如其他数组。如果float 是一个数字数组,可能tensorflow 可以使用。
  • @hpaulj 是的,dtype 是对象。

标签: python arrays numpy tensorflow neural-network


【解决方案1】:

三个问题


问题1
这是你的主要问题,直接导致了错误
你如何初始化/转换你的 x_train 有问题(我认为这是一个错误,或者你使用了一些不寻常的方式来构造你的数据),现在你的 x_train 实际上是一个数组数组,而不是一个多维数组。所以TensorFlow“认为”你有一个根据它的形状的一维数组,这不是你想要的。 解决方案是在发送到 fit() 之前重构数组:

x_train = np.array([np.array(val) for val in x_train])

问题2
密集层希望您的输入具有形状 (batch_size, ..., input_dim),这意味着您的 x_train 的最后一个维度必须等于 input_dim,但您有 300,这与 400 不同。
根据你的描述,你的输入维度,也就是词向量维度是300,所以你应该把input_dim改成300:

model.add(Dense(20, input_dim=300, kernel_initializer='he_uniform', activation='relu'))

或者等效地,直接提供 input_shape 代替

model.add(Dense(20, input_shape=(400, 300), kernel_initializer='he_uniform', activation='relu'))

问题3
因为密集,又名线性层,是用于“线性”输入的,所以它期望它的每个数据都是一维向量,所以输入通常像(batch_size,vector_length)。当dense接收到一个维度> 2(你有3个维度)的输入时,它将对最后一个维度执行Dense操作。引用自 TensorFlow 官方文档:

注意:如果层的输入的秩大于 2,则 Dense 计算 inputskernel 沿 inputs 的最后一个轴和 kernel(使用tf.tensordot)。 例如,如果输入的维度为(batch_size, d0, d1),那么我们 创建一个形状为(d1, units)kernel,然后kernel 运行 沿 input 的轴 2,在形状 (1, 1, d1) 的每个子张量上 (有batch_size * d0 这样的子张量)。在这个输出 案例的形状为(batch_size, d0, units)

这意味着您的 y 应该改为 (462, 400, 9) 形状。这很可能不是您正在寻找的(如果这确实是您正在寻找的,问题 1 和 2 中的代码应该已经解决了您的问题)。

如果您要在整个 400x300 矩阵上执行密集,则需要先展平为一维向量,如下所示:

x_train = np.array([np.array(val) for val in x_train])  # reconstruct
model= Sequential()
model.add(Flatten(input_shape=(400, 300)))
model.add(Dense(20, kernel_initializer='he_uniform', activation='relu'))
model.add(Dense(9, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam')

model.fit(x_train, y_train, verbose=0, epochs=100)

现在输出将是 (462, 9)

【讨论】:

    猜你喜欢
    • 2020-07-05
    • 2021-04-18
    • 2021-04-25
    • 2022-01-10
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 2021-09-20
    • 2020-11-22
    相关资源
    最近更新 更多