z [Constrastive Learning] Momentum Contrast for Unsupervised Visual Representation Learning : MoCo v1
본문 바로가기

Computer Vision

[Constrastive Learning] Momentum Contrast for Unsupervised Visual Representation Learning : MoCo v1

728x90

Constrastive Learning

이번에 처음으로 Constrastive Learning에 대해 공부하게 되었습니다. 이에 대해 천천히 복습할 겸 작성하겠습니다 :)

 

Constrastive Learning의 동기

ImageNet처럼 방대한 데이터에 대해 학습시키다 보면, 비슷한 객체에 대한 결과의 값들을 확인했을 때 각 높은 확률 값을 가짐을 알 수 있습니다. 이게 무슨 뜻이냐면 단순한 물체, 가구 부터 동물까지 들어있는 방대한 데이터셋이 있다고 했을 때 말 사진이 들어갔을 때 얼룩말과 같은 비슷한 클래스에 대해서는 높은 확률 값을 지니고, 별로 관련 없는 대상인 의자, 책상 등에는 낮은 확률값을 갖게 됩니다.

사실 모델에 데이터를 넣을 때 class 정보는 semantic labeling이 아니라 one hot encoding을 사용한 어떠한 관계성도 갖지 않는 정보로 만들기 때문에 살짝 의아할 수 있습니다.

 

근데 이런 특성들을 사용하면 label 없이 좋은 representation을 얻을 수 있지 않을까요?

 

-> 이 아이디어에서 출발하게 됩니다.

 

Contrastive Learning 기본적인 방법

"Contrastive : 대조적인" 이라는 단어에서도 알 수 있듯이 이 방법은 각 데이터간의 대조로부터 학습하는 방법입니다.

 

가장 단순한 아키텍쳐는 두가지의 encoder로 만듭니다. 하나는 현재 데이터에 대한 feature를 얻기 위한 encoder, 다른 하나는 과거 데이터(비교할 것들)에 대한 feature를 얻기 위한 encoder입니다. 여기에서 현재 데이터는 보통 query라고 부르고 과거 데이터에는 key라고 불립니다. 그리고 이 key 데이터들은 memory bank라는 곳에 저장됩니다. (MoCo에서는 그냥 dictionary라고 부름. 실제로 memory bank는 더 큰 사이즈의 dictionary라고 명명하고 있음.)

 

이 memory bank에 저장된 것들에서 현재 data와 같은 객체에 대한 과거 feature를 positive로, 다른 것들은 negative로 둡니다.

그래서 훈련 시 query와 positive의 similarity, query와 negative의 similarity를 구한 후 positive의 경우엔 큰 값을 갖고 negative의 경우엔 작은 값을 갖도록 합니다. (가까이 가게 하고, 멀리 가게 한다.)

 

위와 같은 방법을 적용해주기 위해 InfoNCE (Noise Contrastive Estimation)라는 loss를 사용하게 됩니다.

 

 

기본적으로 encoder를 거친 각 feature들은 L2 Normalization를 적용해주기 때문에 원점을 중심으로 하는 hypersphere를 이루게 됩니다.


MoCo V1

Abstract

MoCo는 unsupervised visual representation learning 입니다.

MoCo는 dynamic dictionary가 클수록 좋고 key가 consistent 할 수록 좋다고 가정합니다. (consistent : query와 일관되도록.)

 

queue 형태의 dynamic dictionary와 Moving averaged encoder를 사용합니다. (python에서는 dyanmic dictionary를 그냥 list로 사용하면 된다.)

 

이전의 Memory bank는 여러 epoch이 진행되면서 계속 과거 feature들을 넣었습니다. 하지만 이는 memory 관점에서 너무 과부하가 심합니다. 그리고 훈련이 지속되면서, 현재 시점에 가까운 key일 수록 갖는 의미가 높습니다. 그래서 이전의 memory 과부하를 막기 위해 queue 형태의 dynamic dictionary를 구상합니다.

 

queue의 형태이기 때문에 FIFO에 입각하여 oldest data는 dequeue 되게 됩니다.

mini batch단위로 훈련을 진행하게 되는데, key에 대한 encoder의 output은 query와의 consistency가 높아야합니다. 이를 위해 key에 대한 encoder를 moving average encoder 형식으로 지정합니다.

Method

학습 방법은 위 Contrastive Learning에서 설명드린 방법과 같습니다.

다른점이 있다면, 지금까지의 data들을 전부 저장한 memory bank를 queue 형태의 dynamic dictionary로 대체했다는 것 입니다.

queue를 선언 할 때 사용자 임의의 하이퍼파라미터로 queue의 크기를 지정한 다음 그 크기만큼의 queue를 만들면 됩니다.

 

자세한 과정을 알려드리자면, 데이터를 불러 올 때 transformation으로 random crop과 같은 random 요소가 들어간 것들을 적용시켜서 동일한 이미지 이지만 다르게 transformation된 두 이미지들을 가져옵니다.

이 중 하나를 query로, 다른 하나를 positive key로 사용하게 됩니다. 이렇게 positive key로 사용된 요소들은 마지막에 enqueue 시켜줍니다. (oldest는 dequeue)

 

그리고 moving average encoder는 훈련된 query encoder의 파라미터들에 대해 사용자 임의 하이퍼 파라미터 m 만큼 moving average 시켜줍니다.

query encoder parameters * m + moving average encoder * (1-m)

m = 0.999일 때 가장 좋은 결과를 냈다고 합니다.

 

https://github.com/yhy258/MoCo_v1_cifar10

 

GitHub - yhy258/MoCo_v1_cifar10

Contribute to yhy258/MoCo_v1_cifar10 development by creating an account on GitHub.

github.com

아주 간단하게 모델 만들어 봤습니다.

728x90