【问题标题】:Convolutional Neural Network Memory Usage卷积神经网络内存使用
【发布时间】:2019-01-13 17:09:01
【问题描述】:

我正在实施一个 CNN。假设有 1000000 个训练示例,我的其中一个层的尺寸为 20x30x30。

现在假设我必须计算这些示例的训练准确度。然后,在前向传播中,我需要为该层存储 1000000x20x30x30 = 180 亿个值,这会占用太多内存。另一方面,如果我分别对每个训练示例进行前向传播,则会花费太长时间。

我只是想知道如何解决这个问题?

非常感谢您所做的一切!

【问题讨论】:

  • 欢迎来到计算的核心困境:时间-内存权衡。在这种情况下,改善一个通常意味着牺牲另一个;改进它的最佳方法是找到一种完全独立的方法,该方法具有更好的平衡,或者提高其中一个组件的效率。不知道这里是否可能,不过,我只是想我会插话。
  • 需要更多关于您的框架、代码、设置等的详细信息,但通常您应该将训练示例拆分为 batches - 您绝对不想初始化 1000000x20x30x30 张量在您使用的任何框架中。更改批量大小通常会在时间和内存之间进行权衡 - 一次输入更多图像可以让您的神经网络框架进行更多不间断的计算,但代价是需要在内存中存储更多图像和中间层。
  • 我尝试将训练示例分成多个批次,效果更好,感谢您的帮助!不过我想知道,为什么一次输入更多图像比在每个训练示例上运行前向传播效率要高得多?为什么不间断的计算会产生如此巨大的差异?因为最后,计算是一样的。再次感谢您!

标签: python machine-learning deep-learning computer-vision conv-neural-network


【解决方案1】:

您在这里遇到的问题通常通过批处理来解决(如 cmets 中所述)。
无需通过所有训练示例,您只需对数据点的一个子集进行采样,然后在仅查看这几个示例后更新您的权重。
与普通的“梯度下降”(GD)相比,它的名称是“随机梯度下降”(SGD)。随机性来自使用 随机子样本(通常是 2 的某个幂,即 4、8、16、32,...)。 现在,我们不再简单地进行迭代,而是在 epoch(通过所有训练数据)和简单迭代(仅使用 batch_size 元素)之间进行区分

这也回答了您在 cmets 中提出的部分问题(“为什么一次提供更多图像更有效?”): 由于您在每批之后更新权重(因此必须通过网络计算反向传播),因此需要更长的时间才能到达下一个前向传递。

一般来说,SGD 也是首选,以获得更好的收敛性。在实践中,与采取一大步相比,采用许多较小的步骤可能会产生更好的结果。如需更多参考,请参阅this great lecture 中的最后几张幻灯片。

由于您担心它需要很长时间:具有合适批量大小的 SGD(我个人什至不会超过每批次 2^10 个样本;一些论文“设定了大约 128 个样本的标准”)可以获得你很快就会有好的结果/收敛。你牺牲了单次迭代的速度来获得更快的收敛速度。

【讨论】:

    猜你喜欢
    • 2021-03-30
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-20
    • 2023-03-14
    • 2020-11-01
    • 2017-10-31
    相关资源
    最近更新 更多