Scheaven
2021-09-18 291deeb1fcf45dbf39a24aa72a213ff3fd6b3405
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
92
93
U
ƒ¨–_lã@sdZddlZddlmmZddlmZe ¡dd„ƒZ    ddd„Z
d    d
„Z d d „Z d d„Z dd„Zdd„ZGdd„deƒZGdd„deƒZdS)z9
@author:  liaoxingyu
@contact: sherlockliao01@gmail.com
éN)Úcommcs@‡fdd„ttj ¡ƒDƒ}tjj|ˆddtj|dd}|S)zƒ
    Performs all_gather operation on the provided tensors.
    *** Warning ***: torch.distributed.all_gather has no gradient.
    csg|]}t ˆ¡‘qS©)ÚtorchÚ    ones_like)Ú.0Ú_©Útensorrú ./modeling/losses/metric_loss.pyÚ
<listcomp>sÿz%concat_all_gather.<locals>.<listcomp>F)Úasync_opr©Údim)ÚrangerÚ distributedÚget_world_sizeÚ
all_gatherÚcat)r    Ztensors_gatherÚoutputrrr
Úconcat_all_gathers 
 ÿréÿÿÿÿcCs(d|tj|d|dd |¡d}|S)zžNormalizing to unit length along the specified dimension.
    Args:
      x: pytorch Variable
    Returns:
      x: pytorch Variable, same shape as input
    gð?éT©Úkeepdimçê-™—q=)rÚnormÚ    expand_as)ÚxÚaxisrrr
Ú    normalizes$rcCs†| d¡| d¡}}t |d¡jddd ||¡}t |d¡jddd ||¡ ¡}||}| dd|| ¡¡|jdd ¡}|S)    NrréTréþÿÿÿr)Úmin)    ÚsizerÚpowÚsumÚexpandÚtÚaddmm_ÚclampÚsqrt)rÚyÚmÚnÚxxÚyyÚdistrrr
Úeuclidean_dist's"r1c    CsŽ| d¡| d¡}}t || dd¡¡}t t t |d¡d¡¡ |d¡ d|¡t t t |d¡d¡¡ d|¡ |d¡}||}d|S)Nrr r)    r#rÚmatmulÚ    transposer*r%r$ÚviewÚrepeat)rr+Zbs1Zbs2Zfrac_upZ    frac_downZcosinerrr
Ú cosine_dist1s((ÿr6cCsTtj||dddd}||}tjt |¡|dddd}t |¡||}|S)Nr T)rrrgíµ ÷ư>)rÚmaxr%Úexp)r0ÚmaskZmax_vÚdiffÚZÚWrrr
Úsoftmax_weights:s
r=cCs‚t| ¡ƒdkst‚| d¡}tj|| ¡ |d¡ddd\}}tj|| ¡ |d¡ddd\}}| d¡}| d¡}||fS)aFor each anchor, find the hardest positive and negative sample.
    Args:
      dist_mat: pair wise distance between samples, shape [N, M]
      is_pos: positive index with shape [N, M]
      is_neg: negative index with shape [N, M]
    Returns:
      dist_ap: pytorch Variable, distance(anchor, positive); shape [N]
      dist_an: pytorch Variable, distance(anchor, negative); shape [N]
      p_inds: pytorch LongTensor, with shape [N];
        indices of selected hard positive samples; 0 <= p_inds[i] <= N - 1
      n_inds: pytorch LongTensor, with shape [N];
        indices of selected hard negative samples; 0 <= n_inds[i] <= N - 1
    NOTE: Only consider the case in which all labels have same num of samples,
      thus we can cope with all anchors in parallel.
    rrrr Tr)    Úlenr#ÚAssertionErrorrr7Ú
