Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
曾经的那一瞬间
Models
提交
f27781ab
M
Models
项目概览
曾经的那一瞬间
/
Models
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
Models
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
f27781ab
编写于
11月 28, 2022
作者:
A
A. Unique TensorFlower
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Internal change
PiperOrigin-RevId: 491378667
上级
e5fb1283
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
104 addition
and
1 deletion
+104
-1
official/vision/modeling/layers/detection_generator.py
official/vision/modeling/layers/detection_generator.py
+102
-1
official/vision/modeling/layers/detection_generator_test.py
official/vision/modeling/layers/detection_generator_test.py
+2
-0
未找到文件。
official/vision/modeling/layers/detection_generator.py
浏览文件 @
f27781ab
...
...
@@ -14,10 +14,11 @@
"""Contains definitions of generators to generate the final detections."""
import
contextlib
from
typing
import
Any
,
Dict
,
List
,
Optional
,
Mapping
,
Sequence
from
typing
import
Any
,
Dict
,
List
,
Optional
,
Mapping
,
Sequence
,
Tuple
# Import libraries
import
tensorflow
as
tf
from
official.projects.edgetpu.vision.modeling
import
custom_layers
from
official.vision.ops
import
box_ops
from
official.vision.ops
import
nms
from
official.vision.ops
import
preprocess_ops
...
...
@@ -372,6 +373,93 @@ def _generate_detections_v2(boxes: tf.Tensor,
return
nmsed_boxes
,
nmsed_scores
,
nmsed_classes
,
valid_detections
def
_generate_detections_v3
(
boxes
:
tf
.
Tensor
,
scores
:
tf
.
Tensor
,
pre_nms_score_threshold
:
float
=
0.05
,
nms_iou_threshold
:
float
=
0.5
,
max_num_detections
:
int
=
100
)
->
Tuple
[
tf
.
Tensor
,
tf
.
Tensor
,
tf
.
Tensor
,
tf
.
Tensor
]:
"""Generates the detections given the model outputs using NMS for EdgeTPU.
Args:
boxes: A `tf.Tensor` with shape `[batch_size, num_classes, N, 4]` or
`[batch_size, 1, N, 4]`, which box predictions on all feature levels. The
N is the number of total anchors on all levels.
scores: A `tf.Tensor` with shape `[batch_size, num_classes, N]`, which
stacks class probability on all feature levels. The N is the number of
total anchors on all levels. The num_classes is the number of classes
predicted by the model. Note that the class_outputs here is the raw score.
pre_nms_score_threshold: A `float` representing the threshold for deciding
when to remove boxes based on score.
nms_iou_threshold: A `float` representing the threshold for deciding whether
boxes overlap too much with respect to IOU.
max_num_detections: A `scalar` representing maximum number of boxes retained
over all classes.
Returns:
nms_boxes: A `float` tf.Tensor of shape [batch_size, max_num_detections, 4]
representing top detected boxes in [y1, x1, y2, x2].
nms_scores: A `float` tf.Tensor of shape [batch_size, max_num_detections]
representing sorted confidence scores for detected boxes. The values are
between [0, 1].
nms_classes: An `int` tf.Tensor of shape [batch_size, max_num_detections]
representing classes for detected boxes.
valid_detections: An `int` tf.Tensor of shape [batch_size] only the top
`valid_detections` boxes are valid detections.
Raises:
ValueError if inputs shapes are not valid.
"""
with
tf
.
name_scope
(
'generate_detections'
):
batch_size
,
num_box_classes
,
box_locations
,
sides
=
(
boxes
.
get_shape
().
as_list
())
if
batch_size
is
None
:
batch_size
=
tf
.
shape
(
boxes
)[
0
]
_
,
num_classes
,
locations
=
scores
.
get_shape
().
as_list
()
if
num_box_classes
!=
1
and
num_box_classes
!=
num_classes
:
raise
ValueError
(
'Boxes should have either 1 class or same as scores.'
)
if
locations
!=
box_locations
:
raise
ValueError
(
'Number of locations is different.'
)
if
sides
!=
4
:
raise
ValueError
(
'Number of sides is incorrect.'
)
# Selects pre_nms_score_threshold scores before NMS.
boxes
,
scores
=
box_ops
.
filter_boxes_by_scores
(
boxes
,
scores
,
min_score_threshold
=
pre_nms_score_threshold
)
# EdgeTPU-friendly class-wise NMS, -1 for invalid.
indices
=
custom_layers
.
non_max_suppression_padded
(
boxes
,
scores
,
max_num_detections
,
iou_threshold
=
nms_iou_threshold
)
# Gather NMS-ed boxes and scores.
safe_indices
=
tf
.
nn
.
relu
(
indices
)
# 0 for invalid
invalid_detections
=
safe_indices
-
indices
# 1 for invalid, 0 for valid
valid_detections
=
1.0
-
invalid_detections
# 0 for invalid, 1 for valid
safe_indices
=
tf
.
cast
(
safe_indices
,
tf
.
int32
)
boxes
=
tf
.
expand_dims
(
valid_detections
,
-
1
)
*
tf
.
gather
(
boxes
,
safe_indices
,
axis
=
2
,
batch_dims
=
2
)
scores
=
valid_detections
*
tf
.
gather
(
scores
,
safe_indices
,
axis
=
2
,
batch_dims
=
2
)
# Compliment with class numbers.
classes
=
tf
.
range
(
num_classes
,
dtype
=
tf
.
float32
)
classes
=
tf
.
reshape
(
classes
,
[
1
,
num_classes
,
1
])
classes
=
tf
.
tile
(
classes
,
[
batch_size
,
1
,
max_num_detections
])
# Flatten classes, locations. Class = -1 for invalid detection
scores
=
tf
.
reshape
(
scores
,
[
batch_size
,
num_classes
*
max_num_detections
])
boxes
=
tf
.
reshape
(
boxes
,
[
batch_size
,
num_classes
*
max_num_detections
,
4
])
classes
=
tf
.
reshape
(
valid_detections
*
classes
-
invalid_detections
,
[
batch_size
,
num_classes
*
max_num_detections
])
# Filter top-k across boxes of all classes
scores
,
indices
=
tf
.
nn
.
top_k
(
scores
,
k
=
max_num_detections
,
sorted
=
True
)
boxes
=
tf
.
gather
(
boxes
,
indices
,
batch_dims
=
1
,
axis
=
1
)
classes
=
tf
.
gather
(
classes
,
indices
,
batch_dims
=
1
,
axis
=
1
)
invalid_detections
=
tf
.
nn
.
relu
(
classes
)
-
classes
valid_detections
=
tf
.
reduce_sum
(
1.
-
invalid_detections
,
axis
=
1
)
return
boxes
,
scores
,
classes
,
valid_detections
def
_generate_detections_batched
(
boxes
:
tf
.
Tensor
,
scores
:
tf
.
Tensor
,
pre_nms_score_threshold
:
float
,
nms_iou_threshold
:
float
,
...
...
@@ -991,6 +1079,19 @@ class MultilevelDetectionGenerator(tf.keras.layers.Layer):
max_num_detections
=
self
.
_config_dict
[
'max_num_detections'
]))
# Set `nmsed_attributes` to None for v2.
nmsed_attributes
=
{}
elif
self
.
_config_dict
[
'nms_version'
]
==
'v3'
:
# TODO(tohaspiridonov): add compatible version of
# `_decode_multilevel_outputs` in cl/485381750
(
nmsed_boxes
,
nmsed_scores
,
nmsed_classes
,
valid_detections
)
=
(
_generate_detections_v3
(
tf
.
transpose
(
boxes
,
[
0
,
2
,
1
,
3
]),
tf
.
transpose
(
scores
,
[
0
,
2
,
1
]),
pre_nms_score_threshold
=
self
.
_config_dict
[
'pre_nms_score_threshold'
],
nms_iou_threshold
=
self
.
_config_dict
[
'nms_iou_threshold'
],
max_num_detections
=
self
.
_config_dict
[
'max_num_detections'
]))
# Set `nmsed_attributes` to None for v2.
nmsed_attributes
=
{}
else
:
raise
ValueError
(
'NMS version {} not supported.'
.
format
(
self
.
_config_dict
[
'nms_version'
]))
...
...
official/vision/modeling/layers/detection_generator_test.py
浏览文件 @
f27781ab
...
...
@@ -126,6 +126,8 @@ class MultilevelDetectionGeneratorTest(
@
parameterized
.
parameters
(
(
'batched'
,
False
,
True
,
None
,
None
),
(
'batched'
,
False
,
False
,
None
,
None
),
(
'v3'
,
False
,
True
,
None
,
None
),
(
'v3'
,
False
,
False
,
None
,
None
),
(
'v2'
,
False
,
True
,
None
,
None
),
(
'v2'
,
False
,
False
,
None
,
None
),
(
'v1'
,
True
,
True
,
0.0
,
None
),
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录