如何确保神经网络学习的特征不相关?

数据挖掘 神经网络 训练 相关性
2021-10-06 15:49:27

神经网络的每一层都学习输入数据的特征。第一层学习低级特征(例如图像中的边缘)。每个后续层都学习更多抽象特征。然后将来自最后一个隐藏层的特征组合起来进行分类或回归。

在此处输入图像描述

如何确保神经网络学习的特征不相关?

我认为我可以强制神经网络通过以下方式学习相关特征。去掉输出层,让最后一个隐藏层产生n输出。然后训练这个网络n目标变量不是独立的,而是两个或三个独立目标的线性组合(可能添加了一些噪声以避免真正的线性相关性)。由于神经网络是通用逼近器,因此应该可以训练这样的网络。然而,在这种情况下,最后一层中的所有神经元都将是冗余的,除了对应于线性独立目标的两个或三个神经元。

这种冗余可以存在于每一层中。如何避免?当然,我可以在训练后检查神经元输出的相关性,删除相关的神经元,然后重新训练网络,但它看起来效率低下。如何让网络从一开始就学习不相关的特征?

我想到的是为层内的每个神经元使用不同且独立(例如正交)的激活函数。有这样的网络吗?通常,激活函数被认为是相同的。

编辑:我试图测试辍学是否会使学习的特征相关性降低。我没有发现它确实如此(或者我以错误的方式做这件事?)。

这是我尝试过的一个玩具问题: y=a2+b2 在哪里 ab 均匀分布在 0 和 1 之间。

a_train = np.random.uniform(low=0.0, high=1.0, size=10000)
b_train = np.random.uniform(low=0.0, high=1.0, size=10000)
y_train = a_train**2 + b_train**2
X_train = np.hstack([a_train[:,np.newaxis], b_train[:,np.newaxis]])

输入特征不相关。

np.corrcoef(X_train[:,0], X_train[:,1])[0,1]

0.002136928470247475

神经网络:

model = keras.Sequential(
    [
        layers.Dense(32, activation="tanh", name="layer1", input_dim=2),
        layers.Dense(16, activation="tanh", name="layer2"),
        layers.Dense(2, activation="tanh", name="feature_layer"),
        layers.Dense(1, name="out_layer"),
    ]
)
optimizer = tf.keras.optimizers.RMSprop(learning_rate=0.001)

model.compile(loss='mean_squared_error',
                optimizer=optimizer,
                metrics=['mean_squared_error'])

model.fit(X_train, y_train, epochs=100, batch_size=128, validation_split = 0.2, verbose=1)

feature_extractor = keras.Model(
    inputs=model.inputs,
    outputs=model.get_layer(name="feature_layer").output,
)

features=feature_extractor(X_train).numpy()

倒数第二层的输出之间的相关性:

np.corrcoef(features[:,0], features[:,1])[1,0]

-0.7527464552820806

添加dropout后,

model = keras.Sequential(
    [
        layers.Dense(32, activation="tanh", name="layer1", input_dim=2),
        layers.Dropout(0.2),
        layers.Dense(16, activation="tanh", name="layer2"),
        layers.Dropout(0.2),
        layers.Dense(2, activation="tanh", name="feature_layer"),
        layers.Dense(1, name="out_layer"),
    ]
)
model.summary()

相关性变为

-0.8645152290698691
1个回答

Dropout(2014 年论文)是我的第一个想法。

通过在每次通过数据时有效地删除 N% 的神经元,您可以使任何两个神经元更难协同工作。当它的伙伴消失时,它被迫寻找另一种方法来学习数据中的模式。下一个纪元,当它的老朋友回来时,它对生活有了新的看法,视野也开阔了,重新进入那种依存关系的可能性更小了。

第二个想法是 L2 正则化:它迫使网络不仅仅依赖于一层中的一个神经元,而是让它们都参与进来。

如果您不相信,请尝试一下。尝试创建一个网络,例如,最后一层中只有两个神经元携带所有信号。然后使用 50% 的 dropout 或更高的 L2 值重新训练它。总体而言,它可能是一个较弱的模型,但不让所有神经元分担负载真的很难。(也可以尝试有无偏见,如下所述。)

层内每个神经元的不同且独立的激活函数。有这样的网络吗?

如果你发现什么,我很想听听。我想您可能会争辩说,偏差是在每个神经元上创建一个独特的激活函数,尽管我认为您建议在某些神经元中使用 ReLU,而在其他神经元中使用 tanh?(有效实施有点棘手?)

从您的问题中删除了一点,但是多头注意力中的不同头(在 Transformer 模型中)是将多个不同的“激活函数”放入一个层的另一个示例。