페이지

2022년 2월 11일 금요일

라벨 데이터가 적은 경우에도 딥러닝을 통한 영상 분류 성능을 보장할 수 있을까? – 2편

 1편에서 자기 지도 학습, SimCLR 프레임워크, 이미지 증식 등을 살펴보았다. 2편에서는 손실 함수에 대해서 살펴보도록 하자.

 

유사도 측정

 1편에서 대조 학습에 대해 라벨이 없는 이미지 두개의 쌍을 비교하여 유사한 것은 가까이 모이도록 하고 다른 것은 멀리 밀어내도록 하는 방식으로 학습하는 것이라고 하였다. 왜 이런 방식의 학습을 하는 걸까? 지도 학습에서는 라벨이 부가된 정답인 y 가 있고 오차는 y 와 모델이 예측한 y^ 의 차이로 산출한다고 하면, 라벨이 없는 비지도 학습에서는 이미지 데이터들의 묘사(representation)들을 이해하기위해 앞의 데이터증식에서 설명한 바와 같이 우선 하나의(anchor) 이미지를 증식하여 만들어진 두 이미지 간의 유사도를 측정한다. 이 두 이미지는 유사도가 매우 높을 것이고 이를 기반으로 anchor 이미지와 다른 이미지의 유사도는 낮을 것이기 때문에 이러한 오차들을 multi-class 분류 문제에 적용하는 categorical cross-entropy 손실 함수로 연산 처리한다.

이를 좀 더 자세히 들여다보면, 두 이미지가 동일한 1편 그림 5SimCLR 프레임워크를 통과되었기 때문에 최종 출력 128 bit 임베딩 zi, Zj 간의 벡터 유사도를 측정하면 이 두 벡터 간의 유사도가 가깝게 나올 것이다. 만약 두개의 다른 이미지가 SimCLR 모델을 통과한 후 비교된다면 유사도가 멀게 나온다. 이 유사도는 아래 그림 1과 같이 cosine similarity 로 측정한다. ①번은 코사인 유사도 식이다. 아래 코드는 파이선 넘파이 linear algebra 함수를 사용한 코사인 유사도 함수이며, 분자는 zi, Zj 간의 벡터 곱이고 분모는 np.linalg.norm 즉 행렬 norm 들의 곱이다. 여기서 Ʈ 는 출력 카테고리 간의 구분을 명확 혹은 부드럽게 출력하는 온도 계수이다.


 

 

<그림 1. 코사인 유사도>


아래 그림 2 와 같이 고양이와 코끼리 데이터가 batch에 있을 때 임의의 복제를 통해 ①의 고양이 쌍, ②의 코끼리 쌍의 이미지가 생겨났다고 가정해보자. 이 경우 batch size N =2 이고 증식된 전체 이미지는 2*N = 2*2 = 4 개 데이터가 훈련 데이터로 준비된다.



<그림 2. batch 이미지로부터 유사 이미지 쌍의 준비>


손실 연산

   SimCLR 이 사용하는 대조 손실은 NT-Xent los(Normalized Temperature-Scaled Cross-Entropy Loss)이라고 불리는 손실을 사용한다, 자 우선 앞의 그림 2의 ①, ②와 같이 증식된 이미지 쌍 2개가 있다고 하자. 이중 ①번 고양이의 증식된 이미지 쌍이 유사할 확률을 구하기위해 아래 그림 3 과 같이 softmax 함수를 적용해보자.


<그림 3. ①번 이미지쌍이 유사할 확률을 구하는 softmax>


  이 소프트맥스 연산은 각 쌍들에 대해서 ①번 이미지쌍의 2번째 고양이 이미지가 1번째 고양이 이미지와 가장 유사할 확률을 구하는 것과 동일하다. 여기서, 배치에 있는 모든 나머지 이미지들은 다른 이미지로 샘플 된다(negative pair). , 샘플 중에서 negative pair 를 샘플링하지 않고 이런 식으로 배치안에 2(N-1)negative sample 로 간주한다.

 그 다음, 손실은 위 그림 4의 연산에 음수의 로그를 취함으로써 계산된다. 이 공식을 잡음 대조 예측(Noise Contrastive Estimation(NCE)) 손실이라고 하고 아래 그림 4와 같다.


