2023. 4. 1. 14:06ㆍ💗 AI/💡 Theory
instance들 간의 유사도를 기반으로 loss를 측정하는 softNN loss에 대해서 알아보자
출처 : https://arxiv.org/abs/1902.01889
Contrastive learning, Metric learning등을 학습 할 때 instance들 간의 유사도를 기반으로 loss를 측정할 일이 생긴다
이때
contrastive loss, triplet loss, lifted structed loss, NCE loss, infoNCE loss 와 같이 다양한 로스들을 사용 할 수 있다.
이 페이지에서는 softNN loss에 대해서 알아보고자 한다.
softNN loss의 경우 기존에 one postivie - multiple negative sample로 계산하는 loss를 보완하기 위해 제안된 loss이다.
논문의 abstract에 따르면
" hidden layers에서 각각 다른 클래스들 간의 entanglement of representations를 최대화하는 것이 마지막 레이어의 변별력에 이득이 된다"라고 한다.
거두절미하고 식부터 바로 보자
식은 사실 별게 없다 (x는 batch(b)의 샘플, y는 클래스)
instance i 에 대해서 i를 제외한 i와 같은 클래스인 모든 instance들에 대해 거리를 구한다.
그리고 그 거리에 exp를 취해주고 평균을 구하면 된다
이 softNNloss를 적용할 수 있는 참고할 만 한 코드도 함께 첨부한다.
위의 코드를 응용(?) 해 보았다
import torch
batch_label = torch.Tensor([1,1,2,3,4,5,2,1])
positive_mask = torch.stack([torch.eq(batch_label,i) for i in batch_label]).float()
diagonal_inf = torch.diag(torch.stack([torch.tensor(-float("inf"))] * positive_mask.shape[0]))
at_least_two_positives_mask = (positive_mask.sum(dim=1) > 1.0).unsqueeze(1).float()
positive_mask *= at_least_two_positives_mask
# as of Frosst et al 2019
score = torch.rand(8,8)
#score = -1 * torch.cdist(input_1, input_1, p=2).square() / 1.0
score += diagonal_inf
import torch.nn.functional as F
loss = torch.log((F.softmax(score, dim=1) * positive_mask).sum(dim=1) + torch.finfo().eps)
한 batch에 대해서 gt label이 [1,1,2,3,4,5,2,1] 라고 해보자 (batch size 8)
배치에 있는 라벨에 대해서 자신과 같은 라벨인 아이들을 모은다.
즉 positive_mask은 다음과 같다
tensor([[1., 1., 0., 0., 0., 0., 0., 1.],
[1., 1., 0., 0., 0., 0., 0., 1.],
[0., 0., 1., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0., 1., 0.],
[1., 1., 0., 0., 0., 0., 0., 1.]])
그리고 각 계산된 변수들은 다음과 같다
# diagnonal_inf
tensor([[-inf, 0., 0., 0., 0., 0., 0., 0.],
[0., -inf, 0., 0., 0., 0., 0., 0.],
[0., 0., -inf, 0., 0., 0., 0., 0.],
[0., 0., 0., -inf, 0., 0., 0., 0.],
[0., 0., 0., 0., -inf, 0., 0., 0.],
[0., 0., 0., 0., 0., -inf, 0., 0.],
[0., 0., 0., 0., 0., 0., -inf, 0.],
[0., 0., 0., 0., 0., 0., 0., -inf]])
# at_least_two_positives_mask
tensor([[1.],
[1.],
[1.],
[0.],
[0.],
[0.],
[1.],
[1.]])
# positive_mask *= at_least_two_positive_mask
tensor([[1., 1., 0., 0., 0., 0., 0., 1.],
[1., 1., 0., 0., 0., 0., 0., 1.],
[0., 0., 1., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0., 1., 0.],
[1., 1., 0., 0., 0., 0., 0., 1.]])
# score += diagonal_inf
tensor([[ -inf, 0.0690, 0.1157, 0.5534, 0.8878, 0.1508, 0.0292, 0.6182],
[0.6962, -inf, 0.1318, 0.4295, 0.3354, 0.2861, 0.0207, 0.7232],
[0.3852, 0.5831, -inf, 0.2593, 0.3734, 0.9604, 0.3205, 0.4382],
[0.8570, 0.4590, 0.4989, -inf, 0.6128, 0.6770, 0.1192, 0.3382],
[0.9990, 0.8546, 0.5761, 0.0645, -inf, 0.9183, 0.7525, 0.2062],
[0.5688, 0.8475, 0.9995, 0.6783, 0.3639, -inf, 0.8031, 0.9515],
[0.6795, 0.8438, 0.0714, 0.5123, 0.2669, 0.5641, -inf, 0.0841],
[0.4445, 0.1030, 0.7346, 0.0428, 0.1578, 0.2113, 0.6154, -inf]])
at_least_two_positive_mask를 구하는 이유는 어차피 1개인 경우는 자기 자신이기 때문
score에 i=j인 부분에 -inf를 더해주는 이유는
자기 자신과의 similarity가 계산된 부분을 제외하고 또 softmax를 취하면 0이 되기 때문
score는 편의상 임의의 rand 값들을 취하였는데 원하는 distance 거리 계산을 하면 된다
tensorflow soft nn code )
https://github.com/tensorflow/similarity/blob/master/tensorflow_similarity/losses/softnn_loss.py
'💗 AI > 💡 Theory' 카테고리의 다른 글
[모두팝] 생성모델부터 Diffusion 1회 내용 정리 (0) | 2023.10.05 |
---|---|
Overfitting(과적합), Underfitting(과소적합) 원인 및 해결 방법 (1) | 2023.02.16 |