2

我正在尝试在 Keras 中使用 BatchNorm。训练的准确性会随着时间的推移而增加。从 12% 到 20%,缓慢而坚定。然而,测试准确度从 12% 下降到 0%。随机基线为 12%。

我非常认为这是由于 batchnorm 层(删除 batchnorm 层导致 ~12% 的测试准确度),这可能没有很好地初始化参数 gamma 和 beta。应用 batchnorm 时我需要注意什么特别之处吗?我真的不明白还有什么可能出了问题。我有以下模型:

模型=顺序()

model.add(BatchNormalization(input_shape=(16, 8)))
model.add(Reshape((16, 8, 1)))

#1. Conv (64 filters; 3x3 kernel)
model.add(default_Conv2D())
model.add(BatchNormalization(axis=3))
model.add(Activation('relu'))

#2. Conv (64 filters; 3x3 kernel)
model.add(default_Conv2D())
model.add(BatchNormalization(axis=3))
model.add(Activation('relu'))

... 

#8. Affine (NUM_GESTURES units) Output layer
model.add(default_Dense(NUM_GESTURES))
model.add(Activation('softmax'))


sgd = optimizers.SGD(lr=0.1)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

default_Conv2D 和 default_Dense 定义如下:

def default_Conv2D():
    return Conv2D(
        filters=64,
        kernel_size=3,
        strides=1,
        padding='same',
        # activation=None,
        # use_bias=True,
        # kernel_initializer=RandomNormal(mean=0.0, stddev=0.01, seed=None), #RandomUniform(),
        kernel_regularizer=regularizers.l2(0.0001),
        # bias_initializer=RandomNormal(mean=0.0, stddev=0.01, seed=None), # RandomUniform(),
        # bias_regularizer=None
    )

def default_Dense(units):

    return Dense(
        units=units,
        # activation=None,
        # use_bias=True,
        # kernel_initializer=RandomNormal(mean=0.0, stddev=0.01, seed=None),#RandomUniform(),
        # bias_initializer=RandomNormal(mean=0.0, stddev=0.01, seed=None),#RandomUniform(),
        kernel_regularizer=regularizers.l2(0.0001),
        # bias_regularizer=None
    )
4

2 回答 2

4

问题是过拟合

您的前 2 个观察结果支持这一点:

  1. 训练的准确性会随着时间的推移而增加。从 12% 到 20%,.. 测试准确度从 12% 下降到 0%
  2. 移除 batchnorm 层会导致 ~12% 的测试准确度

第一条语句告诉我你的网络正在记忆训练集。第二条语句告诉我,当您阻止网络记住训练集(甚至学习)时,它就会停止与记忆有关的错误。

过拟合有一些解决方案,但问题比这篇文章大。请将以下列表视为“顶级”列表,而不是详尽无遗:

  • 在最终的全连接层之前添加一个像Dropout这样的正则化器。
  • 在矩阵权重上添加 L1 或 L2 正则化器
  • 在 CONV 之间添加一个像Dropout这样的正则化器
  • 您的网络可能有太多的自由参数。尝试将层数减少到只有 1 个 CONV,然后一次再添加一层,每次重新训练和测试。

准确性缓慢提高

作为旁注,您暗示说您的准确性并没有像您希望的那样快速增加,缓慢但肯定地说。当我完成以下所有步骤时,我取得了巨大的成功

  • 将您的损失函数更改为小批量中所有项目的所有预测的平均损失。这使您的损失函数独立于您的批量大小,您会发现如果您更改批量大小并且您的损失函数随之更改,那么您将不得不以 SGD 更改学习率。
  • 你的损失是一个单一的数字,它是所有预测类和所有样本的损失的平均值,所以使用 1.0 的学习率。不再需要扩展它。
  • 使用tf.train.MomentumOptimizer,learning_rate = 1.0 且动量 = 0.5。MomentumOptimizer 已被证明比 GradientDescent更健壮。
于 2017-05-10T13:56:51.677 回答
0

似乎 Keras 本身出了点问题。

一个天真的

pip install git+git://github.com/fchollet/keras.git --upgrade --no-deps

成功了。

@wontonimo,非常感谢您的出色回答!

于 2017-05-11T08:30:48.117 回答