<그림 4. NCE 손실 함수>


  여기서   indicator function이라고 하며 k i 가 같지 않을 때 1로 평가한다. 이 뜻은, anchor 이미지(Zi)와 유사도 측정이 되는 대상 이미지(Zk)가 같지 않을 때 1이 된다는 뜻으로, 다른 말로 하면 서로 다른 이미지들의 유사도 측정이라는 뜻이다.  앞의 그림 4에서 증식된 고양이 쌍의 2번째와 1번째와 가장 유사할 확률을 구하는 것과 같다고 설명했는데, 이런 이유에서 이번에는 2번째 고양이 이미지를 anchor image 로 하여 위치들을 바꾸어서 유사도 측정을 하고 결국 이 둘의 평균으로 손실을 측정한다.

 따라서, 고양이와 코끼리 쌍 모두의 손실 연산은 아래 그림 5과 같이 ① 고양이 증식된 쌍의 순서를 바꿔가며 손실을 구한 것과 ② 코끼리 증식된 쌍의 순서를 바꿔가며 손실을 구한 것의 평균이 된다.



<그림 5. 배치 안의 모든 쌍의 손실 연산 후 평균 계산>


자 그럼, 코드를 직접 보면서 NCE loss 가 산출되는 내용을 살펴보자.



<그림 6. nce loss labels 초기화>



  ①번 실행의 결과로 tensor([0, 1, 2, 3, 0, 1, 2, 3])    벡터가 생성된다. 여기서 batch_size = 4,  n_views = 2 (증식될 이미지 쌍을 2개로 함)로 처음 4개는 입력된 이미지, 나머지 4개는 증식(augmented)된 이미지 임을 알 수 있다. 대조 학습에서 batch 수가 클수록 성능이 향상된다고 하였는데, batch를 예를 들어 SimCLR 논문처럼 4096 정도의 크기로 하면 메모리 부족 등의 제약으로 일반적인 컴퓨팅 환경에서 사용이 어렵다. 본 프로젝트에서는 batch4로 설정한다.
   ②   번 실행의 결과로 아래와 같은 labels 행렬이 생성됨


③  모델을 통과한 feature (z) 에 대해서 정규화(norm)

    유사도 함수를 산출

여기서 코사인 유사도 함수 공식을 다시한번 보자



분모의 정규화는 위의 ③번 과정으로 산출되었으므로, 결국 코사인 유사도는 분자의 np.dot , ④번 feature 들 간의 np.dot 으로 산출된다.



<그림 7. mask labels 그리고 유사도 함수>


그 다음에, 위 코드의 ①은 8X8 행렬에서 왼쪽 위에서 오른쪽 아래 대각선으로 true 가 생성되는 mask 행렬을 생성. ②는 labels에 대하여 이러한 mask를 적용함으로써 아래 그림 9 의 왼쪽과 같이 대각선 이 1에서 0으로 변경된 행렬이 생성됨. 4개 증식 이미지와 4개 입력 이미지 상호간에 1 로 표시되는 영역들이 있다. 이는 batch에서 로드 된 8개 이미지(N*n_views = 4 * 2 = 8) 상호간에 유사도가 1인 즉, 다시 말하면 같은 이미지를 뜻한다.

③의 유사도 행렬 연산 후에는 아래 9의 오른쪽과 같이 positives 들이 mask 되어 걸러진다. , Similarity matrix에서 유사도가 1(같은) 이미지들을 Labels[~mask]를 통해 걸러낸다.



<그림 8. 라벨에 마스크 적용 후 유사도 행렬 연산>



<그림 9. logit labels 생성>


그 다음, 위 그림 9의 ①의 수행을 통해 아래 그림 10의 왼쪽 positives 8 X 1 행렬이 생긴다. 이 행렬은 4개 입력 이미지와 4개 증식 이미지 간에 유사도가 1인 즉 같은, 이미지들을 갖는다. ②의 수행을 통해 아래 그림 10의 오른쪽 negatives 8 X 6 행렬이 생긴다. 왼쪽의 positives를 제외한 나머지 값들을 내포한다. ③은 이 positives negatives 행렬을 dim=1 이므로 수평방향으로 결합한다. 따라서 결과는 8 X 7의 행렬로 만들어진다. ④의 labels  1 X 8 벡터가 만들어지고 positive 샘플들의 인덱스들을 내포한다. 즉 각 행의 0번째가 positives임을 나타낸다.

 

지금까지 1편에 이어서 2편에서 손실 함수에 대해서 살펴보았다. 3편에서는 손실 함수의 나머지 부분과 선형분류기를 추가하여 성능평가를 하는 부분을 살펴보겠다.