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
B
ƒ¨–_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>sz%concat_all_gather.<locals>.<listcomp>F)Úasync_opr)Údim)ÚrangerÚ distributedÚget_world_sizeÚ
all_gatherÚcat)rZtensors_gatherÚoutputr)rr    Ú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)Úkeepdimgê-™—q=)rÚnormÚ    expand_as)ÚxÚaxisrrr    Ú    normalizes$rcCs†| d¡| d¡}}t |d¡jddd ||¡}t |d¡jddd ||¡ ¡}||}| dd|| ¡¡|jdd ¡}|S)    NrréT)réþÿÿÿgê-™—q=)Úmin)    ÚsizerÚpowÚsumÚexpandÚtÚaddmm_ÚclampÚsqrt)rÚyÚmÚnÚxxÚyyÚdistrrr    Úeuclidean_dist's"r-c    CsŽ| d¡| d¡}}t || dd¡¡}t t t |d¡d¡¡ |d¡ d|¡t t t |d¡d¡¡ d|¡ |d¡}||}d|S)Nrrr)    rrÚmatmulÚ    transposer&r!r ÚviewÚrepeat)rr'Zbs1Zbs2Zfrac_upZ    frac_downZcosinerrr    Ú cosine_dist1s (,r2cCsTtj||dddd}||}tjt |¡|dddd}t |¡||}|S)NrT)r rrgíµ ÷ư>)rÚmaxr!Úexp)r,ÚmaskZmax_vÚdiffÚZÚWrrr    Úsoftmax_weights:s
r9cCs‚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.
    rrrrT)r)    ÚlenrÚAssertionErrorrr3Ú
contiguousr0rÚsqueeze)Údist_matÚis_posÚis_negÚNÚdist_apZrelative_p_indsÚdist_anZrelative_n_indsrrr    Úhard_example_miningBs
  
 
rDcCsvt| ¡ƒ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:rr;Úfloatr9rr!)r>r?r@rBrCZ
weights_apZ
weights_anrrr    Úweighted_example_miningls
 
 rFc@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)rrr)ÚmarginÚInfg333333Ó?)rNrrrrr-rr0r"Úeqr#ÚnerRrDrFÚnewÚ
resize_as_Úfill_rLÚFÚmargin_ranking_lossÚsoft_margin_lossrErP)rSÚ    embeddingÚtargetsÚ all_embeddingÚ all_targetsr>rAÚMr?r@rBrCr'Úlossrrr    Ú__call__‘s*  
 
 .. zTripletLoss.__call__N)Ú__name__Ú
__module__Ú __qualname__Ú__doc__rUrfrrrr    rG†srGc@seZdZdd„Zdd„ZdS)Ú
CircleLosscCs.|jjjj|_|jjjj|_|jjjj|_dS)N)    rHrIÚCIRCLErOrPrKr(ÚALPHAÚs)rSrTrrr    rU´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)r]rrrrrr.r#rr0r"rXrYr<ÚreluÚdetachr(rnÚsoftplusÚ    logsumexpÚmeanrP)rSr`rarbrcr>rArdr?r@Ús_pÚs_nÚalpha_pÚalpha_nÚdelta_pÚdelta_nZlogit_pZlogit_nrerrr    rfºs( 
 ..
&zCircleLoss.__call__N)rgrhrirUrfrrrr    rk³srk)r)rjrÚtorch.nn.functionalÚnnÚ
functionalr]ÚutilsrÚno_gradrrr-r2r9rDrFÚobjectrGrkrrrr    Ú<module>s 
 
    *-