我正在使用 Sigmoid 神经元构建一个神经网络。我当前的网络是 3 层,每层有 39 个节点,使用 10,000 个观测值的 39 个输入变量的输入。
我通过对每个观察中的损失求和来计算损失。话虽如此,我必须用数字计算使用反向传播从输出神经元开始并向后工作的代码的每次迭代在网络中的权重增量。这需要很长时间。
有没有更有效的方法来处理反向传播?
我正在使用 Sigmoid 神经元构建一个神经网络。我当前的网络是 3 层,每层有 39 个节点,使用 10,000 个观测值的 39 个输入变量的输入。
我通过对每个观察中的损失求和来计算损失。话虽如此,我必须用数字计算使用反向传播从输出神经元开始并向后工作的代码的每次迭代在网络中的权重增量。这需要很长时间。
有没有更有效的方法来处理反向传播?
为了使这个问题可以回答,我必须假设您已经正确实现了反向传播。也就是说,就基础数学而言,步骤顺序正确,没有任何不必要的重复,并且使用正确的公式计算值。
您可以通过对权重实施梯度检查来检查梯度值是否正确,通常您通过随机测试用例(任何网络架构、随机权重、输入和目标值)来执行此操作,运行反向传播代码以获取梯度,然后对于每个权重依次向前运行网络,测量误差,然后将权重调整一个非常小的增量,再次测量误差并使用误差差来估计梯度。如果估计和您的反向传播在所有权重上大致一致,那么您的反向传播代码可能是正确的。如果您打算只为 NN 实现实现一个单元测试,那么这就是要做的。
要直接解决这个问题:“有没有更有效的方法来处理反向传播?”,答案很复杂。
基本答案是“不”。您绝对必须进行反向传播中涉及的所有计算,没有捷径可走。
但是,大多数神经网络框架的性能都会比您的实现好得多,您在其中给出了一个网络示例,该网络[39,39,39,1]对 10,000 个示例进行了层训练,并且需要 28 分钟来处理一个 epoch。
由于您没有链接您的实现,因此无法准确找出差异是什么。但是,忽略错误的可能性,可能会应用以下内容:
避免使用解释语言中的循环计算结果。如果您正在循环遍历神经元或权重索引以将多个值组合在一起并以高级语言存储回数组中,那么这可能非常低效。如果您根据矩阵和向量操作来构建神经网络过程(前向和反向传播),大多数框架都利用了快速循环和并行化。这有时被称为vectorizaton,大多数框架将其拆分,以便向量和矩阵操作是黑盒例程,在低级语言(如 C)中非常注重优化,同时传递结果并决定做什么使用它们可以用 Python 或 Matlab 等高级语言完成。
小批量。您必须为网络看到的每个示例处理前向和反向传播。但是您不必为每个示例应用权重更新。事实证明,每这么多示例只应用一次更新不仅在计算方面更有效,而且对收敛也有好处。通过 GPU 支持大量并行处理的框架也可以通过批量工作大大提高性能。
您不太可能有时间在资源更好的公共框架已经拥有的范围内探索优化。但是,通过利用语言中内置的向量化选项,您可以走得更远——例如使用 Matlab 中的矩阵运算或 Python 中的 Numpy 功能。这可能是值得的,因此您可以继续研究和理解神经网络模型中的低级细节。但是,在某些时候,如果您想解决实际问题而不是自己的 NN 库,您会发现自己很自然地切换到第三方库,因为优化问题和许多有用的附加功能已经为您解决了。