GenerlizedRCNN
[:, None, None] : Shape [3] -> [3, 1, 1]
In NumPy the * operator denotes the element-wise product (multiplying corresponding positions)
- a = np.array([1,2,3])
- b = np.array([2,2,2])
- a * b
- array([ 2., 4., 6.])
For two matrices a and b, compare their dimensions from the last one backwards; broadcasting is possible only if every dimension satisfies one of the following conditions.
They are equal
One of them is 1
boxes1 # shape[N,4]
boxes2 # shape[M,4]
lt = torch.max(boxes1[:, None, :2], boxes2[:, :2]) # left-top [N,M,2]
rb = torch.min(boxes1[:, None, 2:], boxes2[:, 2:]) # right-bottom [N,M,2]
- Here a dimension is inserted as the second dimension of boxes1, making it [N,1,4], so when it meets boxes2 it is automatically broadcast to [N,M,4]: each row is copied M times (think of them as rows), so every column of boxes1's [:,M,4] is identical, e.g. [1,2,3]->[[1,2,3],[1,2,3]]
- Broadcasting again, when boxes2 meets boxes1 the last two dimensions are now identical, so boxes2 becomes [N,M,4], which amounts to copying the whole of boxes2 N times
- So boxes1's [:,M,4] is really just one box's [xmin,ymin,xmax,ymax] repeated M times; essentially there is only one set of coordinates
- boxes2's [0,:,:] is equivalent to the original boxes2, so this amounts to comparing (computing) the first box's coordinates (row) in boxes1 against all the coordinates in boxes2