이번 강의는 Self-Supervised Learning을 다룬다. 지금까지 우리는 다양한 computer vision task들을 살펴보았다. image들에서 학습한 feature들은 (feature는 embedding, latent space와 같은 표현으로 불리기도 한다.) 다양한 task들을 해결하기 위한 좋은 representation이었다. 그러나 요즘의 트렌드는 large-scale data를 이용해 모델을 훈련시키는 방식으로 변해가고 있다. 이런 large scale dataset을 만들 때 우리가 마주하게 되는 문제는 엄청난 양의 labeled data가 필요하다는 것이다. 우리는 지금까지 data x와 label y를 짝지어서 모델에게 제공하고, 이를 통해 모델이 학습할 수 있도록 하는 supervised learning을 사용했다. 이러한 방식을 사용해서 large-scale dataset을 만드려면 데이터 라벨링을 다 해야 하는 것이고, 이는 몹시 귀찮아질 수 있다. 이 문제를 어떻게 해결할 수 있을까?
이러한 배경에서 등장한 것이 Self-Supervised Learning이다. Neural Network들을 label 없이 훈련시킬 수는 없을까? 라는 motivation에서 나오게 된 방식이다.
먼저 Self-Supervised Learning의 기본적인 틀에 대해서 알아보자.

SSL은 두 가지 단계로 볼 수 있다. pretext task, 그리고 downstream task이다. 위의 그림에서는 위쪽이 pretext, 아래쪽이 downstream task에 해당된다.

Pretext task는 data annotation 없이, label이 없는 데이터를 이용해 학습을 진행한다. unsupervised learning으로도 생각할 수 있지만, 여전히 supervised learing에서 사용한 objective(classification, regression)는 사용한다.
그렇다면 정확히 어떤 task를 pretext task로 사용할까? 아무래도 label이 없는 데이터를 사용해야 하니 label이 필요하지 않지만, 좋은 퀄리티의 feature를 생산할 수 있는 task를 pretext task로 정의한다. 예를 들면 Image Completion, rotation prediction jigsaw puzzle, colorization 이 있다.
좋은 pretext task의 조건은 아래와 같다.
- 모델이 좋은 feature를 학습할 수 있는 task여야 할 것
- 자동적으로 pretext task를 위한 label을 생성할 수 있을 것.
사실 따로 언급하진 않았지만, pretext task에서도 label을 사용하긴 한다. 단지 그것이 인간이 라벨링하지 않아도 되는 방식이라 '자동적으로'라는 표현이 2번에 붙은 것이다. 뒤에 pretext task들에 대해 더 자세히 다루기 때문에 지금은 일단 이 정도로 넘어가도록 하자.

Downstream task는 내가 지금 해결하려고 하는 task이다. 여기서 사용하는 dataset은 내 문제를 해결하기 위해 필요한 dataset이다. 크기가 pretext task에서만큼 크지 않고, label이 있는 크기가 작은 dataset으로 이해하면 될 것 같다. 정리하자면, pretext task에서 얻은 좋은 feature들을 내가 해결하려는 downstream task에 맞게 fine-tuning 하는 것이다. 이때 pretext task는 unlabeled data, downstream task는 labeled data를 사용한다. 사실 우리가 문제 해결을 위해 더 집중해야 하는 것은 좋은 feature를 얻는 것, 즉 pretext task이다.
&nsbp 또 하나 중요한 것은 SSL method들의 평가 방법이다. 어떻게 평가해야 모델들의 성능을 정확히 비교할 수 있을까? 평가 방법은 여러 가지가 있다.
label 없이 훈련된 pretext task에서의 모델의 성능을 평가한다.
학습된 representation의 quality를 평가한다. 이것도 여러 가지 방법이 있다.
모델이 다양한 데이터셋이나 variation에 얼마나 강건한지, 어느 정도의 generalization 성능을 보이는지 평가한다.
모델의 training time과 자원 사용량을 평가한다.
학습된 representation을 downstream task에서 fine-tuning 시켜 그 downstream task에서의 성능을 평가한다.

