TensorFlow 对象检测 API 被杀死 - OOM。如何减少洗牌缓冲区的大小?

Posted

技术标签:

【中文标题】TensorFlow 对象检测 API 被杀死 - OOM。如何减少洗牌缓冲区的大小?【英文标题】:Tensorflow object detection API killed - OOM. How to reduce shuffle buffer size? 【发布时间】:2018-11-28 11:14:24 【问题描述】:

系统信息

操作系统平台和发行版:CentOS 7.5.1804 TensorFlow 安装自:pip install tensorflow-gpu TensorFlow 版本:tensorflow-gpu 1.8.0 CUDA/cuDNN 版本:9.0/7.1.2 GPU 型号和内存:GeForce GTX 1080 Ti,11264MB

复制的确切命令

python train.py --logtostderr --train_dir=./models/train --pipeline_config_path=mask_rcnn_inception_v2_coco.config

描述问题

我正在尝试在我自己的数据集上训练一个 Mask-RCNN 模型(从一个在 COCO 上训练的模型进行微调),但是一旦 shuffle 缓冲区被填满,这个过程就会被终止。

在此之前,nvidia-smi 显示内存使用量约为 10669MB/11175MB,但 GPU 使用率仅为 1%。

我已尝试调整以下 train_config 设置:

batch_size: 1    
batch_queue_capacity: 10    
num_batch_queue_threads: 4    
prefetch_queue_capacity: 5

对于 train_input_reader:

num_readers: 1
queue_capacity: 10
min_after_dequeue: 5

我相信我的问题类似于 TensorFlow Object Detection API - Out of Memory,但我使用的是 GPU 而不是 CPU。

我正在训练的图像相对较大 (2048*2048),但是我想避免缩小尺寸,因为要检测的对象非常小。我的训练集包含 400 张图像(在 .tfrecord 文件中)。

有没有办法减少 shuffle 缓冲区的大小,看看这是否会减少内存需求?

追溯

INFO:tensorflow:Restoring parameters from ./models/train/model.ckpt-0
INFO:tensorflow:Restoring parameters from ./models/train/model.ckpt-0
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Starting Session.
INFO:tensorflow:Starting Session.
INFO:tensorflow:Saving checkpoint to path ./models/train/model.ckpt
INFO:tensorflow:Saving checkpoint to path ./models/train/model.ckpt
INFO:tensorflow:Starting Queues.
INFO:tensorflow:Starting Queues.
INFO:tensorflow:global_step/sec: 0
INFO:tensorflow:global_step/sec: 0
2018-06-19 12:21:33.487840: I tensorflow/core/kernels/data/shuffle_dataset_op.cc:94] Filling up shuffle buffer (this may take a while): 97 of 2048
2018-06-19 12:21:43.547326: I tensorflow/core/kernels/data/shuffle_dataset_op.cc:94] Filling up shuffle buffer (this may take a while): 231 of 2048
2018-06-19 12:21:53.470634: I tensorflow/core/kernels/data/shuffle_dataset_op.cc:94] Filling up shuffle buffer (this may take a while): 381 of 2048
2018-06-19 12:21:57.030494: I tensorflow/core/kernels/data/shuffle_dataset_op.cc:129] Shuffle buffer filled.
Killed

【问题讨论】:

shuffle.buffer 位于以 RAM 为边界的 CPU 上(但存在交换)。你的输入对于训练来说太大了。一个像样的 GPU 在训练期间可以处理的最大尺寸是 1300 x 1300。GPU 利用率不是您的问题。 谢谢。将配置中的 max_dimension 参数从 1365 减少到 900 解决了 OOM 问题。但是,GPU 利用率仍显示为 0%(或个位数)。这肯定不是预期的行为吗? 您真的希望得到答案而不显示任何相关代码吗? 我正在使用与上面相同的命令来运行 train.py 文件来训练我的模型,一旦缓冲区被填满,它就不再被杀死。但是,在训练期间,nvidia-smi 显示 GPU-Util 为 0%,而内存使用量为 11680MiB / 12212MiB。 【参考方案1】:

您可以尝试以下步骤:

1.设置batch_size=1(或自己尝试)

2.更改"default value": optional uint32 shuffle_buffer_size = 11 [default = 256](或尝试自己的) 代码在这里

models/research/object_detection/protos/input_reader.proto

Line 40 in ce03903

 optional uint32 shuffle_buffer_size = 11 [default = 2048];

原始设置是:

optional uint32 shuffle_buffer_size = 11 [default = 2048]

默认值是2048,对于batch_size=1来说太大了,应该做相应的修改,我认为它消耗了很多内存。

3.重新编译Protobuf库

来自 tensorflow/models/research/

protoc object_detection/protos/*.proto --python_out=.

【讨论】:

我也遇到了这个问题。你建议我把optional uint32 shuffle_buffer_size = 11 [default = 2048]改成什么? optional uint32 shuffle_buffer_size = 11 [default = 2048]改为optional uint32 shuffle_buffer_size = 11 [default = 256],如果256不能满足要求,可以修改。【参考方案2】:

在您的 pipeline.config 中,添加

shuffle_buffer_size: 200

或根据您的系统。

train_input_reader 
  shuffle_buffer_size: 200
  label_map_path: "tfrecords/label_map.pbtxt"
  tf_record_input_reader 
    input_path: "tfrecords/train.record"
  

它对我有用,也在 tf1 和 tf2 上测试过。

【讨论】:

【参考方案3】:

我将 flow_from_directory 更改为 flow_from_dataframe 函数。因为它不会将所有图像的矩阵值上传到内存中。

【讨论】:

以上是关于TensorFlow 对象检测 API 被杀死 - OOM。如何减少洗牌缓冲区的大小?的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow 对象检测 API - 对象检测 api 中的损失意味着啥?

TensorFlow 对象检测 API 中未检测到任何内容

具有奇怪检测结果的 TensorFlow 对象检测 api

Tensorflow 对象检测 API 中的过拟合

Tensorflow 对象检测 API - 验证丢失行为

Tensorflow 2 对象检测 API:Numpy 版本错误