我可以在没有GPU支持的情况下使用Keras的卷积层吗?当我在Colab上使用运行时设置为None时会出现错误。我的代码如下所示:
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_valuey_train = train_labelx_test = test_valuey_test = test_labelprint(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格式。[[{{node training/SGD/gradients/gradients/conv1/conv1d_grad/Conv2DBackpropFilter}}]]
UnimplementedError: Conv2D操作当前在CPU上仅支持NHWC张量格式。操作接收到的格式为:NCHW [[{{node conv1_1/conv1d}}]]
我已经发现问题出在输入数据的格式上。我的输入数据是大小为(1,2048)的向量。您能指导我如何将这些向量转换为NHWC格式吗?如果有人能帮我解决这个问题,我将不胜感激。提前感谢。
回答:
根据Keras文档
data_format: 一个字符串,可以是”channels_last”(默认)或”channels_first”。输入的维度顺序。”channels_last”对应于形状为(batch, steps, channels)的输入(Keras中时间数据的默认格式),而”channels_first”对应于形状为(batch, channels, steps)的输入
现在TensorFlow中的Keras似乎是通过Conv2D
操作来实现Conv1D
的——基本上是形成一个有一行、W
列、然后是您的C
“通道”的“图像”。这就是为什么当您没有图像数据时会收到关于图像形状的错误消息。
在上面的文档中,“channels”指的是每个时间步的数据项数(例如,每个时间步可能有5个传感器读数,那么您就有5个通道)。根据您之前的回答,我认为您传递的张量形状为(n, 1, 2048)
,其中n
是您的批次大小。因此,使用channels_last
,TensorFlow认为这意味着您的批次中有n
个示例,每个示例的序列长度为1
,每个时间步有2048
个数据项——也就是只有一个时间步,每个观察值有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上运行相同的模型。