2편에서는 손실 함수와 유사도 함수 그리고 mask를 통한 labels 그리고 similarity matrix 생성, 그리고 8 X 1 행렬의 positives 와 8 X 6 행렬의 negatives를 결합한 logits 과 1 X 8의 positives 샘플들의 인덱스를 포함한 labels를 살펴보았다.
logits 과 labels 생성
Pytorch의 CrossEntropyLoss에서 target을 index 로 출력하는 예를 보면,
criterion = nn.CrossEntropyLoss(),
loss = criterion(input, target)
이다. 이때 input에 해당하는 것이 logits, target에 해당하는 것이 labels이다. 아래 그림 10에서, positives 와 negatives의 횡적 결합한 8 X 7 행렬이 logits 이고 labels 는 positives 샘플들의 인덱스를 포함한 1 X 8 행렬로써, labels는 CrossEntropy를 각 행의 logits를 보고 0값의 벡터를 보고 positive 쌍이 첫번째 인덱스에 있음을 알려주는 indicator function으로 일반적으로 사용하는 라벨과는 다른 내용이다.
아래 그림 11의 ①을 통해 대조 학습을 위한 온도 계수를 logits에 적용하는 부분이다. 1편의 그림 1에서 Ʈ는 출력 카테고리 간의 구분을 명확 혹은 부드럽게 출력하는
온도 계수라고 설명하였다. ②에서 logits 와 labels를 리턴 한다.
지금까지 살펴본 info_nce_loss
함수는 simclr.py 의 train 함수에서
사용한다.
logits,
labels = self.info_nce_loss(features)
loss =
self.critetion(logits, labels)
<그림 11. logits 과 labels 반환>
훈련
100 epoch 훈련이 끝나면 runs 밑에 일자_job_xx 디렉토리가 생기고 그 밑에 아래 그림 12 와 같은 파일들이
생성된다. Nvidia 2080Ti GPU 4대로 ubuntu20.04,
Pytorch 1.10, Pthon3.8, CUDA11.3 환경에서 훈련에 4시간 29분 소요되었다.
<그림 12. 훈련 후 생성되는 파일 들>
성능 평가
훈련을 통해 만들어진 분류기의 정확도를 측정하기위해 학습한 encoder를
고정(freeze)시키고 그 위에 linear classifier를
추가하여 정확도를 측정합니다. 코드는 feature_eval 디렉토리
밑에 mini_batch_logistic_regression_evaluator.ipynb 노트북 코드이다.
우선 아래와 같이 stl10 ResNet-18 공식 데이터세트를 ①과 같이
download=True로 하여 다운로드 받는다. 앞에 훈련에서
사용했던 데이터세트를 사용해도 되지만, 사전 학습 모델을 이용하여 모델이나 데이터세트의 차이에 따른
정확도 측정을 위해 주어진 mini_batch_~ 코드를 최대한 활용해본다. 위의 그림 12와 같은 내용이 ./data
디렉토리 밑에 다운로드 된다.
<그림 13. state_dict 의 fc.wieght, fc.bias 제거>
그리고 아래 그림 14의 ①번과 같이 model.named_parameters 의 fc.weight, fc.bias 를 제외한 나머지들을 모두 False 로 선언함으로써 역전파시 gradient 연산이 일어나지 않게 된다. ②는 model.parmaters중에 gradient enable 된 parameter를 뽑아내는 함수이다.
<그림 14. Gradient freeze 이외에 남은 변수를 넘겨 받기>
아래 그림 15의 ①번과 같이 model 의
summary를 호출하면 ②와 같이 ResNet-18의 마지막 layer에
완전연결층이 10개 class의 출력을 가지고 있음을 볼
수 있다.
<그림 15. 모델 summary>
완전연결층(FC layer) 훈련 및 모델 평가
아래 그림 16과 같이 훈련될 gradient를
enable 한 FC layer 를 훈련한다. epoch는 100으로 정하고 ①과 같이 모델에 x_batch를 넣어주면 logits가 출력된다. ②와 같이 logits와 y_batch와
함께 topl=(1,)를 변수로 top1 accuracy를
호출한다. ③ pytorch에서는 이후에 backward를 해줄 때 gradients 값들을 계속 더해주기
때문에 한번의 학습이 완료되면 gradients를 항상 0으로
만들어주어야 한다. ④ 오차를 역전파(backward)하기
위한 설정. ⑤ 옵티마이저는 parameter, learning
rate 및 여러 다른 hyper-parameter를 받아 step() method를 통해 업데이트한다.
<그림 16. FC layer 훈련 및 top-1 정확도 산출>
평가 기준 정의: top-k accuracy
테스트 데이터를 통한 Top1, Top5 정확도 평가
이어서 아래 그림 17과 같이 테스트 데이터를 로드 하여 정확도 성능을 평가한다. ①은 test_loader로부터 batch
단위로 데이터를 로드 한다. ②에서 batch 단위의
테스트 데이터가 모델에 입력되어 logits를 출력. ③에서
topk=(1,5)를 변수로 logits 와 y_batch를 입력하여 top1, top5 결과를 출력한다. ④를 통해 batch 단위의 결과를 평균 내어 ⑤와 같이 화면에
epoch 당 Top1 Test Accuracy와 Top 5 결과가 나타난다.
성능 결과
<그림 18. 선형분류기 학습을 통한 성능 평가>
결언
본 프로젝트의 목적은 라벨 없는 영상데이터들로 이미지 분류가 가능한지와 어느 정도의 성능을 보여주는지를 살펴보는 것이었다. 대조 학습을 위하여 라벨 없는 stl10 데이터를 훈련하였고 성능
평가를 위해 stl10 데이터의 10개 class를 보유한 train, test 라벨 있는 데이터를 마지막
층에 선형 분류기를 통하여 성능 평가를 하였다. ResNet-50에 비하여 비교적 구조가 간단한 ResNet-18 구조를 채택하여 official record 인 74.45에는 못 미치지만 69.28 의 Top1%를 달성하였다.
댓글 없음:
댓글 쓰기