我一直在尝试使用tensorflow对象检测API训练对象检测模型。
当batch_size
为1时,网络训练良好。但是,增加batch_size
会导致某些步骤后出现以下错误。
网络: Faster RCNN
train_config: {
batch_size: 1
optimizer {
momentum_optimizer: {
learning_rate: {
manual_step_learning_rate {
initial_learning_rate: 0.0002
schedule {
step: 25000
learning_rate: .00002
}
schedule {
step: 50000
learning_rate: .000002
}
}
}
momentum_optimizer_value: 0.9
}
use_moving_average: false
}
错误:
INFO:tensorflow:报告给协调器的错误:,ConcatOp:输入的尺寸应匹配:shape [0] = [1,841,600,3] vs. shape [3] = [1,776,600,3]
[[node concat(在/home/<>/.virtualenvs/dl4cv/lib/python3.6/site-packages/object_detection-0.1-py3.6.egg/object_detection/legacy/trainer.py:190中定义)]]
错误可能源自输入操作。
连接到节点concat的输入源操作:
Preprocessor_3 / sub(定义在/home/<>/.virtualenvs/dl4cv/lib/python3.6/site-packages/object_detection-0.1-py3.6.egg/object_detection/models/faster_rcnn_inception_v2_feature_extractor.py:100)
增加了batch_size
的培训可在 SSD移动网络上进行。
同时,我已经解决了我的用例问题,在SO中发布了此问题以了解此行为的原因。
答案 0 :(得分:2)
出现错误的原因是,从技术上讲,您无法在单个GPU上以批处理模式训练Faster RCNN。这是由于其两阶段的体系结构。 SSD是单级的,因此可以并行化以提供更大的批量。如果您仍想以大于1的批次大小训练F-RCNN,则可以使用多个GPU进行训练。您需要将--num_clones参数设置为您可用的GPU数量。设置num_clones和batchsize以保存值(它应等于可用的GPU数量) 我在应用程序中使用了4,8和16的batchsize。 --num_clones = 2 --ps_tasks = 1 检查此链接以获取更多详细信息 https://github.com/tensorflow/models/issues/1744
答案 1 :(得分:1)
仅从错误看来,您的各个输入具有不同的大小。我想它尝试将4个单一输入连接到一个张量中,以构建一个迷你批处理作为输入。
尝试连接时,有一个输入841x600x3
和一个输入776x600x3
(忽略批处理维)。因此显然841和776不相等,但应该相等。批处理大小为1时,可能不会调用concat函数,因为您无需连接输入即可获得小批量。似乎也没有其他组件依赖于预定义的输入大小,因此网络将正常训练,或者至少不会崩溃。
我将检查您正在使用的数据集,并检查是否应该采用这种方式,或者您有一些错误的数据样本。如果数据集还可以,并且实际上可能发生这种情况,那么您需要将所有输入调整为某种预先定义的分辨率,以便能够将它们组合成一个小批量。
答案 2 :(得分:0)
您无需调整数据集中的每个图像的大小。如果在配置文件中指定,Tensorflow可以处理它。
默认的frcnn和ssd配置为:
## frcnn
image_resizer {
keep_aspect_ratio_resizer {
min_dimension: 600
max_dimension: 1024
}
}
## ssd
image_resizer {
fixed_shape_resizer {
height: 300
width: 300
}
}
如果像在ssd中一样将frcnn的image resizer
更改为fixed_shape_resizer
,则可以增加批处理大小。
我实现了它,并且训练进行得很顺利。不幸的是,我的损失没有像我预期的那样减少。然后,我切换回具有4个工作人员的批处理大小4(这意味着每个工作人员的批处理大小为1)。后一种情况对我来说更好,但也许对你而言会有所不同。
答案 3 :(得分:0)
增加批量大小时,张量中加载的图像应全部具有相同的大小。
这是使图像大小都相同的方法:
image_resizer {
keep_aspect_ratio_resizer {
min_dimension: 896
max_dimension: 896
pad_to_max_dimension: true
}
}
将图像填充到最大尺寸,使其为“ true”,这将导致图像尺寸全部相同。这样一来,您的批处理大小将大于一个。