首页 文章

具有Keras的卷积神经网络输入形状

提问于
浏览
0

我有32760音频频谱计算尺寸= 72(#帧)×40(#频段),我试图进入“宽”卷积神经网络(第一层是4个不同的转换层的集合) . 这些光谱没有深度,因此它们可以表示为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,其中每一行代表一个光谱和无数其他组合 . 在后端使用带有Keras 2.1.3的Python 3.6.5和TensorFlow 1.1.0 .

这是我的第一个CNN,我之前只使用了Keras实现了ANN,所以我可能会犯一个非常明显的错误 . 任何帮助赞赏!


更新!根据@enumaris的建议,在输入层使用 data_format=channels_last 作为参数,并在最后 Conv2D 和softmax输出层之间添加 Flatten() 层,修复了后一个值错误 . 现在我逐渐意识到我的训练数据 mono_X 形状错误 . 如果我没有弄错的话,预期的输入形状应该是(#samples,H,W,#channels) . mono_X 具有形状(32760,),而 mono_X[0] 具有形状(72,40) . 使用numpy 's reshape doesn'似乎能够解压缩这些嵌套数组 . 如何正确准备输入张量?

1 回答

  • 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)
    

    就个人而言,我会在训练之前重塑,而不是在模型中,以避免任何额外的培训开销 .

相关问题