无法将 NumPy 数组转换为张量(不支持的对象类型 numpy.ndarray) - 已将数据转换为 numpy 数组

Sar*_*kar 3 python arrays numpy neural-network tensorflow

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

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)
Run Code Online (Sandbox Code Playgroud)

收到错误为:

ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type numpy.ndarray).
Run Code Online (Sandbox Code Playgroud)

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'>
Run Code Online (Sandbox Code Playgroud)

小智 7

存在三个问题


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

x_train = np.array([np.array(val) for val in x_train])
Run Code Online (Sandbox Code Playgroud)

Problem2
Dense层期望你的输入具有形状(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'))
Run Code Online (Sandbox Code Playgroud)

或者等效地,直接提供 input_shape

model.add(Dense(20, input_shape=(400, 300), kernel_initializer='he_uniform', activation='relu'))
Run Code Online (Sandbox Code Playgroud)

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

注意:如果层的输入的秩大于 2,则 沿 的最后一个轴和 的轴 1 计算和 Dense 之间的点积(使用)。例如,如果输入具有维度,那么我们创建一个形状,并且沿着 的轴 2对形状的每个子张量 (存在这样的子张量)进行操作。这种情况下的输出将具有形状。inputskernelinputskerneltf.tensordot(batch_size, d0, d1)kernel(d1, units)kernelinput(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)
Run Code Online (Sandbox Code Playgroud)

现在输出将是 (462, 9)