지금까지 살펴본 SSL의 전반적인 과정은 위의 구조도 하나로 요약할 수 있다.
- Unlabeled Data로 pretext task 학습.
- Downstream task에서의 supervised learning
-> 적은 양의 labeled data로 학습하고, 모델에는 shallow한 네트워크를 학습된 encoder에 붙여서 훈련시킨다.- Evaluation : downstream task에서의 성능 평가. ex) Classification, detection.. etc.
SSL은 robotics, reinforcement learning, Language Modeling, Speech Synthesis 등 많은 분야에서 사용될 수 있다고 한다.
이제 pretext task에서 어떤 task들을 학습하는지 자세히 알아보자.
이미지가 회전한 각도를 맞추는 task이다. 여기서의 가설은 모델이 특정 object가 어떤 각도에 놓여 있을 때 제대로 놓여 있는 것인지 안다는 것이다. 즉, 모델이 visual commonsense가 있다고 생각하고 unperterbed object가 무엇인지 안다는 의미이다.

보통은 0, 90, 180, 270 4가지 class에 대해 4-way classification을 많이 사용한다. 이미지가 0, 90, 180, 270도 중 어떤 각도로 회전되어 있는지 맞추는 classification task인 것이다. 이러한 방식으로 모델을 학습했을 때 좋은 representation을 얻을 수 있었고, 초기 layer들을 freeze하고 나머지 layer들만 downstream task(아래 사진에서 CIFAR10)에서 fine-tuning 했을 때 좋은 결과를 얻었다고 한다.

위의 그래프에서 눈여겨 볼 것은 pretrained model은 시작부터 비교적 좋은 성능으로 시작한다는 것이다. 이것이 pretext task에서 학습한 representation의 퀄리티가 좋다는 것을 보여주는 부분이라고 해석할 수 있다.

ImageNet dataset에서도 Supervised Learning을 뛰어넘지는 못하지만 SSL method가 어느 정도는 그 성능에 비슷한 수치를 내는 것을 볼 수 있다.

Feature들을 시각화해보면 SSL은 object들의 여러 부분을 보는 등 holistic한 경향이 있고, Supervised Learning은 object의 한 부분만 보는 경향이 있다고 한다.
이 task는 이미지는 3x3의 patch들로 나눈 후, 특정 patch가 어떤 위치에 들어가야 하는지 맞추는 task이다.

위의 사진을 보면, 파란색 칸이 쳐져 있는 center patch는 reference patch이다.이를 기반으로 주변 8개의 위치 중 현재 내가 보고 있는 patch가 어디에 들어가야 할 지를 예측하면 되는 것이다. 이것 또한 8-way classification으로 생각할 수 있다.
이 task는 우리가 직전에 살펴본 patch location prediction task의 follow up paper에서 연구한 task이다. 똑같이 이미지를 3x3 grid로 나누고, 그 patch들을 섞은 상태에서 맞는 순서를 모델에게 맞추라고 하는 것이다.

그러나 이렇게만 하면 경우의 수가 너무 많다. 9! 가지의 경우의 수가 나오기 때문이다. 따라서 저자들은 64-way classification이 되도록 미리 table을 만들어 놓고 모델이 어떤 것이 정답인지 맞추도록 하는 것을 목표로 했다.

이 task는 이미지의 특정 부분을 masking하고 모델이 이 부분을 채우는 것을 목표로 하는 task이다. 일종의 reconstruction이기 때문에 encoder-decoder 구조를 사용한다.

Loss는 Adversarial Loss를 사용하는데, 이는 다음 강의에서 더 자세히 다룬다고 한다.


