Keras 过度装配、过度训练或结构不正确

Keras 过度装配、过度训练或结构不正确,keras,conv-neural-network,Keras,Conv Neural Network,我有一个6*32的技术数据数组,看起来像“射线”,连接了六行中的部分或全部的局部最大值,并以某种角度颠倒: 1: 100 (102) 97 98 127 120 121 2: 88 87 (91) 90 88 88 88 3: 101 100 101 100 101 100 100 4: 99 97 97 98 (99) 98 97 5: ... 6: ... 我的基本想法是使用CNN网络,因为目前运营商以视觉方式检测这些模式,而且在

我有一个6*32的技术数据数组,看起来像“射线”,连接了六行中的部分或全部的局部最大值,并以某种角度颠倒:

1:     100 (102) 97  98 127 120 121
2:      88  87  (91) 90  88  88  88
3:     101 100  101 100 101 100 100
4:      99  97   97  98 (99) 98  97
5: ...
6: ...
我的基本想法是使用CNN网络,因为目前运营商以视觉方式检测这些模式,而且在与文本或照片对象识别进行比较时,这个问题似乎并不太困难。我使用Keras和以下体系结构可以获得最佳结果。不幸的是,只有在训练中

model = keras.Sequential([
    keras.layers.BatchNormalization(input_shape=( 6, 32, 1)),

    keras.layers.Conv2D(filters=32, kernel_size=2, activation='tanh', padding="same"),
    keras.layers.Conv2D(filters=32, kernel_size=2, activation='tanh', padding="same"),
    keras.layers.MaxPooling2D(2),
    keras.layers.Conv2D(filters=16, kernel_size=3, activation='tanh', padding="same"),
    keras.layers.Conv2D(filters=16, kernel_size=3, activation='tanh', padding="same"),
    keras.layers.MaxPooling2D(2),
    keras.layers.Conv2D(filters=8, kernel_size=4, activation='tanh', padding="same"),
    keras.layers.Conv2D(filters=8, kernel_size=4, activation='tanh', padding="same"),

    keras.layers.GlobalAveragePooling2D(),
    keras.layers.Dense(8096, activation=tf.nn.tanh),
    keras.layers.Dropout(0.6),
    keras.layers.Dense(8096, activation=tf.nn.relu),
    keras.layers.Dropout(0.6),

    keras.layers.Dense(1, activation=tf.nn.sigmoid)
    ])
汇编:

model.compile(optimizer=keras.optimizers.RMSprop(), 
          loss='binary_crossentropy',
          metrics=['accuracy'])
培训:

model.fit(train_data, train_labels, epochs=200, batch_size=128)
在训练中,它会损失~0.1667精度~0.9480
在测试时,准确率仅为61%。

很可能存在过拟合问题,因此需要在训练期间增加正则化

首先(根据经验,您应该始终这样做),通过向每个层添加以下参数,在权重大小上添加正则化:

kernel_regularizer=keras.regularizers.l2(w_reg)
因此,您的每个层应如下所示:

keras.layers.Conv2D(filters=32,
                    kernel_size=2,
                    activation='tanh',
                    padding="same",
                    kernel_regularizer=keras.regularizers.l2(w_reg))
其他观察结果:

我认为您的模型对于输入的大小来说太宽了,因此很容易记住训练数据和过度拟合。您使用的密集层有8096个神经元,用于192个变量的输入和单个输出。在我看来,这是一种过度杀伤力,你应该将神经元的大小减少到几百个。如果我错了,你会发现你的训练精度没有达到90年代的更高水平,你可以随时添加回神经元

我注意到您正在对输入使用批标准化。在标准情况下,这是不做的。您应该规范化您的输入,但通常在模型之外执行,方法是减去训练集的平均值,然后除以每个样本中训练集的方差(是的,所有样本,包括测试集和任何未来样本的样本,都使用训练集的平均值和方差进行规范化)


我还注意到,您在模型中使用了两种不同的激活函数(不包括输出上的sigmoid),这是故意的还是可能是错误的

谢谢你的回复。关于不同的激活函数,首先是relu,但我发现tanh越快,精确度越高。但最后一层应该有relu。我错了吗?关于标准化,由于硬件故障,一些输入数组可能包含异常的过高或过低值。使用标准化,我试图消除它们的影响,以估计w_reg?我添加了w_reg=0.01的规则化,并将神经元数量减少到512个。现在精度从第二个纪元到200个纪元止于0.6169。当从密集层中移除正则化时,精度会提高,但速度较慢。第一条注释:最后一层不应具有ReLu,在您的情况下,输出需要为0到1之间的单个数字,然后可以四舍五入到最接近的值以获得分类。因此,sigmoid是适用于您的模型的正确激活函数。(在你的脚本中也是这样,ReLU在前最后一层,你在最后一层稠密(1)中得到了sigmoid)