优化 CNN 网络

数据挖掘 Python 喀拉斯 回归 卷积神经网络 音频识别
2021-10-11 21:24:56

我目前正在尝试重新创建本文的结果,其中他们从 log-melfilter 能量的“频谱图”中进行特征提取..

在此处输入图像描述

由于论文没有说明我正在寻找什么样的特征,我目前正在尝试提取特征,并将它们与 MFCC 特征相匹配。该论文阐述了一种称为LWS(有限权重共享)的技术,其中频谱图频率轴将被划分为多个部分,并且每个部分不与其他部分共享它们的权重。

因此,我将输入图像分为 13 个部分,以从 (6,3,3) 输入图像中接收 1 个输出特征。6 为行数,每列 3 表示给定日志 melfilter energi 的 [static delta delta_delta] 数据,最后 3 为颜色通道。

如果我使用了 13 个滤波器组并制作了绘图,那么结果是否会是每个 (1,3,3) 矩阵都会产生一个特征,但这似乎有点好得令人难以置信,所以我决定使用 78 个滤波器组并将其分为 13 个部分,这应该会导致可以从大小为 (6,3,3) 的矩阵中提取一个特征

我正在使用这种模型结构训练网络:

def create_model(init_mode='normal',activation_mode='softsign',optimizer_mode="Adamax", activation_mode_conv = 'softsign'):
    model = Sequential()


    model.add(ZeroPadding2D((6,4),input_shape=(6,3,3)))
    model.add(Convolution2D(32,3,3 , activation=activation_mode_conv))
    print model.output_shape
    model.add(Convolution2D(32, 3,3, activation=activation_mode_conv))
    print model.output_shape
    model.add(MaxPooling2D(pool_size=(2,2),strides=(2,1)))
    print model.output_shape
    model.add(Convolution2D(64, 3,3 , activation=activation_mode_conv))
    print model.output_shape
    model.add(Convolution2D(64, 3,3 , activation=activation_mode_conv))
    print model.output_shape
    model.add(MaxPooling2D(pool_size=(2,2),strides=(2,1)))
    model.add(Flatten())
    print model.output_shape
    model.add(Dense(output_dim=32, input_dim=64, init=init_mode,activation=activation_mode))
    model.add(Dense(output_dim=13, input_dim=50, init=init_mode,activation=activation_mode))
    model.add(Dense(output_dim=1, input_dim=13, init=init_mode,activation=activation_mode))
    model.add(Dense(output_dim=1,  init=init_mode, activation=activation_mode))
    #print model.summary()
    model.compile(loss='mean_squared_error',optimizer=optimizer_mode)

    return model

由于某种原因,这个模型一直给我带来非常糟糕的结果。我似乎一直在损失 216,这几乎是数据范围的 3 倍......

我做了一个网格搜索来找出哪个参数(激活函数、init_mode、epochs 和 batch_size 最好,它们是在上面的函数中选择的(尽管结果没有太大变化..)

我该怎么做才能获得更好的结果?CNN 网络设计不好?

2个回答

我给出的一个建议是改变 CNN 的层级。您有 3 个 CNN 层,所有层都按顺序添加,作用于相同的形状,并以相同的滤波器大小输出相同的输出形状。

您可以尝试更改过滤器尺寸并使用多种过滤器尺寸来捕捉不同尺寸的不同特征。为此,试试这个模型:

main_input = Input(shape=input_shape, name="main input")
flattened_outputs = []
for i in filter_sizes:
    conv_filter_i = Convolution1D(no_of_filters, i, border_mode='same', activation='relu', W_constraint=maxnorm(3))(main_input)
    pooling_i = MaxPooling1D(pool_length=2)(conv_filter_i)
    flattened_i = Flatten()(pooling_i)
    flattened_outputs.append(flattened_i)
merged_conv_outputs = merge(flattened_outputs, mode="concat")
softmax = Dense(output_shape, activation="softmax")(merged_conv_outputs)
model = Model(input=main_input, output=softmax)
model.compile(loss='mean_squared_error',optimizer=optimizer_mode)

注意:根据需要更改尺寸。

  1. 除此之外,我建议您使用Dropout图层。
  2. 根据我的个人经验,它有很大帮助。另外,一定要使用亚当优化器。
  3. 尝试各种池化机制。请记住,必须进行大量实验,因此也要尝试各种其他参数和过滤器尺寸。

有一些我认为可以提高 CNN 性能的建议:

  1. 输入大小为 (6, 3),因此不宜使用MaxPooling层。
  2. padding = 'same'在所有输出与输入相同维度的卷积图像的卷积层中使用。
  3. 使用ReluorLeakyRelu作为激活函数。
  4. 使用Adam optimizer和调整学习率。
  5. 按照 sh37211 的建议将一些Dense图层转换为1x1 Convolution with no. of filters = no. of units in dense layer

例如

no_of_filters = [32, 64, 64, 32]
kernel_size = [3, 3, 3, 1]

input = Input(shape = (6,3,3), name = "input")
layer_output = [input]
for i in range(4):
    convolution = Convolution2D(no_of_filters[i], kernel_size[i], kernel_size[i], padding = 'same')(layer_output[-1])
    activation = LeakyReLU()(convolution)
    layer_output.append(activation)

flatten = Flatten()(layer_output[-1])
flatten_dropout = Dropout(0.5)(flatten)
fc = Dense(output_dim = 13)
activation = LeakyReLU()(fc)
layer_output.append(activation)
fc = Dense(output_dim = 1, activation = 'tanh')

model.compile(loss = 'mean_squared_error',optimizer = 'adam')