我有32760个音频频谱,它们的尺寸= 72(#帧)x 40(#频段),我试图将其馈送到“宽”卷积神经网络中(第一层是4个不同conv层的集合) 。这些频谱没有深度,因此可以表示为72 x 40 2D numpy浮点数组,因此输入到分类器的X数组长32760个元素,每个元素都是这些72 x 40 x 1频谱之一。 Y输入是由32760个元素进行一键编码的标签数组。
当尝试使用
拟合CNN时model.fit(mono_X, mono_Y, epochs=10, batch_size=None, verbose=2)
我收到以下错误:
ValueError when checking input: expected input_47 to have 4 dimensions, but got array with shape (32760, 1)
以下是我的CNN的体系结构:
spectra = Input(shape=(72, 40, 1))
# conv1a
c1a = Conv2D(48, (3,5), activation='relu', padding = 'same')(spectra)
c1a = BatchNormalization()(c1a)
c1a = MaxPooling2D(pool_size=(5, 5), strides = 1)(c1a)
# conv1b
c1b = Conv2D(32, (3,9), activation='relu', padding = 'same')(spectra)
c1b = BatchNormalization()(c1b)
c1b = MaxPooling2D(pool_size=(5, 5), strides = 1)(c1b)
# conv1c
c1c = Conv2D(16, (3,15), activation='relu', padding = 'same')(spectra)
c1c = BatchNormalization()(c1c)
c1c = MaxPooling2D(pool_size=(5, 5), strides = 1)(c1c)
# conv1d
c1d = Conv2D(16, (3,21), activation='relu', padding = 'same')(spectra)
c1d = BatchNormalization()(c1d)
c1d = MaxPooling2D(pool_size=(5, 5), strides = 1)(c1d)
# stack the layers
merged = keras.layers.concatenate([c1a, c1b, c1c, c1d], axis=3)
# conv2
c2 = Conv2D(224, (5,5), activation='relu')(merged)
c2 = BatchNormalization()(c2)
c2 = MaxPooling2D(pool_size=(5, 5), strides = 1)(c2)
# output softmax
out = Dense(15, activation='softmax')(c2)
# create Model
model = Model(spectra, out)
# apply optimization and loss function
adam = Adam(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
model.compile(optimizer=adam,
loss='categorical_crossentropy',
metrics=['accuracy'])
但是,如果我尝试将输入形状更改为32760x1,则会收到以下错误消息:
ValueError: Input 0 is incompatible with layer conv2d_203: expected ndim=4, found ndim=3
我在这里做错了什么?有没有更好的方法来表示我的输入数据?我已经尝试过使用pandas DataFrame,其中每一行代表一个光谱以及无数其他组合。 在后端将TensorFlow 1.1.0和Keras 2.1.3与Python 3.6.5结合使用。
这是我的第一个CNN,我以前只使用Keras实现了ANN,所以我可能犯了一个非常明显的错误。任何帮助表示赞赏!
更新!根据@enumaris的建议,在输入层上使用data_format=channels_last
作为参数,并在最后一个Flatten()
和softmax输出层之间添加一个Conv2D
层,以修复后者的值错误。现在,我意识到我的训练数据mono_X
的格式错误。如果我没记错的话,预期的输入形状 应该是(#samples,H,W,#channels)。 mono_X
的形状为(32760),而mono_X[0]
的形状为(72,40)。使用numpy的重塑似乎无法解压缩这些嵌套数组。如何正确准备输入张量?
答案 0 :(得分:0)
输入形状为(72,40,1),但是您说mono_X
的元素具有形状(72,40)。需要重整形,可能是在准备训练数据如mono_X = mono_X.reshape(-1, 72, 40, 1)
时。假设mono_X
是一个形状为numpy的数组(#samples,72、40),但是由于某种原因,听起来像您有一个numpy数组的numpy数组。
您还可以像这样重塑Keras层:
spectra = Input(shape=(72, 40))
spectra = Reshape((72, 40, 1))(spectra)
就个人而言,我会在训练之前进行重塑,而不是在模型中进行重塑,以避免训练上的任何额外开销。