본문 바로가기

오늘의 코딩/머신러닝,Deep Learning

[pytorch] 맨땅에 transfer learning 하기 1

작업환경

python 3.x

pytorch 1.4.0

torchvision 0.5

 

0. Transfer Learning 이란?

Transfer Learning(전이 학습) 이란 특정 환경(모델, 데이터셋)에서 파라미터 값을 훈련시킨 Neural Network를 내가 원하는 상황(데이터)에 맞게 리뉴얼하는 것이다. 

 

Transfer Learning을 하는 이유는:

(1) 적은 데이터셋을 이용하여 모델을 학습시킬 수 있고

(2) 대부분의 경우, Transfer Learning한 모델이 처음부터 쌓은 모델보다 더 성능이 좋으며

(3) 훈련에 드는 시간을 절약할 수 있기 때문이다.

 

Transfer Learning은 특정 데이터셋에 맞춰 학습이 완료된 모델의 파라미터를 이용하여 내가 원하는 데이터셋에 이용하는 것인데, 낮은 단계의 파라미터-filter는 input데이터로부터 아주 기본적인 feature map을 추출하므로 미리 학습시킨 데이터셋과 비슷하지만 다른 종류의 데이터셋에서도 어느정도 효과를 나타낸다.

 

MNIST dataset

예를 들어, MNIST 데이터셋을 이용하여 훈련시킨 모델의 경우, 낮은 단계의 레이어는 직선이나 곡선 정도를 추출할 것이다. 이렇게 추출된 feature map은 한글이나 영어같은 글자에서도 효과적으로 작용할 것이라 추측할 수 있다. 

 

1. Transfer Learning 처음부터 직접 구현해보기

 

Transfer Leaning을 준비하기 위해서는 (1)(내가 원하는) Dataset 과 (2) (pre-trained) Neural Network model 이 필요하다.

 

 

(1) Dataset

torchvision에서는 TORCHVISION.DATASETS 패키지에서 다양한 데이터셋을 제공하고 있다.

자세한 내용은 ( https://pytorch.org/docs/stable/torchvision/datasets.html) 를 참고하면 된다.

 

(2) Neural Network model

torchvision에서는TORCHVISION.MODELS 패키지에서 다양한 pre-trained 모델을 제공하고 있다.

자세한 내용은 ( https://pytorch.org/docs/stable/torchvision/models.html )를 참고하면 된다.

 

쓸만한 모델을 발견했다면 이제 내가 원하는 데이터셋을 이용하여 학습시켜야 한다. 글자를 구분하는 모델을 만들 때 CIFAR 같은 데이터셋을 이용하여 학습시킬 수는 없는 노릇이다. 여기서 우리가 취할 수 있는 액션은 두가지이다.

 

- 우리가 원하는 데이터셋을 이용하여 모델을 먼저 학습시키거나

일이 복잡해진다. 따로 포스트를 작성하겠다.

여기서 우리가 알아야 할 것은 학습시킨 모델을 저장하는 방법이다. 이건 쉽다. 다음과 같다.

 

Model Save

 

#resnet을 인스턴스로 생성.
from torchvision.models.resnet import ResNet
model = ResNet()

# ~~~ 학습 과정 생략 ~~~

#모델 저장 경로 지정
PATH = './trained_resnet.pth'

#파라미터값 저장(추천)
torch.save(model.state_dict(), PATH)

#모델 자체를 저장
torch.save(model, PATH)

모델을 인스턴스로 생성한 후 다양한 과정을 통해 학습시켜야하지만 그 부분은 생략했다.

중요한 부분은 우리가 공들여 학습한 모델을 저장하는 부분이다.

 

(1) pytorch에서는 훈련시킨 모델을 .pt 나 .pth 확장자를 이용하여 저장한다.

(2) .state_dict() 함수는 간단히 말해 훈련시킨 파라미터값을 저장한다. 

 

state_dict는 간단히 말해 각 계층을 매개변수 텐서로 매핑되는 Python 사전(dict) 객체입니다. 이 때, 학습 가능한 매개변수를 갖는 계층(합성곱 계층, 선형 계층 등) 및 등록된 버퍼들(batchnorm의 running_mean)만이 모델의 state_dict 에 항목을 가짐을 유의하시기 바랍니다. 

pytorch 튜토리얼  -참고 링크 하단 기재

(3) 모델 자체를 저장한다.

 

 

- 우리가 원하는 데이터셋을 이용하여 학습된 모델을 불러오거나

Model Load

 

#만든 모델과 똑같은 모델 인스턴스를 생성해야 함
from torchvision.models.resnet import ResNet

the_model = ResNet()

#모델 저장 경로
PATH = './trained_resnet.pth'

#그래야 파라미터 값을 모델에 입힐 수 있음
the_model.load_state_dict(torch.load(PATH))

 

모델을 불러올 때 주의할 점이 있다.

우리가 학습시킨 model과 같은 인스턴스를 만들어야 한다.

앞서 말했듯 .state_dict() 함수는 훈련시킨 파라미터값을 저장하므로 혼자서는 존재하지 못한다. 따라서 값을 붙여넣을 틀(model 인스턴스)이 필요하다.

 

#모델 자체를 저장했을 경우
the_model = torch.load(PATH)

 

모델 자체를 저장했다면 torch.load 함수로 그냥 불러오면 된다.

 

 

다음엔 불러온 모델을 이용하여 본격적으로 transfer learning을 시도해보겠다!

 

 

참고 링크

https://pytorch.org/docs/stable/notes/serialization.html

https://tutorials.pytorch.kr/beginner/saving_loading_models.html