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。如何减少洗牌缓冲区的大小?的主要内容,如果未能解决你的问题,请参考以下文章