首页 > 解决方案 > 在 CPU 上使用卷积层时出错

问题描述

我可以在没有 gpu 支持的情况下使用 keras 的卷积层吗?当我在运行时为 None 的 Colab 上使用它时出现错误。我的代码如下所示:

model = tf.keras.Sequential()
model.add(layers.Conv1D(1,5, name='conv1', padding="same", activation='relu',data_format="channels_first", input_shape=(1,2048)))
# model.add(layers.LSTM(5, activation='tanh'))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(num_classes, activation='softmax'))
#model.summary()
model.compile(loss=tf.keras.losses.categorical_crossentropy,
              optimizer=tf.keras.optimizers.SGD(lr=0.001, momentum=0.9),
              metrics=['accuracy'])

x_train = train_value
y_train = train_label
x_test = test_value
y_test = test_label
print(np.shape(x_train)) #shape of x train is (4459, 1, 2048)
print(np.shape(x_test)) #shape of test is (1340,1,2048)

history = model.fit(x_train, y_train,
          batch_size=100,
          epochs=30, 
          verbose=1,
          validation_data=(x_test, y_test)

          )

它在 GPU 上运行良好,但在 CPU 上出现以下错误:

InvalidArgumentError:Conv2DCustomBackpropFilterOp 仅支持 NHWC。[[{{节点训练/SGD/gradients/gradients/conv1/conv1d_grad/Conv2DBackpropFilter}}]]

UnimplementedError:Conv2D 运算目前仅支持 CPU 上的 NHWC 张量格式。该操作的格式为:NCHW [[{{node conv1_1/conv1d}}]]

我发现问题出在输入数据的格式上。我的输入数据是大小为 (1,2048) 的向量。您能否指导我如何将这些向量转换为 NHWC 格式?如果有人可以为我解决这个问题,我将不胜感激。提前致谢。

标签: pythontensorflowmachine-learningkeras

解决方案


根据Keras 文档

data_format:一个字符串,“channels_last”(默认)或“channels_first”之一。输入中维度的排序。“channels_last”对应于形状为(batch、steps、channels)的输入(Keras 中时间数据的默认格式),而“channels_first”对应于形状为(batch、channels、steps)的输入

现在 TensorFlow 中的 Keras 似乎是Conv1D根据Conv2D操作符来实现的——基本上形成一个“图像”,其中包含 1 行、W列,然后是C“通道”。这就是当您没有图像数据时会收到有关图像形状的错误消息的原因。

在上面的文档中,“通道”是每个时间步长的数据项数(例如,您可能在每个时间步长有 5 个传感器读数,因此您有 5 个通道)。从您上面的答案中,我相信您传递的张量形状(n, 1, 2048)n您的批量大小。因此,channels_lastTensorFlow 认为这意味着您n的批次中有示例,每个示例的序列长度12048每个时间步的数据项 - 这只是一个时间步,每次观察有 2048 个数据项(例如,在每个时间步获取 2048 个传感器读数)在这种情况下,卷积不会进行卷积 - 它相当于将所有 2048 个数字作为输入的单个密集层。

我认为实际上每个时间步只有一个数据项,并且有 2048 个时间步。这就解释了为什么传递channels_first可以提高您的准确性 - 现在 TensorFlow 了解您的数据代表 1 个数据项样本 2048 次,并且它可以对该数据进行卷积。

要修复,您可以tf.reshape(t, (1, 2048, 1))- 并删除channels_first(该代码假设您正在执行大小为 1 的批次,并且您的张量名为t)。现在它的格式(n, s, 1)n批量大小(1此处),s时间步数(2048),并1表示每个时间步一个数据点。您现在可以在 GPU 或 CPU 上运行相同的模型。


推荐阅读