在 TensorFlow 2 中有效地训练小型神经网络的集合

数据挖掘 神经网络 喀拉斯 张量流 训练 集成建模
2022-03-07 21:46:49

我有一堆小型神经网络(例如,5 到 50 个前馈神经网络,只有两个隐藏层,每个隐藏层有 10-100 个神经元),它们仅在权重初始化方面有所不同。我想在同一个较小的数据集(比如 10K 行)上训练它们,批量大小为 1。这样做的目的是通过平均结果将它们组合成一个集合。

现在,我当然可以在 TensorFlow/Keras 中将整个集成构建为一个神经网络,如下所示:

def bagging_ensemble(inputs: int, width: int, weak_learners: int):
    r'''Return a generic dense network model

    inputs: number of columns (features) in the input data set
    width: number of neurons in the hidden layer of each weak learner
    weak_learners: number of weak learners in the ensemble
    '''
    assert width >= 1, 'width is required to be at least 1'
    assert weak_learners >= 1, 'weak_learners is required to be at least 1'

    activation = tf.keras.activations.tanh
    kernel_initializer = tf.initializers.GlorotUniform()

    input_layer = tf.keras.Input(shape=(inputs,))
    layers = input_layer
    hidden = tf.keras.layers.Dense(units=width, activation=activation, kernel_initializer=kernel_initializer)\
                (input_layer)
    hidden = []
    # add hidden layer as a list of weak learners
    for i in range(weak_learners):
        weak_learner = tf.keras.layers.Dense(units=width, activation=activation, kernel_initializer=kernel_initializer)\
                        (input_layer)
        weak_learner = tf.keras.layers.Dense(units=1, activation=tf.keras.activations.sigmoid)(weak_learner)
        hidden.append(weak_learner)

    output_layer = tf.keras.layers.Average()(hidden)  # add an averaging layer at the end

    return tf.keras.Model(input_layer, output_layer)      

example_model = bagging_ensemble(inputs=30, width=10, weak_learners=5)
tf.keras.utils.plot_model(example_model)

生成的模型图如下所示: Keras 模型图

但是,模型的训练速度很慢,而且由于批量大小为 1,GPU 并不能真正加快这个过程。在 TensorFlow 2 中训练这样的模型时,如何更好地利用 GPU,而不使用更大的批量?

[使用这种集成的动机如下:特别是对于小型数据集,每个小型网络会因为不同的随机初始化而产生不同的结果。通过如此处所示的 bagging,生成的模型的质量大大提高。如果您对这种技术所源自的彻底的神经网络建模方法感兴趣,请查找 HG Zimmermann 的作品。]

1个回答

我对这种方法有疑问,尽管我正在讨论它并且可能是错误的。

想法:你应该在主要任务上训练每个子模型,而不是集成。为此,您可以利用您的 GPU 实际并行计算所有内容(即使使用 5 维输入,一次有效地编码 5 个批次,进一步增强子模型的独立训练)。要做到这一点,我的快速赌注是只有五个独立的输出,所有输出都以 1/5 的权重优化,与用于平均函数的损失相同。然后,在没有进一步优化的情况下进行平均。

动机:模型内部有平均层作为输出层这一事实意味着损失差异也发生在那里。这意味着,在训练期间,您允许单个子网络之间存在相互依赖关系。经过短暂的考虑,应该清楚这并不是你的动机所暗示的:

[使用这种集成的动机如下:特别是对于小型数据集,每个小型网络会因为不同的随机初始化而产生不同的结果。

小型网络不会产生任何东西,因为您没有衡量和优化它们的产量。简而言之,您只是构建了一个更大的模型,连接性稍微复杂一些。