다음은 Image Coloring이다. Grayscale의 이미지를 컬러로 바꿔주는 task이다. Lab이라는 color space를 사용하고, L은 lightness, a,b 채널이 컬러 채널을 의미한다. L,a,b 채널을 모두 concat하면 우리에게 익숙한 컬러 이미지가 된다고 한다. L channel이 주어졌을 때 ab channel을 예측하는 것이 모델의 task이다.
이러한 방식은 split-brain autoencoder의 등장으로 이어지게 되었다.

이 모델의 아이디어는 cross-channel prediction이다. 모델은 두 가지의 function을 배우게 된다. 먼저 input image를 L/ab channel로 나눈다. 이렇게 나뉜 이미지를 이용해 각각 다른 function을 배우게 되는데, 그 function들은 아래와 같다.
- L-> ab (위의 사진 상 )
- ab -> L (위의 사진 상 )
이렇게 배운 두 가지 function의 output을 더해 predicted image를 만들고, loss 계산에 이용하는 방식이다. Lab color space 뿐만 아니라 다양한 color space에도 적용할 수 있다는 장점이 있다.

다음은 Video Coloring이다. 위의 사진과 같이 reference frame을 기준으로 다른 frame들의 색을 채우는 task이다. 여기서의 가설은 frame 간의 colorization을 배우는 것이 모델에게 tracking objects, regions과 같은 것을 배우게 해준다는 것이다.
frame 간의 colorization을 할 때 중요한 것은 이전 frame의 특정 object가 현재 frame에서는 어디에 있는가? 이다. 그래서 이러한 pointer를 찾고, 그 pointer를 기반으로 frame의 다른 object들의 위치를 파악하고, 같은 object의 색깔을 복사해서 넣게 된다.

구체적으로 어떻게 이러한 pointer를 찾는다는 것일까? 이는 attention map을 통해 학습된다.

attention map은 target frame의 이 pixel이 reference frame의 어떤 부분을 참고해야 하는가? 에 대한 정보를 담고 있다. 위의 사진을 보면, Reference와 target frame을 모두 CNN에 넣고, feature embedding을 얻는다. 만약 같은 object가 있다면, 같은 형식의 feature를 만들 가능성이 높다. 그리고 나서 attention map을 계산하게 되는데, target frame의 특정 위치 j와 reference frame의 모든 픽셀들을 비교해서 얻는다. 마지막으로 reference frame pixel들의 색을 가지고 Attention map의 비율대로 weighted sum을 해서 target frame의 색을 얻게 되는 것이다.
&nsbp 지금까지 우리가 배운 SSL의 한 가지 방법론으로 MAE가 있다. MAE는 이미지의 더 많은 비율(50% 혹은 75%)이 masking 된 상태에서 reconstruction을 진행하는 task이다.

