# Check for degenerate boxes
# TODO: Move this to a function
if targets is not None:
for target_idx, target in enumerate(targets):
boxes = target["boxes"]
degenerate_boxes = boxes[:, 2:] <= boxes[:, :2]
if degenerate_boxes.any():
# print the first degenerate box
bb_idx = torch.where(degenerate_boxes.any(dim=1))[0][0]
degen_bb: List[float] = boxes[bb_idx].tolist()
torch._assert(
False,
"All bounding boxes should have positive height and width."
f" Found invalid box {degen_bb} for target at index {target_idx}.",
)

——————————————————————————————————
知识补充:enumerate() 函数
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons, start=1)) # 下标从 1 开始
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
知识补充字典取值:
a = {'box': [1,2,3], 'car': [4,5,6], 'yaya':'dabenzhu'}
print(type(a))
print(a['yaya'])
for i in enumerate(a):
b_idx, b = i
print(b_idx, b)
print('------------------------------')
a = [{'box': [1,2,3], 'car': [4,5,6], 'yaya':'dabenzhu'},
{'box': [4,5,6], 'car': [4,5,6], 'yaya':'dabenzhu'}]
print(type(a))
for b_idx, b in enumerate(a):
print(b['box'])
D:\anaconda\python.exe D:/pythonProject-alexnet/test.py
<class 'dict'>
dabenzhu
0 box
1 car
2 yaya
------------------------------
<class 'list'>
[1, 2, 3]
[4, 5, 6]
Process finished with exit code 0
————————————————————————————————————————
知识补充:
any函数
if degenerate_boxes.any():
any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 False,如果有一个为 True,则返回 True。
元素除了是 0、空、FALSE 外都算 TRUE。
>>>any(['a', 'b', 'c', 'd']) # 列表list,元素都不为空或0
True
>>> any(['a', 'b', '', 'd']) # 列表list,存在一个为空的元素
True
>>> any([0, '', False]) # 列表list,元素全为0,'',false
False
>>> any(('a', 'b', 'c', 'd')) # 元组tuple,元素都不为空或0
True
>>> any(('a', 'b', '', 'd')) # 元组tuple,存在一个为空的元素
True
>>> any((0, '', False)) # 元组tuple,元素全为0,'',false
False
>>> any([]) # 空列表
False
>>> any(()) # 空元组
False
————————————————————————————————————————
知识补充:
degenerate_boxes = boxes[:, 2:] <= boxes[:, :2]
判断boxes的二维后两个数是否小于二维前两个数,若存在,返回true(这里跟所解决的代码问题不一样,所要解决应该是返回box,不是true?试验下明天,把box改成二维,第一维???想一想怎么改,不会改哈哈哈哈)
它是位置对应验证的,比如第三个跟第一个比,第四个跟第二个比。
验证:
a = [{'box': [48,65,202,219]},
{'box': [61,66,198,203]},
{'box': [32,66,-1,288]},
{'box': [55,33,398,-1]},
{'box': [66,33,-1,-1]},]
for i in a:
box = i["box"]
print(box[2:], box[:2])
degenerate_box = box[2:] <= box[:2]
print(degenerate_box)
print('_________')
D:\anaconda\python.exe D:/pythonProject-alexnet/test.py
[202, 219] [48, 65]
False
_________
[198, 203] [61, 66]
False
_________
[-1, 288] [32, 66]
True
_________
[398, -1] [55, 33]
False
_________
[-1, -1] [66, 33]
True
_________
————————————————————————————————————————————
知识补充:pytorch torch.where用法
torch.where(condition, x, y) → Tensor
函数的作用
根据条件,返回从x,y中选择元素所组成的张量。如果满足条件,则返回x中元素。若不满足,返回y中元素。

例子

————————————————————————————————————————————
# print the first degenerate box
bb_idx = torch.where(degenerate_boxes.any(dim=1))[0][0]
degen_bb: List[float] = boxes[bb_idx].tolist()
torch._assert(
False,
"All bounding boxes should have positive height and width."
f" Found invalid box {degen_bb} for target at index {target_idx}.",
)
代码验证理解: bb_idx = torch.where(degenerate_boxes.any(dim=1))[0][0]
对于二维tensor,dim=1即每行。
import torch
x = torch.tensor([[0, 0, 0, 0],
[0, 0, 0, 1],
[0, 0.5690, 1.7978, 1],
[0, 0.5690, 1.7978, 1],
[0, 0.5690, 1.7978, 1]])
print(x)
print('____________________________')
# a = torch.where(x.any(dim=1))[0][2]
a = x.any(dim=1)
b = torch.where(a)[0][0]
print(a)
print(b)
D:\anaconda\python.exe D:/pythonProject-alexnet/test2.py
tensor([[0.0000, 0.0000, 0.0000, 0.0000],
[0.0000, 0.0000, 0.0000, 1.0000],
[0.0000, 0.5690, 1.7978, 1.0000],
[0.0000, 0.5690, 1.7978, 1.0000],
[0.0000, 0.5690, 1.7978, 1.0000]])
____________________________
tensor([False, True, True, True, True])
tensor(1)
Process finished with exit code 0
则上文代码中的得到索引 bb_idx,再代入boxes[bb_idx]中。
————————————————————————————————————————————