Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
曾经的那一瞬间
Models
提交
014c9383
M
Models
项目概览
曾经的那一瞬间
/
Models
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
014c9383
编写于
5月 10, 2022
作者:
A
A. Unique TensorFlower
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Internal change
PiperOrigin-RevId: 447823991
上级
a7ba08aa
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
65 addition
and
54 deletion
+65
-54
official/vision/ops/box_matcher.py
official/vision/ops/box_matcher.py
+65
-54
未找到文件。
official/vision/ops/box_matcher.py
浏览文件 @
014c9383
...
...
@@ -12,9 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""Box matcher implementation."""
from
typing
import
List
,
Tuple
import
tensorflow
as
tf
...
...
@@ -43,15 +43,19 @@ class BoxMatcher:
assigned positive_value.
"""
def
__init__
(
self
,
thresholds
,
indicators
,
force_match_for_each_col
=
False
):
def
__init__
(
self
,
thresholds
:
List
[
float
],
indicators
:
List
[
int
],
force_match_for_each_col
:
bool
=
False
):
"""Construct BoxMatcher.
Args:
thresholds: A list of thresholds to classify boxes into
different buckets. The list needs to be sorted, and will be prepended
with -Inf and appended with +Inf.
indicators: A list of values to assign for each bucket. len(`indicators`)
must equal to len(`thresholds`) + 1.
thresholds: A list of thresholds to classify the matches into different
types (e.g. positive or negative or ignored match). The list needs to be
sorted, and will be prepended with -Inf and appended with +Inf.
indicators: A list of values representing match types (e.g. positive or
negative or ignored match). len(`indicators`) must equal to
len(`thresholds`) + 1.
force_match_for_each_col: If True, ensures that each column is matched to
at least one row (which is not guaranteed otherwise if the
positive_threshold is high). Defaults to False. If True, all force
...
...
@@ -74,19 +78,20 @@ class BoxMatcher:
self
.
thresholds
=
thresholds
self
.
_force_match_for_each_col
=
force_match_for_each_col
def
__call__
(
self
,
similarity_matrix
):
def
__call__
(
self
,
similarity_matrix
:
tf
.
Tensor
)
->
Tuple
[
tf
.
Tensor
,
tf
.
Tensor
]:
"""Tries to match each column of the similarity matrix to a row.
Args:
similarity_matrix: A float tensor of shape [
N, M] representing any
similarity metric.
similarity_matrix: A float tensor of shape [
num_rows, num_cols] or
[batch_size, num_rows, num_cols] representing any
similarity metric.
Returns:
A integer tensor of shape [N] with corresponding match indices for each
of M columns, for positive match, the match result will be the
corresponding row index, for negative match, the match will be
`negative_value`, for ignored match, the match result will be
`ignore_value`
.
matched_columns: An integer tensor of shape [num_rows] or [batch_size,
num_rows] storing the index of the matched column for each row.
match_indicators: An integer tensor of shape [num_rows] or [batch_size,
num_rows] storing the match type indicator (e.g. positive or negative or
ignored match)
.
"""
squeeze_result
=
False
if
len
(
similarity_matrix
.
shape
)
==
2
:
...
...
@@ -101,29 +106,37 @@ class BoxMatcher:
"""Performs matching when the rows of similarity matrix are empty.
When the rows are empty, all detections are false positives. So we return
a tensor of -1's to indicate that the
columns do not match to any row
s.
a tensor of -1's to indicate that the
rows do not match to any column
s.
Returns:
matches: int32 tensor indicating the row each column matches to.
matched_columns: An integer tensor of shape [num_rows] or [batch_size,
num_rows] storing the index of the matched column for each row.
match_indicators: An integer tensor of shape [num_rows] or [batch_size,
num_rows] storing the match type indicator (e.g. positive or negative
or ignored match).
"""
with
tf
.
name_scope
(
'empty_gt_boxes'
):
matches
=
tf
.
zeros
([
batch_size
,
num_rows
],
dtype
=
tf
.
int32
)
match_
label
s
=
-
tf
.
ones
([
batch_size
,
num_rows
],
dtype
=
tf
.
int32
)
return
matche
s
,
match_label
s
matche
d_column
s
=
tf
.
zeros
([
batch_size
,
num_rows
],
dtype
=
tf
.
int32
)
match_
indicator
s
=
-
tf
.
ones
([
batch_size
,
num_rows
],
dtype
=
tf
.
int32
)
return
matche
d_columns
,
match_indicator
s
def
_match_when_rows_are_non_empty
():
"""Performs matching when the rows of similarity matrix are non empty.
Returns:
matches: int32 tensor indicating the row each column matches to.
matched_columns: An integer tensor of shape [num_rows] or [batch_size,
num_rows] storing the index of the matched column for each row.
match_indicators: An integer tensor of shape [num_rows] or [batch_size,
num_rows] storing the match type indicator (e.g. positive or negative
or ignored match).
"""
# Matches for each column
with
tf
.
name_scope
(
'non_empty_gt_boxes'
):
matches
=
tf
.
argmax
(
similarity_matrix
,
axis
=-
1
,
output_type
=
tf
.
int32
)
matched_columns
=
tf
.
argmax
(
similarity_matrix
,
axis
=-
1
,
output_type
=
tf
.
int32
)
# Get logical indices of ignored and unmatched columns as tf.int64
matched_vals
=
tf
.
reduce_max
(
similarity_matrix
,
axis
=-
1
)
match
ed
_indicators
=
tf
.
zeros
([
batch_size
,
num_rows
],
tf
.
int32
)
match_indicators
=
tf
.
zeros
([
batch_size
,
num_rows
],
tf
.
int32
)
match_dtype
=
matched_vals
.
dtype
for
(
ind
,
low
,
high
)
in
zip
(
self
.
indicators
,
self
.
thresholds
[:
-
1
],
...
...
@@ -133,48 +146,46 @@ class BoxMatcher:
mask
=
tf
.
logical_and
(
tf
.
greater_equal
(
matched_vals
,
low_threshold
),
tf
.
less
(
matched_vals
,
high_threshold
))
match
ed
_indicators
=
self
.
_set_values_using_indicator
(
match
ed
_indicators
,
mask
,
ind
)
match_indicators
=
self
.
_set_values_using_indicator
(
match_indicators
,
mask
,
ind
)
if
self
.
_force_match_for_each_col
:
# [batch_size,
M], for each col (groundtruth_box), find the best
# matching row (anchor).
force_match_column_id
s
=
tf
.
argmax
(
# [batch_size,
num_cols], for each column (groundtruth_box), find the
#
best
matching row (anchor).
matching_row
s
=
tf
.
argmax
(
input
=
similarity_matrix
,
axis
=
1
,
output_type
=
tf
.
int32
)
# [batch_size, M, N]
force_match_column_indicators
=
tf
.
one_hot
(
force_match_column_ids
,
depth
=
num_rows
)
# [batch_size, N], for each row (anchor), find the largest column
# index for groundtruth box
force_match_row_ids
=
tf
.
argmax
(
input
=
force_match_column_indicators
,
axis
=
1
,
output_type
=
tf
.
int32
)
# [batch_size, N]
force_match_column_mask
=
tf
.
cast
(
tf
.
reduce_max
(
force_match_column_indicators
,
axis
=
1
),
tf
.
bool
)
# [batch_size, N]
final_matches
=
tf
.
where
(
force_match_column_mask
,
force_match_row_ids
,
matches
)
final_matched_indicators
=
tf
.
where
(
force_match_column_mask
,
self
.
indicators
[
-
1
]
*
tf
.
ones
([
batch_size
,
num_rows
],
dtype
=
tf
.
int32
),
matched_indicators
)
return
final_matches
,
final_matched_indicators
else
:
return
matches
,
matched_indicators
# [batch_size, num_cols, num_rows], a transposed 0-1 mapping matrix M,
# where M[j, i] = 1 means column j is matched to row i.
column_to_row_match_mapping
=
tf
.
one_hot
(
matching_rows
,
depth
=
num_rows
)
# [batch_size, num_rows], for each row (anchor), find the matched
# column (groundtruth_box).
force_matched_columns
=
tf
.
argmax
(
input
=
column_to_row_match_mapping
,
axis
=
1
,
output_type
=
tf
.
int32
)
# [batch_size, num_rows]
force_matched_column_mask
=
tf
.
cast
(
tf
.
reduce_max
(
column_to_row_match_mapping
,
axis
=
1
),
tf
.
bool
)
# [batch_size, num_rows]
matched_columns
=
tf
.
where
(
force_matched_column_mask
,
force_matched_columns
,
matched_columns
)
match_indicators
=
tf
.
where
(
force_matched_column_mask
,
self
.
indicators
[
-
1
]
*
tf
.
ones
([
batch_size
,
num_rows
],
dtype
=
tf
.
int32
),
match_indicators
)
return
matched_columns
,
match_indicators
num_gt_boxes
=
similarity_matrix
.
shape
.
as_list
()[
-
1
]
or
tf
.
shape
(
similarity_matrix
)[
-
1
]
result_match
,
result_matched
_indicators
=
tf
.
cond
(
matched_columns
,
match
_indicators
=
tf
.
cond
(
pred
=
tf
.
greater
(
num_gt_boxes
,
0
),
true_fn
=
_match_when_rows_are_non_empty
,
false_fn
=
_match_when_rows_are_empty
)
if
squeeze_result
:
result_match
=
tf
.
squeeze
(
result_match
,
axis
=
0
)
result_matched_indicators
=
tf
.
squeeze
(
result_matched
_indicators
,
axis
=
0
)
matched_columns
=
tf
.
squeeze
(
matched_columns
,
axis
=
0
)
match_indicators
=
tf
.
squeeze
(
match
_indicators
,
axis
=
0
)
return
result_match
,
result_matched
_indicators
return
matched_columns
,
match
_indicators
def
_set_values_using_indicator
(
self
,
x
,
indicator
,
val
):
"""Set the indicated fields of x to val.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录