Caffe内存不足,用在哪里?
Posted
技术标签:
【中文标题】Caffe内存不足,用在哪里?【英文标题】:Caffe out of memory, where is it used? 【发布时间】:2019-07-23 15:28:45 【问题描述】:我正在尝试在 Caffe 中训练一个网络,这是一个稍作修改的 SegNet-basic
模型。
我了解我收到的 Check failed: error == cudaSuccess (2 vs. 0) out of memory
错误是由于我的 GPU 内存不足。然而,让我感到困惑的是:
我的“旧”训练尝试效果很好。网络初始化并运行,如下:
批量大小 4Memory required for data: 1800929300
(这个是在batch size中计算的,所以这里是4x
sample size)
参数总数:1418176
网络由 4x(卷积、ReLU、池化)和 4x(上采样、反卷积)组成;每层有 64 个过滤器,内核大小为 7x7
。
令我惊讶的是,我的“新”网络内存不足,而且我不明白是什么保留了额外的内存,因为我降低了批量大小:
批量大小 1Memory required for data: 1175184180
(= 样本量)
参数总数:1618944
输入大小沿每个维度加倍(预期输出大小不变),因此参数数量增加的原因是网络开始时增加了一组(卷积、ReLU、池化)。
参数个数由this script统计,逐层参数相加,乘以每一层的维数。
假设每个参数需要 4 个字节的内存,与新的 memory_new = 1181659956 = 1.10GB
相比,旧设置 memory_old = 1806602004 = 1.68GB
的内存要求仍然更高。
我已经接受了某个地方可能需要额外的内存,并且如果我找不到具有更多内存的 GPU,我将不得不重新考虑我的新设置并对输入进行缩减采样,但是我真的在尝试了解哪里需要额外的内存以及为什么我的新设置内存不足。
编辑:根据请求,以下是每个网络的层尺寸以及通过它的数据大小:
“旧”网络:
Top shape: 4 4 384 512 (3145728)
('conv1', (64, 4, 7, 7)) --> 4 64 384 512 (50331648)
('conv1_bn', (1, 64, 1, 1)) --> 4 64 384 512 (50331648)
('conv2', (64, 64, 7, 7)) --> 4 64 192 256 (12582912)
('conv2_bn', (1, 64, 1, 1)) --> 4 64 192 256 (12582912)
('conv3', (64, 64, 7, 7)) --> 4 64 96 128 (3145728)
('conv3_bn', (1, 64, 1, 1)) --> 4 64 96 128 (3145728)
('conv4', (64, 64, 7, 7)) --> 4 64 48 64 (786432)
('conv4_bn', (1, 64, 1, 1)) --> 4 64 48 64 (786432)
('conv_decode4', (64, 64, 7, 7)) --> 4 64 48 64 (786432)
('conv_decode4_bn', (1, 64, 1, 1)) --> 4 64 48 64 (786432)
('conv_decode3', (64, 64, 7, 7)) --> 4 64 96 128 (3145728)
('conv_decode3_bn', (1, 64, 1, 1)) --> 4 64 96 128 (3145728)
('conv_decode2', (64, 64, 7, 7)) --> 4 64 192 256 (12582912)
('conv_decode2_bn', (1, 64, 1, 1)) --> 4 64 192 256 (12582912)
('conv_decode1', (64, 64, 7, 7)) --> 4 64 384 512 (50331648)
('conv_decode1_bn', (1, 64, 1, 1)) --> 4 64 384 512 (50331648)
('conv_classifier', (3, 64, 1, 1))
对于“新”网络,顶部几层不同,其余层完全相同,只是批量大小为 1 而不是 4:
Top shape: 1 4 769 1025 (3152900)
('conv0', (64, 4, 7, 7)) --> 1 4 769 1025 (3152900)
('conv0_bn', (1, 64, 1, 1)) --> 1 64 769 1025 (50446400)
('conv1', (64, 4, 7, 7)) --> 1 64 384 512 (12582912)
('conv1_bn', (1, 64, 1, 1)) --> 1 64 384 512 (12582912)
('conv2', (64, 64, 7, 7)) --> 1 64 192 256 (3145728)
('conv2_bn', (1, 64, 1, 1)) --> 1 64 192 256 (3145728)
('conv3', (64, 64, 7, 7)) --> 1 64 96 128 (786432)
('conv3_bn', (1, 64, 1, 1)) --> 1 64 96 128 (786432)
('conv4', (64, 64, 7, 7)) --> 1 64 48 64 (196608)
('conv4_bn', (1, 64, 1, 1)) --> 1 64 48 64 (196608)
('conv_decode4', (64, 64, 7, 7)) --> 1 64 48 64 (196608)
('conv_decode4_bn', (1, 64, 1, 1)) --> 1 64 48 64 (196608)
('conv_decode3', (64, 64, 7, 7)) --> 1 64 96 128 (786432)
('conv_decode3_bn', (1, 64, 1, 1)) --> 1 64 96 128 (786432)
('conv_decode2', (64, 64, 7, 7)) --> 1 64 192 256 (3145728)
('conv_decode2_bn', (1, 64, 1, 1)) --> 1 64 192 256 (3145728)
('conv_decode1', (64, 64, 7, 7)) --> 1 64 384 512 (12582912)
('conv_decode1_bn', (1, 64, 1, 1)) --> 1 64 384 512 (12582912)
('conv_classifier', (3, 64, 1, 1))
这会跳过池化层和上采样层。这是“新”网络的train.prototxt
。旧网络没有层conv0
、conv0_bn
和pool0
,而其他层相同。 “旧”网络还将 batch_size
设置为 4
而不是 1
。
EDIT2:根据请求,更多信息:
所有输入数据具有相同的维度。它是 4 个通道的堆栈,每个通道的大小为769x1025
,因此始终为 4x769x1025
输入。
caffe 训练日志是here:如你所见,我在网络初始化后得到out of memory
。没有一次迭代运行。
我的 GPU 有 8GB 内存,而我刚刚发现(在另一台机器上尝试)这个新网络需要 9.5GB 的 GPU 内存。
只是重申一下,我试图了解我的“旧”设置如何适合 8GB 内存而“新”设置不适合,以及为什么额外数据所需的内存量是 ~比保存输入所需的内存大 8 倍。然而,既然我已经确认“新”设置只需要 9.5GB,它可能没有我想象的“旧”设置那么大(不幸的是,GPU 目前正在被其他人使用,所以我不能检查旧设置到底需要多少内存)
【问题讨论】:
输入和特征图的大小也决定了内存的使用,而不仅仅是参数的数量。您应该共享两个模型的完整架构。 @MatiasValdenegro 我已经用输入和特征图的大小更新了问题。我是否还应该通过 pastebin 或类似的方式分享描述架构的 prototxt? 能否附上你的 Caffe 日志? 1.所有训练图像的大小/分辨率是否相同? 2. 您是在训练开始时还是在一段时间后“失忆”?验证时? 3. 你用的是什么求解器?新元?亚当? 4. 你的 GPU 有多少内存? 【参考方案1】:请记住,caffe 实际上为网络的 两个 副本分配空间:“训练阶段”网络和“测试阶段”网络。因此,如果数据占用 1.1GB,则需要将该空间翻倍。 此外,您需要为参数分配空间。每个参数都需要存储其梯度。此外,求解器跟踪每个参数的“动量”(有时甚至是第二个矩,例如在 ADAM 求解器中)。因此,即使是少量增加参数的数量也会导致训练系统的内存占用显着增加。
【讨论】:
我猜每个参数所需的额外空间是最可能的解释。但是,你能澄清一下存储网络的训练和测试阶段的网络吗?我觉得这很令人困惑,至于培训,我只将train.prototxt
(或者更确切地说,solver.prototxt
仅指向 train
)传递给 caffe;在培训完全完成之前,不会使用或读取任何指向任何测试文件的文件,并且我开始运行我的测试和评估程序。
@penelope 查看日志文件:您会看到 caffe 构建网络两次,一次用于训练,一次用于评估,也就是 phase: TEST
。以上是关于Caffe内存不足,用在哪里?的主要内容,如果未能解决你的问题,请参考以下文章
在 R Studio 中,我的 Java 内存不足(对于 RWeka)