pytorch transfer learning 튜토리얼 side notes

hur-kyuh-leez·2021년 12월 27일
0

data pre-processing 설명 매우 잘되어 있음 (한국어)
https://ys-cs17.tistory.com/32

pytorch 대충 훝기 좋음
https://wikidocs.net/61073


기존 resnet18으로 이미, bee and ant 분류 할 수 있음.
https://image-net.org/challenges/LSVRC/2015/browse-synsets.php
그러나 더 좋은 모델도 top-1 accuracy는 90%.
https://paperswithcode.com/sota/image-classification-on-imagenet
이 수치는 transfer learning 94% 보다 낮음

transfer learning을 통해
조금 더 내가 가지고 있는 이미지셋에 맞추는 것
resnet18이 풀려고 하는 문제는 1/1000 classification 확률
반대로 pytorch tuturial에서 풀려고 하는 문제는 1/2 classification 이라서 accuracy(94%)높을 수 밖에 없음
https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html
그래서 선택을 줄여 확률을 높인 건지 아니면 정말 transfer learning에 의해서 좋아진 건지 확인 할 필요 있음.
그래서 resnet18과 category 2가지 설정 해놓고 train을 아예 하지 않으면 accuracy가 얼마나 되는지 확인 해보면 모델이 더 좋아지는 건 지 확인 가능함.
가장 간단하게 하는 방법이 뭘까...

for phase in ['train', 'val']:

for phase in ['val']:

로 바꿔 train을 아예 안했을 때
valuation이 얼마나 나오는지 보면 됨.
해보면 50% 보다 낮은 46%
그리고 59% 가 나옴.

transfer learning이 resnet18을 그대로 사용하는 것 보다
실제로 더 좋게 만드는 것을 알 수 있음.

그런데 의문은 왜 resnet18 50% 이하가 나오는 것 일까...
아무리 다른것을 목적으로 train 되었다고 해도...
그래도 학습 된 것 인데...
마지막 out을 새로 만들고 트레이닝을 안하니 당연

생각해보면 transfer learning 자체가 새로운 방식인거 처럼 느낄 수 있는데
원래 category를 줄이고 직전 weight를 다 초기화 시키니 그걸 다시 train 시키는 것. 직전에 줄이는 거 말고
처음 시작점을 쓰는 것도 마찬가지.

내가 제시한 방법은 잘못된 방법임.
category을 1000를 bee and ant 2개로 줄여도
2개의 weights는 유지 하는 것으로 확인 해야 함.


그 전에 그냥 category 1000개로 해보면...

# ref: https://github.com/pytorch/pytorch/issues/46160 

import json
from torchvision.datasets.utils import download_url
from torchvision import models
from torchvision import transforms
from PIL import Image
import torch

download_url("https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json", ".", "imagenet_class_index.json")

with open("imagenet_class_index.json", "r") as h:
    labels = json.load(h)


# alexnet = models.AlexNet()
resnet = models.resnet18(pretrained=True)


preprocess = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(
        mean=[0.485, 0.456, 0.406],
        std=[0.229, 0.224, 0.225]
    )
])

!wget https://download.pytorch.org/tutorial/hymenoptera_data.zip
!unzip hymenoptera_data.zip -d data/
import glob
!ls

def get_val_acc(category='ant'):
  imgs = glob.glob(f'data/hymenoptera_data/val/{category}s/*.jpg')
  wrong = 0
  for idx, img in enumerate(imgs):
    img = Image.open(img)
    img.show()
    img_t = preprocess(img)
    batch_t = torch.unsqueeze(img_t, 0)
    resnet.eval()
    with torch.no_grad():
      out = resnet(batch_t)
    label_indices = out.argmax(dim=1)
    
    for i, p in enumerate(label_indices):
      model_category = labels[str(p.item())][1]
      if model_category != category:
        wrong += 1
  print( 1 - wrong / len(imgs))
  return len(imgs), wrong
  
ant_data_size, ant_data_wrong = get_val_acc('ant')
bee_data_size, bee_data_wrong = get_val_acc('bee')
final_acc = (1 - (ant_data_wrong + bee_data_wrong) / (ant_data_size + bee_data_size)) * 100
print(f'final acc: {final_acc}%')
// final acc: 74.50980392156863%

74% 나온다.

다음에 할 것은 weight 309(bees), 310(ants) tensor weights만 고정하고 다른거 다 삭제 하고 기본으로 하면 얼마 나올지 봐야함

profile
벨로그에 생각을 임시로 저장합니다. 틀린건 틀렸다고 해주세요 :) 그래야 논리 학습이 강화됩니다.

0개의 댓글