본문 바로가기

데이터 과학/딥러닝(Deep Learning)

CenterLoss의 구현

CenterLoss는 랜덤으로 정의한 각 클래스 중심으로 부터 샘플이 멀수록 패널티를 주어 클래스간 분리성과 클래스 내의 분산을 줄이는 방법으로 학습되도록 돕는다(Seperable Inter-Class differences and Minimizing Intra-Class variations)

 

Center Loss의 식을 구성하는 각 원소는 아래와 같은 차원을 지닌다.

x : (Batch_Size(32), feat_dim(2)) 

c_yi : (num_classes(10), feat_dim(2)) 의 사이즈를 지닌다.

 

각 원소의 사이즈가 위와 같을 때 아래의 빨간 박스 부분을 어떻게 코드로 구현하는지 살펴본다.

 

위의 식을 풀어 쓰면 아래와 같다

(1) 먼저 $x_i$(32 x 2)를 제곱한다 --> 열 방향으로 더한다(32 x 1) --> (batch_size, num_classes)로 늘려서 (32 x 10) 사이즈가 되게 한다 : $x_i^2$ 계산

(2) $c_{yi}$(10 x 2)를 제곱한다.  --> 열 방향으로 더한다(10 x 1) -->  (num_classes, batch_size)로 늘려서 (10 x 32)가 되게 한다 : $c_{yi}^2$ 계산

(3) (2)에서 구한 식을 Transpose해서 (1)에 더한다.

(4) 이후 파이토치 .addmm_ 매소드를 이용해서 $x_i$ (32 x 2)와 $c_{yi}$ (10 x 2) 를 곱해서 (32 x 10)이 되게 한다. 그리고 (3)에서 나온 결과와 더한다. $ -2 * x_{i}^2 * c_{yi}^2 $ 계산

 

(※ (1) ~ (4) 과정을 거치면 샘플 (32개)각 각 클래스에 대해 계산한 거리가 나온다.

★★이 때 올바른 클래스의 중심으로 다가가길 희망하므로(Minimizing Intra-Class variations) 정답 라벨의 거리만 사용한다. 따라서, 아래의 과정을 진행한다.)

 

(5) [32] 사이즈의 샘플 라벨을 [32, 10] Boolean One-hot 으로 만든다.

(6) Boonlean One-hot 마스킹과 위에서 구한 거리 행렬을 곱한다.

(7) 32개 원소를 다 더한 후 Batch_size 로 나눠 로스 값 평균을 구한다

batch_size = x.size(0)
# (1) (2) (3)
distmat = torch.pow(x, 2).sum(dim=1, keepdim=True).expand(batch_size, self.num_classes) + \
torch.pow(self.centers, 2).sum(dim=1, keepdim=True).expand(self.num_classes, batch_size).t()

# (4)
distmat.addmm_(x, self.centers.t(), beta=1, alpha=-2)

# (5)
classes = torch.arange(self.num_classes).long()
labels = labels.unsqueeze(1).expand(batch_size, self.num_classes) # [32] -> [32, 1] -> [32, 10]
mask = labels.eq(classes.expand(batch_size, self.num_classes))

#(6)
dist = distmat * mask.float() # (32, 10) * (32, 10) element-wise 곱
#(7)
loss = dist.clamp(min=1e-12, max=1e+12).sum() / batch_size

 

 

 

 

 

 

 

반응형

'데이터 과학 > 딥러닝(Deep Learning)' 카테고리의 다른 글

Triplet Loss 구현  (0) 2022.06.09
LSTM Autoencoder 설명  (0) 2021.05.28
공분산(Covariance) 정리  (0) 2021.02.12
PCA(주성분 분석) 정리  (0) 2021.02.10
Autoencoder 설명  (0) 2021.02.06