【问题标题】:Neural Networks training on multiple cores多核神经网络训练
【发布时间】:2014-06-23 12:16:00
【问题描述】:

直截了当。

我的神经网络是经典的前馈反向传播。 我有一个历史数据集,其中包括:

时间、温度、湿度、压力

我需要根据历史数据预测下一个值。

这个数据集大约 10MB 大,因此在一个核心上训练它需要很长时间。我想进行多核训练,但我无法理解每个核心的训练数据会发生什么,以及核心完成工作后究竟会发生什么。

根据:http://en.wikipedia.org/wiki/Backpropagation#Multithreaded_Backpropagation

训练数据被分成同样大的批次,每个批次 线程。每个线程执行前向和后向 传播。对每个的权重和阈值增量求和 线程。在每次迭代结束时,所有线程都必须暂停 简要说明要对权重和阈值增量求和并应用 到神经网络。

  1. '每个线程都执行前向和后向传播' - 这意味着,每个线程只是使用数据集的一部分来训练自己,对吧?每个核心训练多少次迭代?

  2. '在每次迭代结束时,所有线程都必须短暂暂停,以便将权重和阈值增量相加并应用于神经网络' - 这究竟是什么意思?当核心用他们的数据集完成训练时,主程序会做什么?

感谢您对此的任何意见!

【问题讨论】:

  • 可能更适合程序员。stackexchange.com
  • 快速无关的建议:如果你真的想把它推到边缘,你可以使用公司现在正在使用的东西:并行处理能力(即大规模并行处理器)。您可以在 openCL 或 CUDA 上编写自己的神经网络并对其进行快速训练(嗯,相对于幼稚的方法来说足够快)
  • 每个核心有多少次迭代?一。该答案作为第二个问题的一部分给出:“在每个迭代结束时”。合并后,再做一次迭代。

标签: c++ multithreading neural-network


【解决方案1】:

对于多核并行化,考虑将训练数据拆分为线程等是没有意义的。如果您自己实现这些东西,您很可能最终会得到一个比顺序实现慢的并行化实现,因为您复制了您的数据过于频繁。

顺便说一下,在当前的技术状态下,人们通常使用小批量随机梯度下降进行优化。原因是您可以简单地并行前向传播和反向传播小批量样本,但批量梯度下降通常比随机梯度下降慢得多。

那么如何并行化正向传播和反向传播呢?您不必手动创建线程!您可以简单地用矩阵运算写下前向传播并使用并行化的线性代数库(例如Eigen),或者您可以使用 C++ 中的 OpenMP 进行并行化(请参阅例如OpenANN)。

如今,用于 ANN 的前沿库不进行多核并行化(有关列表,请参阅 here)。您可以使用 GPU 来并行化矩阵运算(例如使用 CUDA),这速度要快几个数量级。

【讨论】:

    【解决方案2】:

    通过反向传播完成训练通常不是人们真正想要的,原因是过度拟合。为了获得更好的泛化性能,通常采用权重衰减或提前停止等方法。

    在此背景下,考虑以下启发式方法:将数据拆分为与核心数量相对应的部分,并为每个核心设置一个网络(每个核心都具有相同的拓扑)。训练每个网络与其他网络完全分开(我会使用一些常用参数来表示学习率等)。你最终得到了一些http://www.texify.com/img/%5Cnormalsize%5C%21N_%7B%5Ctext%7B%7D%7D.gif 训练有素的网络http://www.texify.com/img/%5Cnormalsize%5C%21f_i%28x%29.gif

    接下来,您需要一个方案来组合结果。选择http://www.texify.com/img/%5Cnormalsize%5C%21F%28x%29%3D%5Csum_%7Bi%3D1%7D%5EN%5C%2C%20%5Calpha_i%20f_i%28x%29.gif,然后使用最小二乘法调整参数http://www.texify.com/img/%5Cnormalsize%5C%21%5Calpha_i.gif,使http://www.texify.com/img/%5Cnormalsize%5C%21%5Csum_%7Bj%3D1%7D%5EM%20%5C%2C%20%5Cbig%28F%28x_j%29%20-%20y_j%5Cbig%29%5E2.gif 最小化。这涉及奇异值分解,它在测量数量 M 中线性缩放,因此在单个内核上应该是可行的。请注意,这种启发式方法也与极限学习机有一些相似之处。或者,更简单的是,您可以简单地尝试平均权重,见下文。

    此外,请参阅这些答案here


    关于您的问题:

    1. 正如 Kris 所说,它通常是一次迭代。但是,通常它也可以是您选择的一小部分。我会在这里玩大约 1 到 20 之间的选择。请注意,上面的建议使用无穷大,可以说,但随后用更合适的方法替换了重组步骤。

    2. 这一步只是按照它所说的去做:它总结了所有的权重和增量(具体取决于您的算法)。请记住,您最终的目标是一个经过训练的网络,并且使用拆分后的数据进行估计。

    要收集,通常会执行以下操作:

    (i) 在每个线程中,使用您当前的(全局)网络权重通过反向传播来估计增量。然后使用这些增量计算新的权重。

    (ii) 平均这些线程局部权重以获得新的全局权重(或者,您可以对增量求和,但这仅适用于线程中的单个 bp 迭代)。现在从 (i) 重新开始,您在每个线程中使用相同的新计算权重。这样做直到达到收敛。

    这是迭代优化的一种形式。该算法的变体:

    • 不要总是使用相同的拆分,而是在每个迭代步骤(...或每次第 n 次迭代)使用随机拆分。或者,本着随机森林的精神,只使用一个子集。
    • 在单个线程中调整迭代次数(如上文第 1 点所述)。
    • 不要将权重相加,而是使用更高级的重组形式(可能是与线程内部训练误差相关的权重,或上述某种最小二乘法)。
    • ...以及在每个复杂优化中的更多选择...

    【讨论】:

    • 谢谢大卫,我会试一试 - 听起来很明智。
    猜你喜欢
    • 2011-04-07
    • 1970-01-01
    • 2010-11-20
    • 2019-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-25
    相关资源
    最近更新 更多