问题描述
这个问题是从这个问题构建的:(tensorflow 计算得到最大框后记住索引).我发现丢弃全零的盒子特别困难,所以我发布了一个新的.
This question is built from this question: (tensorflow remember the index after calculating getting the maximum box). I find discarding boxes with all zeros particularly hard, so I am posting a new one.
完整描述:
假设我有两个盒子数组,每个盒子的形状分别为 (?, b1, 4)
和 (?, b2, 4)
(处理?
作为未知的批量大小):
Assume that I have two arrays of boxes, each of which has the shape (?, b1, 4)
and (?, b2, 4)
respectively (treat ?
as a unknown batch size):
box1: [[[1,2,3,4], [2,3,4,5], [3,4,5,6], [0,0,0,0], [0,0,0,0]...]...]
box2: [[[4,3,2,1], [3,2,5,4], [4,3,5,6]...]...]
(以上数字任意设定)
请注意,box1
可能有也可能没有假框([0,0,0,0]
) 最后.
Note that box1
may or may not have fake box([0,0,0,0]
) at the end.
我想:
在每个批次中,对于
box1
中的每个 non-fake 框 A(即不包含所有零),在box2
中找到与 A 具有最大 IOU(交集)的框 B(当然,在同一批次中)),然后将元组 (A, B) 附加到列表 list_max.
in each batch, for each non-fake box A in
box1
(that is, boxes that does not contain all zeros), find inbox2
the box B which has the maximum IOU (intersection over union) with A (in the same batch, of course), and then append the tuple (A, B) to a list list_max.
将box2
中所有与box1
中任意一个框没有最大IOU的框追加到list_nonmax中(以batch分隔),当然)
append to list_nonmax all the boxes in box2
that does not have maximum IOU with any box in box1
(separated by batch, of course)
您可以假设:
b1 和 b2 都是 python 变量,不是 tensorflow 张量.
b1 and b2 are both python variables, not tensorflow tensor.
计算单个盒子之间或一批盒子之间的IOU的方法已经存在并且可以直接使用:
methods for calculating IOU between single box or between batch of boxes already exists and can be used literally:
iou_single_box(box1, box2)
:box1 和 box2 都是 (4,)
形状.
iou_single_box(box1, box2)
: both box1 and box2 are of shape (4,)
.
iou_multiple_boxes(bbox1, bbox2)
: bbox1 和 bbox2 都是 (b1, 4)
和 (b2, 4)
分别.
iou_multiple_boxes(bbox1, bbox2)
: both bbox1 and bbox2 are of shape (b1, 4)
and (b2, 4)
respectively.
iou_batch_boxes(bbbox1, bbbox2)
: bbbox1 和 bbbox2 的形状都是 (?, b1, 4)
和 (?, b2, 4)
分别(将 ?
视为未知批大小).
iou_batch_boxes(bbbox1, bbbox2)
: both bbbox1 and bbbox2 are of shape (?, b1, 4)
and (?, b2, 4)
respectively (treat ?
as a unknown batch size).
你可以看一下问题(tensorflow 在计算获得最大框后记住索引) 我之前发布过.我只添加一个约束:
You can take a look at the question (tensorflow remember the index after calculating getting the maximum box) I post previously. I only add one constraint:
- 我不希望
box1
中的任何 假 框与box2
中的任何框匹配.当获得 list_max 和 list_nonmax
- I don't want any fake box in
box1
to match against any box inbox2
. when getting list_max and list_nonmax
注意没有设置fake box的数量.
Note that the number of fake box is not set.
****:我知道这个问题很复杂.我做所有这些是因为 Tensorflow 无法处理动态长度数组(你必须在运行时为 box1
设置一个确定性的 b1
).所以我在 box1
的末尾填充 [0, 0, 0, 0]
来固定长度.
****: I know this question is quite complicated. I do all these because Tensorflow cannot handle dynamic-length array (you have to have a deterministic b1
for box1
at runtime). So I pad [0, 0, 0, 0]
at the end of box1
to make the length fixed.
推荐答案
我相信这很容易通过 tf.boolean_mask()
喜欢这个代码(已测试):
I believe this is easily doable with tf.boolean_mask()
like this code (tested):
from __future__ import print_function
import tensorflow as tf
box1 = tf.reshape( tf.constant( range( 16 ), dtype = tf.float32 ), ( 2, 2, 4 ) )
box1 = tf.concat( [ box1, tf.zeros( ( 2, 2, 4 ) ) ], axis = 1 )
box2 = tf.reshape( tf.constant( range( 2, 26 ), dtype = tf.float32 ), ( 2, 3, 4 ) )
batch_size = box1.get_shape().as_list()[ 0 ]
def dummy_iou_batch_boxes( box1, box2 ):
b1s, b2s = box1.get_shape().as_list(), box2.get_shape().as_list()
return tf.constant( [ [ [9.0,8,7], [1,2,3], [ 0, 10, 0 ], [ 0, 0, 0 ],
[0 ,1,2], [0,5,0], [ 0, 0, 0 ], [ 0, 0, 0 ] ] ] )
iou = dummy_iou_batch_boxes( box1, box2 )
val, idx = tf.nn.top_k( iou, k = 1 )
idx = tf.reshape( idx, ( batch_size, box1.get_shape().as_list()[ 1 ] ) )
one_hot_idx = tf.one_hot( idx, depth = box2.get_shape().as_list()[ 1 ] )
# for listmax
full_idx = tf.where( tf.equal( 1.0, one_hot_idx ) )
box1_idx = full_idx[ :, 0 : 2 ]
box2_idx = full_idx[ :, 0 : 3 : 2 ]
box12 = tf.gather_nd( box1, box1_idx )
box22 = tf.gather_nd( box2, box2_idx )
list_max_raw = tf.stack( [ box12, box22 ], axis = 1 )
# filter out for a = [ 0, 0, 0, 0 ]
nonzero_mask = tf.reduce_any( tf.not_equal( 0.0, list_max_raw ), axis = 2 )[ :, 0 ]
list_max = tf.boolean_mask( list_max_raw, nonzero_mask )
# for list nonmax
nonzero_mask = tf.cast( tf.reduce_any( tf.not_equal( 0.0, box1 ), axis = 2 ), tf.float32 )[ ..., None ]
filtered_one_hot = one_hot_idx * nonzero_mask
active_box2 = tf.sign( tf.reduce_sum( filtered_one_hot, axis = 1 ) )
nonactive_box2 = 1.0 - active_box2
nonactive_box2_idx = tf.where( tf.equal( 1.0, nonactive_box2 ) )
list_nonmax = tf.gather_nd( box2, nonactive_box2_idx )
with tf.Session() as sess:
res = sess.run( [ box1, box2, list_max ] )
print( "Input boxes: " )
for v in res[ : 2 ]:
print( v )
print( " ", "=" * 40 )
print( "List max: " )
for v in res[ 2 : ]:
print( v )
print( " ", "=" * 40 )
res = sess.run( [ list_nonmax ] )
print( "List nonmax: " )
for v in res:
print( v )
print( " ", "=" * 40 )
会输出
输入框:
[[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7. ]
[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]]
[[ 8. 9. 10. 11.]
[12.13. 14. 15.]
[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]]]
========================================
[[[ 2. 3. 4. 5.]
[ 6. 7. 8. 9. ]
[10.11. 12. 13.]]
[[ 8. 9. 10. 11.]
[12. 13. 14. 15.]
[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]]]
========================================
[[[ 2. 3. 4. 5.]
[ 6. 7. 8. 9.]
[10. 11. 12. 13.]]
[[14.15. 16. 17.]
[18.19. 20. 21.]
[22.23. 24. 25.]]]
========================================
列表最大值:
[[[ 0. 1. 2. 3.]
[ 2. 3. 4. 5.]]
[[14. 15. 16. 17.]
[18. 19. 20. 21.]
[22. 23. 24. 25.]]]
========================================
List max:
[[[ 0. 1. 2. 3.]
[ 2. 3. 4. 5.]]
[[ 4.5.6.7.]
[10.11. 12. 13.]]
[[ 4. 5. 6. 7.]
[10. 11. 12. 13.]]
[[ 8. 9. 10. 11.]
[22.23. 24. 25.]]
[[ 8. 9. 10. 11.]
[22. 23. 24. 25.]]
[[12.13. 14. 15.]
[18.19. 20. 21.]]]
========================================
列出非最大值:
[[ 6. 7. 8. 9.]
[14.15. 16. 17.]]
========================================
[[12. 13. 14. 15.]
[18. 19. 20. 21.]]]
========================================
List nonmax:
[[ 6. 7. 8. 9.]
[14. 15. 16. 17.]]
========================================
这篇关于tensorflow 获取具有最大 IOU 的框对,但丢弃全为零的框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!