【问题标题】:How to tell if my neural network is crashing due to memory errors?如何判断我的神经网络是否由于内存错误而崩溃?
【发布时间】:2017-09-30 07:49:22
【问题描述】:

我正在尝试围绕一台笔记本电脑训练神经网络的能力来校准我的期望。我正在使用 tensorflow 和 keras,大约 10 分钟后,它崩溃了。我见过killsignal 9 exit code 137,我想知道这是不是因为内存不足?其他时候,当使用np_utils.to_categorical() 进行单热编码时,我在控制台中看到了memoryerror 字样,仅此而已,我的脚本崩溃了。这只是试图将输出转换为神经网络在运行之前所期望的。 我有 6400 个输入和 1500 个输出以及一个包含 100 个节点的小型隐藏层。批量大小 128。 而已。它甚至不深。无论使用 nvidia gpu 还是 4 核 cpu,它都会崩溃。对于专业人士来说,我的网络是否太大而无法在我的系统上进行训练(i7 4 核,16gb 内存,nvidia GT 750m,计算能力 3.0)。我的神经网络算大吗?顺便说一句,我有 300 万个样本。

1) 如何估算我的网络所需的内存量?是6400 (# inputs) * 1500 (#outputs) * 4 bytes (per parameter) = 38.4 gb吗?我可以在某处的Mac上实时查看正在使用多少内存吗?我用过活动监视器,内存压力表正常。 2) GPU 通常最大内存为 8gb-12gb,而台式机上的 CPU 可以轻松拥有 64gb。那么如果我的网络的内存需求超过 8gb 的 RAM,就不可能在单个 GPU 上进行训练吗? 3)batch_size 和batch_training 之间有什么区别,尤其是内存方面的区别? 谢谢!

【问题讨论】:

  • 可能问题出在“300 万个样本”中。为什么不将其拆分为较小的批次,例如“100.000 个样本”,即使使用fit 时,仍然传递一个小的batch_size,也许是200。
  • 评估网络的内存需求并非易事。作为一个粗略的指导,查看你的张量形状,查看变量类型,并将形状乘以类型的内存需求,然后将所有内容相加。例如,如果您定义了一个 6400 个单位的输入层、100 个隐藏层和 1500 个输出层,并且假设它们都是tf.float64,那么您的最小内存需求(不考虑权重、偏差和所有开销)将为 (64 * 6400 + 100 * 64 + 1500 * 64) * batch_size。如果您一次将所有 300 万个样本输入其中,那么这将达到大约 1.4GB。
  • 也就是说,可能还有很多其他事情正在发生,查看您的模型代码可能会有所帮助。
  • 您好,您能详细介绍一下您的计算吗?我必须在将位转换为 GB 时遇到问题。大多数批处理大小只有 128,但您是说即使我将批处理大小设置为 3,000,000,总内存也是 1.4 GB,这是任何笔记本电脑都应该能够处理的非常小的内存。
  • 根据我的计算,每个样本您将使用6400 * 100 + 100 * 1500 = 790000 * 4 = 3160000 / 1000000 = 3.16 MB(不考虑偏差,但这可以忽略不计)。我认为您的 GPU 内存是 2 GB。这意味着每批最多可以容纳 590 个样本。你的批量大小比这个大吗?你也有验证吗?如果是,您是在 fit 内还是在某个回调内计算它?如果是,您还必须将验证批次大小添加到 590 个样本中。同样根据您的描述,您的 CPU RAM 用完了(也许)。所以可能你想一次考虑一大块样本。

标签: tensorflow deep-learning keras


【解决方案1】:

您的乘法计算是正确的,但您处理的是兆字节而不是千兆字节。实际要求是 6400*100*4 + 100*1500*4,如果使用默认的 float32,则应该约为 4 MB。您将两个后续层的层大小相乘,因为每个神经元都连接到后续层中的每个神经元。然后将整个内存需求乘以批量大小。这就是为什么使用卷积层来训练深度网络的原因。

对于 gpu,我使用 nvidia-smi 来监控 linux 上的内存需求。谷歌搜索给了我这个 mac:https://phvu.net/2015/03/30/nvidia-smi-on-macos/。如果内存要求超过 GPU 内存,则无法在 gpu 上进行训练。你可以在 cpu 上训练它,但这需要很长时间。

有多种方法可以使用大型训练集进行训练。通常生成器用于批量训练。这意味着只加载您实际需要的训练集部分 (https://keras.io/getting-started/faq/#how-can-i-use-keras-with-datasets-that-dont-fit-in-memory)。

【讨论】:

  • 非常感谢。所以较小的 batch_size 并不能消除分块加载大于 RAM 的数据集的需要?无论我的 batch_size 是什么,整个数据集是否都会被加载?如果是这样,batch_size 有什么帮助?
  • 取决于您的算法。如果您事先加载整个数据集,则无济于事。如果您使用生成器,您通常只预先加载样本的批量大小。因此,如果您可以发布您的培训代码会有所帮助。
【解决方案2】:

确定神经网络的内存需求不仅取决于网络的大小或参数本身的数量。为了计算神经网络的内存足迹,我经常去的一个文档是Stanford CS231n Convolutional Neural Networks for Visual Recognition 课程笔记。请查看他们找到网络每一层的内存要求的部分。

此外,批次大小(每批次的输入数量)是决定“内存使用量”的关键因素。例如,在较新的 NVIDIA P100 GPU 中,如果我训练 CIFAR10 模型,我每批最多可以处理 2048 张图像,如果我在 ImageNet 数据集上训练 AlexNet,我可以少于 512 或 256 张图像。输入大小很重要,批处理大小也很重要,因为 GPU 内存需要考虑输入的批处理。

测试批处理大小的一种方法是执行nvidia-smi 并查看使用了多少内存。因为时不时做这件事很无聊,所以我通常在我的 Linux 机器上做watch nvidia-smi。在我的 MAC 中,我没有安装 NVIDIA GPU,所以我很少使用这些技巧。如果需要,我会编写如下的快速 bash 脚本:

while true; do nvidia-smi; sleep 0.5; clear; done

您也可以在 Mac 中移植安装 watch

此外,我最喜欢的两个工具是htopdstat

htop 为 Linux 中著名的top 命令提供了更好的图形界面。它为您提供有关内存和处理器使用情况以及不同进程的实时信息。如果您授予sudo 访问htop 的权限,您可以直接从界面更改niceness 和其他参数。

dstat 为您提供有关 I/O 的实时信息。在大多数情况下,我会添加两个标志 -d-n 来仅指定磁盘和网络使用情况。

幸运的是,htop 可以通过运行在 Mac 上 brew 安装:

brew install htop

另一方面,dstat 不能直接使用。请查看ifstatiostat 以获得类似功能。

Mac 中htop 命令的截图。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    • 2023-03-03
    • 1970-01-01
    • 2015-04-02
    • 2011-07-24
    相关资源
    最近更新 更多