Python 在Tensorflow对象检测API中避免重叠边界框

Python 在Tensorflow对象检测API中避免重叠边界框,python,tensorflow,object-detection,bounding-box,object-detection-api,Python,Tensorflow,Object Detection,Bounding Box,Object Detection Api,我正在使用Tensorflow对象检测API来训练我自己的数字板检测器。我使用了ssd\u mobilenet\u v3\u small\u coco作为功能提取器。当我使用对象检测教程测试我的模型时,我发现同一个对象被检测了多次。经过一些搜索,我发现tensorflow使用了非最大值抑制,但为什么同一个对象要检测多次 我的配置文件在这里 #带有Mobilenet v3大型功能提取器的SSDLite。 #接受COCO14培训,从头开始初始化。 #3.22M参数,1.02B触发器 #TPU兼容。

我正在使用Tensorflow对象检测API来训练我自己的数字板检测器。我使用了
ssd\u mobilenet\u v3\u small\u coco
作为功能提取器。当我使用对象检测教程测试我的模型时,我发现同一个对象被检测了多次。经过一些搜索,我发现tensorflow使用了
非最大值抑制
,但为什么同一个对象要检测多次

我的配置文件在这里

#带有Mobilenet v3大型功能提取器的SSDLite。
#接受COCO14培训,从头开始初始化。
#3.22M参数,1.02B触发器
#TPU兼容。
模型{
固态硬盘{
就地规范更新:真
冻结:错误
班级数:1
箱式编码器{
更快的rcnn盒编码器{
y_比例:10.0
x_比例:10.0
高度刻度:5.0
宽度/刻度:5.0
}
}
匹配器{
argmax_匹配器{
匹配的_阈值:0.5
不匹配的_阈值:0.5
忽略_阈值:false
否定比不匹配低:真
为每行强制匹配:true
使用_matmul_聚集:true
}
}
相似性计算器{
借据相似性{
}
}
将背景编码为零:真
锚定发电机{
ssd_锚定_发生器{
层数:6
最小刻度:0.2
最大刻度:0.95
纵横比:1.0
纵横比:2.0
纵横比:0.5
纵横比:3.0
纵横比:0.3333
}
}
图像缩放器{
固定形状大小调整器{
身高:320
宽度:320
}
}
箱型预测器{
卷积盒预测器{
最小深度:0
最大深度:0
预测值之前的层数:0
使用退出:false
辍学率:0.8
内核大小:3
使用深度:true
包装箱编码尺寸:4
将_sigmoid_应用于_分数:false
类别预测偏差初始值:-4.6
conv_超参数{
激活:RELU_6,
正则化器{
l2_正则化子{
重量:0.00004
}
}
初始值设定项{
随机\u正规\u初始值设定项{
标准差饷租值:0.03
平均值:0.0
}
}
批量单位范数{
火车:是的,
比例:对,
中:是的,
衰减:0.97,
ε:0.001,
}
}
}
}
特征提取器{
类型:“ssd\u mobilenet\u v3\u大型”
最小深度:16
深度乘数:1.0
使用深度:true
conv_超参数{
激活:RELU_6,
正则化器{
l2_正则化子{
重量:0.00004
}
}
初始值设定项{
截断的\u正规\u初始值设定项{
标准差饷租值:0.03
平均值:0.0
}
}
批量单位范数{
火车:是的,
比例:对,
中:是的,
衰减:0.97,
ε:0.001,
}
}
覆盖\u基\u特征\u提取器\u超参数:真
}
损失{
分类损失{
加权乙状结肠焦{
阿尔法:0.75,
伽马:2.0
}
}
定位损失{
加权平滑{
增量:1.0
}
}
分类单位重量:1.0
重量:1.0
}
通过\u num\u匹配规范化\u损失\u:true
通过代码大小规范化\u loc\u损失\u:true
后处理{
批量\u非\u最大\u抑制{
评分标准:1e-8
欠条限额:0.6
每类最大探测次数:100
最大总检测次数:100
使用静态形状:真
}
分数转换器:S形
}
}
}
列车配置:{
批量大小:512
同步复制副本:true
启动\u延迟\u步骤:0
副本到集合:32
步数:400000
微调检查点:“ssd\u mobilenet\u v3\u large\u coco\u 2019\u 08\u 14/model.ckpt-1636”
来自\u检测\u检查点:true
数据扩充选项{
随机水平翻转{
}
}
数据扩充选项{
ssd_随机_裁剪{
}
}
优化器{
动量优化器:{
学习率:{
余弦衰减学习率{
学习率基数:0.4
总步数:400000
热身学习率:0.13333
预热步骤:2000
}
}
动量\优化器\值:0.9
}
使用移动平均值:false
}
最大箱数:100
unpad_groundtruth_张量:false
}
列车输入读取器:{
tf_记录_输入_读取器{
输入路径:“数据/列车记录”
}
标签映射路径:“training/object detection.pbtxt”
}
评估配置:{
数字示例:1850
}
评估输入读取器:{
tf_记录_输入_读取器{
输入路径:“数据/测试记录”
}
标签映射路径:“training/object detection.pbtxt”
洗牌:错
阅读器数量:1
}
我的模型的输出是 你可以在这里查阅

在一个图像上运行模型时,它会吐出一个 输出字典

为预测设置阈值,我们发现有多少预测高于阈值ie长度(这里我使用了std 0.5)

length=len(如果i>0.5,[i表示输出中的i['detection\u scores']
box_tensor=tf.将_转换为_tensor(输出[u dict['detection_box'][:length],np.float32)
分数张量=tf。将分数转换为张量(输出[u dict['detection\u scores'][:length],np.float32)
所选索引=tf.image.non\u max\u抑制(box=box\u张量,max\u输出大小=长度,iou\u阈值=,分数=分数张量)
box=输出目录['detection\u box'][tf.Session().run(所选索引)]
分数=输出[检测分数][tf.Session().run(选定的索引)]
您将看到盒子和它们各自的溃疡

您可以在这里查阅

在一个图像上运行模型时,它会吐出一个 输出字典

为预测设置阈值,然后我们发现
length = len([i for i in output_dict['detection_scores'] if i>0.5]

boxes_tensor = tf.convert_to_tensor(output_dict['detection_boxes'][:length], np.float32)
scores_tensor = tf.convert_to_tensor(output_dict['detection_scores'][:length], np.float32)
selected_indices = tf.image.non_max_suppression(boxes=boxes_tensor, max_output_size=length, iou_threshold=<IOU YOU WANT TO SET>,scores=scores_tensor)
boxes = output_dict['detection_boxes'][tf.Session().run(selected_indices)]
scores = output_dict['detection_scores'][tf.Session().run(selected_indices)]