多核神经网络训练

Neural Networks training on multiple cores

本文关键字:神经网络 多核      更新时间:2023-10-16

直击事实。

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

时间、温度、湿度、压力

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

这个数据集大约10MB大,因此在一个核心上训练它需要很长时间。我想用多核训练,但我不明白每个核的训练数据会发生什么,以及核完成工作后到底发生了什么。

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

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

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

  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的数量上呈线性缩放,因此在单个核心上应该是可行的。请注意,这种启发式方法也与极限学习机有一些相似之处。或者,更容易的是,您可以简单地尝试取权重的平均值,见下文。

此外,请看这里的答案。


关于你的问题:

  1. 正如Kris所指出的,它通常是一个迭代。然而,一般来说,它也可以由你选择一个小数字。我会选择1到20之间的选项。请注意,上面的建议使用了无穷大,可以这么说,但随后用更合适的东西替换了重组步骤。

  2. 这一步简单地做它所说的:它汇总了所有的权重和增量(具体取决于你的算法)。请记住,您的目标是最终得到一个经过训练的单一网络,并且使用分裂的数据进行估计。

收集,通常是这样做的:

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

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

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

  • 与其总是使用相同的分割,不如在每个迭代步骤中使用随机分割(…或者在每n次迭代时)。或者,根据随机森林的精神,只使用一个子集。
  • 设置单个线程中的迭代次数(如第1点所述)。上图)。
  • 与其将权重相加,不如使用更高级的重组形式(可能是关于线程内部训练误差的加权,或者像上面那样的最小二乘)。
  • …加上更多的选择,因为在每个复杂的优化…

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

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

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

今天,人工神经网络的前沿库不做多核并行化(见这里的列表)。你可以使用gpu来并行化矩阵运算(例如,使用CUDA),这要快几个数量级。