input은 위의 사진처럼 masked image가 사용되고, masking 된 비율은 50% 혹은 75%이다. unmasked patch들은 encoder에게 주어지고, 그를 통해 feature를 얻는다. 이 feature들은 decoder에 사용된다.
ViT와 비슷하게, input을 먼저 non-overlapping patch들로 나눈다. 그리고 uniform하게 patch들 중 75%를 sampling해서 그들을 masking한다. 이렇게 높은 비율을 masking하는 것은 task를 더 어렵지만 의미 있게 만들어 준다. 또, 이렇게 masking을 한다면 encoder에 들어가는 patch의 비율이 적어지기 때문에(=적은 계산량) encoder의 capacity가 늘어날 수 있게 해준다.
Encoder는 unmasked patch들만 다룬다. patch들에 positional embedding과 linear projection을 적용한다. 이때 transformer block을 사용한다. 또, 실제 이미지의 25% 정도만 사용하기 때문에 encoder의 크기는 굉장히 크다. decoder와의 per token computation을 비교하면 encoder가 9배보다 더 많다고 한다.
Decoder 단에서는 shared mask token이라는 개념이 등장한다. shared mask token은 Transformer에서의 class token과 같은 trainable parameter이다. 이들은 masked patch들 자리에 들어가게 된다. shared mask token은 가려진 patch들의 average를 나타내는 patch 정도로 생각하면 좋을 것 같다. 여기에 positional embedding이 더해져 decoder로 들어가게 된다. 이렇게 얘기하면 이해가 잘 되지 않을 수도 있을 것 같다. 다시 한 번 정리해보자.
- encoder output은 masked patch들을 제외한 것이므로, 모든 patch들을 복원해야 하는 decoder 입장에서는 patch 수가 부족하다.
- 이를 해결하기 위해 shared mask token을 적용한다. 이는 하나의 벡터이고, 이름에서 도 알 수 있듯이 모든 masked patch 자리에 공통된 shared mask token이 들어간다.
-> shared mask token은 가려진 patch들의 average 정도로 생각하면 된다.- 이렇게만 하면 위치를 구별하기 어려우니, positional embedding을 같이 적용해서 위치를 구별할 수 있게 해준다.
-> 그림 상에서는 회색 patch들이 shared mask token을 의미한다.- Decoder는 이러한 정보를 기반으로 원래의 image를 복원해낸다.
Decoder는 transformer block -> linear projection (pixel 복원을 위한 설계) 의 구조를 가진다. 또, decoder는 복원을 위해서만 존재하고, 우리의 목적은 언제까지나 더 좋은 퀄리티의 encoder를 만드는 것이기 때문에 training 이후에는 사용하지 않는다.
MSE(mean squared error) Loss를 사용하며, masked patch들에 대해서만 loss를 계산한다.

training이 끝난 후 downstream task에 적용할 때 사용할 수 있는 방식은 Linear Probing, Full fine-tuning 두 가지라고 논문의 저자들은 말한다.
Linear Probing은 pre-trained model은 freeze 시킨 후 그 뒤에 linear layer 하나만 추가시켜서 학습시키는 방식이다. 이러한 방식은 pre-trained model의 representation quality를 평가하기 위해 많이 사용된다.
Fine-tuning에서는 pre-trained model이 freeze 되어 있지 않고 추가된 하나의 linear layer와 함께 학습된다. 이 방식은 새로운 task에 대한 모델의 잠재적인 성능을 최대 한도로 보여주는 방식이다.
이렇게 MAE의 구조를 살펴봤다. MAE는 사실 선택할 수 있는 modeling, hyperparameter가 굉장히 많다.

지금까지 살펴본 pretext task를 정리해보자.

지금까지의 pretext task는 몇 가지 문제가 있다.
- 각각의 pretext task를 생각해내는 것은 짜증나는 작업이다.
- pretext task를 통해 학습된 representation은 general 하지 않을 수 있다.
이러한 motivation에서 더 general한 representation을 만들어내고자 연구된 것이 Contrastive Representation Learning이다.

Contrastive Representation Learning의 가장 기본적인 아이디어는 같은 category에 있는 pixel, object는 representation space 내에서 서로 가까이 붙이고, 다른 category에 있는 것들은 멀리 떨어지게 만들자는 것이다. 이러한 아이디어에서 나온 모델들로는 SimCLR, MOCO, CPC, DINO 등이 있다.
reference image가 라면, 가까이 붙어야 하는 positive sample들은 , 떨어져야 하는 negative sample들은 로 표현한다.

그림으로 표현하면 위와 같을 것이다. 우리가 원하는 궁극적인 목표를 수식으로
와 같이 나타낼 수 있다. positive pair 의 score가 negative pair 의 score보다 더 높은 점수를 얻게 하는 encoder를 학습시켜야 하는 것이다.
이제 loss function을 정의해보자.

