可以训练神经网络以平滑值/输出平均值吗?

数据挖掘 神经网络 回归 噪音
2021-10-06 17:27:15

假设我们有一个具有一个输入神经元和一个输出神经元的神经网络。训练数据(x,f(x))由进程生成

f(x)=ax+N(b,c)

a,b,cR+,例如类似的东西

feature  | target
-----------------
0             0.0
0             1.0
0             1.5
0            -1.2
0            -0.9
...

我知道神经网络可以很好地处理分类问题中的标签错误。这意味着如果您有一个大型数据集并且几个示例的标签错误,它们基本上会被忽略。

但是对于这种问题我不太确定。第一个实验表明它们可以平滑值。

架构/训练中是否有有助于平滑/平均/去除噪声的选择?

我试过的

我创建了一个可以在没有噪音的情况下解决这种回归问题的网络。它的 MSE 约为0.0005. 当我只向训练集添加一点噪音时,我得到的 MSE 为0.001

#!/usr/bin/env python

# core modules
import random

# 3rd party modules
from keras.models import Sequential
from keras.layers import Dense
from sklearn.model_selection import train_test_split
import numpy as np


def main(add_noise=True):
    # Get data
    xs, ys = create_data_points(10000)
    x_train, x_test, y_train, y_test = train_test_split(xs, ys, test_size=0.20)

    # Add noise to training data
    if add_noise:
        noise = np.random.normal(0, 0.1, len(x_train))
        x_train = x_train + noise

    # Create model
    model = create_model()
    model.compile(optimizer='rmsprop',
                  loss='mse',
                  metrics=['mse'])

    # Fit model to data.
    model.fit(x_train, y_train, epochs=10, batch_size=32, verbose=1)

    # Evaluate
    y_pred = model.predict(x_test, batch_size=100).flatten()
    print("MSE on test set:")
    print(((y_pred - y_test)**2).sum() / len(y_test))


def create_data_points(nb_points):
    xs = []
    ys = []
    for i in range(nb_points):
        x = random.random()
        xs.append(x)
        ys.append(2 * x)
    return np.array(xs), np.array(ys)


def create_model(input_dim=1, output_dim=1):
    model = Sequential()
    model.add(Dense(200, input_dim=input_dim, activation='relu'))
    model.add(Dense(200, input_dim=input_dim, activation='relu'))
    model.add(Dense(output_dim, activation='linear'))
    return model


if __name__ == '__main__':
    main()

异常值

在这个问题的早期版本中,当我的意思是“标签噪音”时,我写了“异常值”。对于异常值,有:

2个回答

通常,更简单的模型对输入中的噪声更加鲁棒。神经网络的优势也是它们最大的“陷阱”——它们极具表现力。这意味着它们很容易过拟合并且可能对输入中的噪声敏感。简化模型以使其对噪声更加鲁棒的策略称为正则化。有很多类型:

  • 使用较小的隐藏层(即 20 而不是 200 个节点)
  • 使用 dropout,其中在训练期间输入随机设置为 0(使网络整体对噪声更加鲁棒)
  • 早点停止训练——“早点停止”
  • 使用 L1 或 L2 正则化,这会对权重施加成本

所有这些都可以通过 Keras 完成。您希望在不降低验证质量的情况下使您的网络对噪声更加健壮。为此,我会按顺序尝试上述建议。您可以通过查看训练数据和验证数据的预测准确性之间的差异来衡量过度拟合。如果它们非常不同 - 您的模型在您的训练数据中学习了不在您的验证中的结构,这不是您想要的。尝试调整正则化 nob,直到(1)您的训练验证 AUC 或准确性非常相似,(2)您的验证 AUC/准确性仍然足够高。

我知道神经网络可以很好地处理异常值。

不必要。

这取决于您的损失函数和样本量。

在线性回归中,损失函数是 MSE。MSE 对异常值不稳健,因此线性回归对异常值不稳健。拥有更大的样本将减轻异常值的影响。

同样的原则也适用于神经网络。

架构/训练中是否有有助于平滑/平均/去除噪声的选择?

这只是过度拟合的问题。

@tom 涵盖了最常用的技术。我唯一要补充的是使用更大的样本量。有时这可以通过使用数据增强技术(即图像旋转等)廉价地实现。