contiguousr4r"Úsqueeze)Údist_matÚis_posÚis_negÚNÚdist_apZrelative_p_indsÚdist_anZrelative_n_indsrrr
Úhard_example_miningBs
ÿ
ÿ
 
 
rHcCsvt| ¡ƒdkst‚| ¡}| ¡}||}||}t||ƒ}t| |ƒ}tj||dd}tj||dd}||fS)aYFor each anchor, find the weighted positive and negative sample.
    Args:
      dist_mat: pytorch Variable, pair wise distance between samples, shape [N, N]
      is_pos:
      is_neg:
    Returns:
      dist_ap: pytorch Variable, distance(anchor, positive); shape [N]
      dist_an: pytorch Variable, distance(anchor, negative); shape [N]
    rr r )r>r#r?Úfloatr=rr%)rBrCrDrFrGZ
weights_apZ
weights_anrrr
Úweighted_example_miningls
 
 rJc@s eZdZdZdd„Zdd„ZdS)Ú TripletLosszÁModified from Tong Xiao's open-reid (https://github.com/Cysu/open-reid).
    Related Triplet Loss theory can be found in paper 'In Defense of the Triplet
    Loss for Person Re-Identification'.cCs<|jjjj|_|jjjj|_|jjjj|_|jjjj    |_
dS©N) ÚMODELÚLOSSESÚTRIÚMARGINÚ_marginÚ    NORM_FEATÚ_normalize_featureÚSCALEÚ_scaleÚ HARD_MININGÚ _hard_mining©ÚselfÚcfgrrr
Ú__init__‹szTripletLoss.__init__cCsB|jrt|dd}t ¡dkr0t|ƒ}t|ƒ}n|}|}t||ƒ}| ¡\}}| |d¡ ||¡     | |d¡ ||¡ 
¡¡}| |d¡ ||¡  | |d¡ ||¡ 
¡¡}    |j rÂt |||    ƒ\}
} nt|||    ƒ\}
} |  ¡ | ¡ d¡} |jdkrtj| |
| |jd} n0t | |
| ¡} | tdƒkr8tj| |
| dd} | |jS)Nr)rr r)ÚmarginÚInfg333333Ó?)rSrrrrr1r#r4r&Úeqr'ÚnerWrHrJÚnewÚ
resize_as_Úfill_rQÚFÚmargin_ranking_lossÚsoft_margin_lossrIrU)rYÚ    embeddingÚtargetsÚ all_embeddingÚ all_targetsrBrEÚMrCrDrFrGr+Úlossrrr
Ú__call__‘s*  
 
 .. zTripletLoss.__call__N)Ú__name__Ú
__module__Ú __qualname__Ú__doc__r[rlrrrr
rK†srKc@seZdZdd„Zdd„ZdS)Ú
CircleLosscCs.|jjjj|_|jjjj|_|jjjj|_dSrL)    rMrNÚCIRCLErTrUrPr,ÚALPHAÚsrXrrr
r[´szCircleLoss.__init__cCshtj|dd}t ¡dkr,t|ƒ}t|ƒ}n|}|}t || ¡¡}| ¡\}}|     |d¡ 
||¡  |     |d¡ 
||¡ ¡¡}|     |d¡ 
||¡  |     |d¡ 
||¡ ¡¡}    ||  ¡     |d¡}
||      ¡     |d¡} t |
 ¡ d|j¡} t |  ¡|j¡} d|j}|j}|j | |
|}|j| | |}t tj|ddtj|dd¡ ¡}||jS)Nr r r)rcrrrrrr2r'r#r4r&r^r_r@ÚreluÚdetachr,rtÚsoftplusÚ    logsumexpÚmeanrU)rYrfrgrhrirBrErjrCrDÚs_pÚs_nÚalpha_pÚalpha_nÚdelta_pÚdelta_nZlogit_pZlogit_nrkrrr
rlºs( 
 ..
&zCircleLoss.__call__N)rmrnror[rlrrrr
rq³srq)r)rprÚtorch.nn.functionalÚnnÚ
functionalrcÚutilsrÚno_gradrrr1r6r=rHrJÚobjectrKrqrrrr
Ú<module>s 
 
 
    *-