Contrastive Learning은 위와 같은 loss function을 사용한다. 의미를 생각해보자. 분자, 분모에 모두 있는 는 positive pair의 score를 의미한다. 분모에 있는 는 negative pair인 N-1개의 sample들의 score 합을 의미한다. -(positive pair의 score)/(전체(N개의 sample)의 score 합) 이므로, 전체 score 중에서 정답 score의 비율을 최대한 높이는 loss function인 것이다. (loss function은 보통 최소화하기 때문에, 정답 score의 비율을 최대한 높이는 것 = - 정답 score의 비율을 최소화 하는 것으로 바꾼 것이다.) 앞에 (-) 부호가 붙은 것은 loss fuction을 최소화 하기 위해서이다.
이 loss function은 가만 보면 cross entropy loss와도 비슷하다. N-way softmax classifier에서 우리는 이러한 형식의 식을 봤었다. 이러한 loss는 보통 InfoNCE Loss라고 불린다.

SimCLR은 original image 를 두 개의 random한 transformation을 적용한다. 이를 통해 나온 결과물이 이다. 이들은 을 통해 각각 representation space로 가고, 각 이미지는 representation 로 변하게 된다. 그리고 나서 nonlinear/linear projection network 를 통해 contrastive learning을 위한 space로 projection 된다. 최종적으로 가 contrastive learning에 사용되는 것이다.
representation space와 contrastive learning space로의 projection과 같이 projection이 많이 일어난다. 특히 로의 projection은 굳이 왜 하지? 라는 생각이 들 수 있다. 그냥 feature space에서 contrastive learning을 진행할 수 있을 것 같기 때문이다. 그런데 이것은 design choice였다고 한다. 이러한 환경에서 모델을 훈련 시키는 것이 더 좋은 결과를 가져다 주었다고 한다.

SimCLR의 전체적인 알고리즘이다. 우리가 앞서서 이야기 했던 random한 transformation은 data augmentation 테크닉 중 하나를 random하게 적용한다. 또한, InfoNCE loss를 사용한다. Score Function은 cosine similarity를 사용하고, 좋은 결과를 내기 위해 굉장히 큰 batch size가 필수적이라고 한다. 하지만 자원에 따라서 언제나 굉장히 큰 batch size를 갖기는 힘들다. 그래서 이를 어느 정도 해결하려고 등장한 것이 MoCo이다.

MoCo는 SimCLR에서의 구조와 비슷한 구조를 사용하지만, 큰 batch size를 피하기 위해 negative pair의 queue를 둔다. 는 현재 보고 있는 batch data이고, 는 이전의 batch를 의미한다. 현재 batch는 encoder에 태워서 를 얻고, 이전의 batch는 momentum encoder에 넣어서 을 얻는다. 이때 는 SimCLR에서 본 feature representation이라고 생각하면 된다. 이때, momentum encoder는 backprop을 통한 update를 진행하지 않는다. 그 batch 크기가 너무 크기 때문이다. 대신에 momentum update rule을 이용해 업데이트 한다. momentum encoder의 weight들은 query encoder weight의 exponential moving average가 되는 것이다.
batch 내의 negative sample만 보는 SimCLR과 달리, MoCo는 모델이 batch 내의 negative sample만 보는 것을 방지하기 위해 batch가 달라져도 사용할 수 있는 negative sample들을 queue에 두는 것이다.

전체 알고리즘을 보면, positive pair 를 생성한 후, negative sample을 가지고 있는 queue를 이용해 학습에 사용한다. backprop은 query encoder에서만 적용하고, momentum encoder는 momentum update를 사용한다. 마지막에 queue를 업데이트하고 이를 계속 반복한다. 이후에 MoCo v2, v3까지 나왔다고 하니 나중에 찾아봐야겠다.
전반적인 내용을 엄청 자세히 다루지는 않았지만, SSL의 기본적인 틀과 몇 가지 방법론들을 훑어봤다는 것에 의의를 두는 것이 좋을 것 같다. 개인적으로 SSL을 공부하며 이 분야에 흥미를 느끼게 되었다. 이 분야의 최신 논문들을 좀 훑어봐야겠다.