File size: 3,367 Bytes
df4f158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import torch
import numpy
#from transformer import Local_Attention,Transformer_1
# codes of this function are borrowed from https://github.com/yanx27/Pointnet_Pointnet2_pytorch/blob/master/models/pointnet2_utils.py
def index_points(device, points, idx):
    """

    Input:
        points: input points data, [B, N, C]
        idx: sample index data, [B, S]
    Return:
        new_points:, indexed points data, [B, S, C]
    """
    B = points.shape[0]
    view_shape = list(idx.shape)
    view_shape[1:] = [1] * (len(view_shape) - 1)
    repeat_shape = list(idx.shape)
    repeat_shape[0] = 1
    # batch_indices = torch.arange(B, dtype=torch.long).to(device).view(view_shape).repeat(repeat_shape)
    batch_indices = torch.arange(B, dtype=torch.long).to(device).view(view_shape).repeat(repeat_shape)
    new_points = points[batch_indices, idx, :]
    return new_points

def knn_l2(device, net, k, u):
    '''
    Input:
        k: int32, number of k in k-nn search
        net: (batch_size, npoint, c) float32 array, points
        u: int32, block size
    Output:
        idx: (batch_size, npoint, k) int32 array, indices to input points
    '''
    INF = 1e8
    batch_size = net.size(0)
    npoint = net.size(1)
    n_channel = net.size(2)

    square = torch.pow(torch.norm(net, dim=2,keepdim=True),2)

    def u_block(batch_size, npoint, u):
        block = numpy.zeros([batch_size, npoint, npoint])
        n = npoint // u
        for i in range(n):
            block[:, (i*u):(i*u+u), (i*u):(i*u+u)] = numpy.ones([batch_size, u, u]) * (-INF)
        return block

    # minus_distance = 2 * torch.matmul(net, net.transpose(2,1)) - square - square.transpose(2,1) + torch.Tensor(u_block(batch_size, npoint, u)).to(device)
    minus_distance = 2 * torch.matmul(net, net.transpose(2,1)) - square - square.transpose(2,1) + torch.Tensor(u_block(batch_size, npoint, u)).to(device)
    _, indices = torch.topk(minus_distance, k, largest=True, sorted=False)
    
    return indices

if __name__ == '__main__':

        bs,gs,k=5,5,4
        
        A=torch.rand(bs*gs,512,14,14).cuda()
        net=Transformer_1(512,4,4,782).cuda()
        Y=net(A)
        print(Y.shape)
        exit(0)
        feature_map_size=A.shape[-1]
        point = A.permute(0,2,1,3,4).reshape(A.size(0), A.size(1)*A.shape[-1]*A.shape[-2], -1)
        point = point.permute(0,2,1)
        X=point
        print(point.shape)
        idx = knn_l2(0, point, 4, 1)
        #print(idx)
        
        feat=idx
        new_point = index_points(0, point,idx)

        group_point = new_point.permute(0, 3, 2, 1)
        print(group_point.shape)
        _1,_2,_3,_4=group_point.shape
        X=X.permute(0,2,1)
        print(X.shape)
        #torch.cat([group_point.reshape(_1*_2,k,_4),X.reshape(_1*_2,1,_4)],dim=1).permute(0,2,1)
        attn_map=X.reshape(_1*_2,1,_4)@torch.cat([group_point.reshape(_1*_2,k,_4),X.reshape(_1*_2,1,_4)],dim=1).permute(0,2,1)
        V=torch.cat([group_point.reshape(_1*_2,k,_4),X.reshape(_1*_2,1,_4)],dim=1)
        print(attn_map.shape)
        Y=attn_map@V
        Y=Y.reshape(_1,_2,_4)
        
        #group_point = torch.max(group_point, 2)[0]  # [B, D', S]
        group_point=Y
        print(group_point.shape)
        
        intra_mask = group_point.view(bs,gs, group_point.size(2), feature_map_size, feature_map_size)
        print(intra_mask.shape)