Image Classification

Remake:PyTorch Transfer Learning 예제

coding art 2022. 3. 12. 16:43
728x90

이 예제는 2020년 초 작성했던 블로그의 remake 버전입니다. 2년 가량 지났지만 그다지 변경된 내용은 없는 듯 합니다.

PyTorch Transfer Learning 예제실행-V https://blog.daum.net/ejleep1/835

 

TRANSFER LEARNING FOR COMPUTER VISION TUTORIAL: PyTorch 홈페이지의 이 예제 블로그를 참조하여 해설하기로 한다.

https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html

 

큰 규모의 image classification 작업을 위한 컨볼류션 네트워크를 굳이 스크래치 수준에서 다시 말해 랜덤한 웨이트값 초기화부터 다시 시작해야할 필요는 없지 않을까? 큰 규모란 ImageNet 의 1000종의 1200만개의 이미지 정도이면 웬만한 알만한 오브젝트들의 이미지를 포함하고 있다 보면 될 것이다.  이정도면 개인 PC에서 학습하기에는 컴퓨팅 부담이 다소 어마어마하다고 볼 수 있을 것이다.

 

이런 작업은 이미 다 완료하여 보급이 되어 있는 상태로서 pretrained=True 로 파라메터를 설정하여 image 데이터들을 라이브러리에 의해 불러 테스트해 볼 수 있도록 보급이 되었다.

 

하지만 사용자가 ImgeNet에서 미처 포함하지 못했던 특정한 이미지들을 포함하여 image classification 작업을 실행하고 싶을 경우가 있을 수 있다. 예를 들어 서양 애완견들은 다 포함되었겠지만 국산인 풍산개라든지 또는 삽살개 등 ImageNet에서 미처 포함하지 못했을 거라 보이는 이미지들은 추가를 해 줘야 classificatin 이 더욱 잘될 것이다.

 

이러한 목적 달성을 위해서 이미 ImageNet  학습 결과 웨이트 값을 binary  형태로 전달 받으면 다음과 같이 활용할 수 있을 것이다.

설사 사용자가 소량의 이미지를 추가로 포함하여 학습을 시켜도 이미 전달 받은 웨이값들의 변화는 극히 미미할 것이며 마이너한 규모의 컴퓨팅만 요구될 것이다. 미미한 변화를 겪은 웨이트 값들을 사용하면 사용자가 추가 이미지 데이터를 제공했던 클라스의 classification 작업이 더욱 원활해 질 것이다. 이를 fine tuning 이라 한다.

 

또 다른 기법으로는 fully connected  앞부분까지의 웨이트값들은 변하지 않도록 동결(freeze)한 상태에서 fully connected layer 만 랜덤 초기화부터 실행하여 전체 웨이트 값을 조정하는 방법이다. 

 

둘다 어느 방법이든 괜찮은 결과를 준다.

 

PyTorch 의 개미와 벌 Transfer Learning 예제를 다루어 보기 위해서 예제 이미지 데이터를 준비하자. here 를 클릭하여 zip 파일을 다운 받은 후 압축을 해제하고 hymenoptera_data 폴더를 NDRIVE에 드래그 하여 올리도록 한다.

NDRIVE 에 가져다 둔 hymenoptera_data 폴더를 Colab 예제코드에서 구글 드라이브 마운트 명령을 사용하여 연결하도록 하자. 마운팅 결과 폴더를 체크해 보면 아래와 같이 업로드된 결과를 확인할 수 있다.

지난 2020년 초에 이 예제를 다루었을때와 지금의 라이브러리 버전을 참고로 살펴보자. 상당히 많은 업그레이드가 이루어지고 있다.

Colab 구글 드라이브에 마운팅한 이미지 데이터를 읽어들이기 위해서 아래와 같이 데이터 디렉토리를 지정하자. 요 부분이 블로그 예제와 다른 점이다.

 

아래의 data augmentation 이란 필요한 데이터를 준비함에 있어서 뒤집기(flip), 잘라내기(crop), 회전 등의 작업을 통해 이미지 데이터 수를 늘리는 작업이다. 하나의 데이터를 사용하여 다르게 인식할 수 밖에 없는 이미지 수들을 늘리는 것이다. 이 작업은 어느 image classification 작업에서 공통으로 이루어지는 과정이다. 아울러 하단에 GPU  설정 과정이 포함되어 있다. 일단 Colab에서 GPU 를 설정하여 실행시키도록 하자. 2020년 실행 시 PC에서  50분 가량의 시간이 소모되었던 것을 기억한다.

몇개의 이미지를 샘플로 출력해보자.

메서드(method) train_model을 준비하자. LRscheduler(Learning Rate scheduler) 가 사용된다. 학습횟수가 커질수록 learning rate 값이 조절되된다.

device에 데이터 입력 과정과 아울러 optimizer.zero_grad() 명령에 의한 그라디언트 값 초기화로 부터 시작하여 PyTorch 특유의 backpropagation 포함 학습 알고리듬이 준비된다.

 

 

파라메터에 model 이 포함되어 있으며 반복 학습과정에 나타나는데 이 model 은 이하의 코딩 과정에서 import 한 models에서 가장 정밀도가 뛰어나다고 알려진 ResNet 을 불러 model 로 삼기로 한다.

prdiction 용 몇가지 이미지 가시화 출력용 코드

컨볼루션넷을 pretrained 된 ResNet18 즉 학습된 binary ResNet18을 사용하여 Fine Tunning 해 보자. ResNet18이 TesNet 중에서 가장 해상도가 낮은 넷이다. Loss 함수는 cross entropy 르 사용하고 optimizer는 현재의 Fine Tunning 과정이 일종의 업데이트 과정이므로 SGD(Stochastic Gradient Descent)를 사욜하기로 하자.

구글 Colab에서 GPU 를 사용하여 학습을 시키자. 블로그에서는 GPU 사용 시 1분이라 하였으나 요즘 Colab 이 붐비므로 좀 더 걸릴 것이다. 해보니 4분가량 소모되었다. PC CPU 로 하면 1 시간 정도로 예상한다. 

prediction 결과를 출력해 보자. 컬럼형인데 row 형태로 편집하였다.

ConveNet을 고정(fixed, frozen) 시킨 후 fullyconnected layer 만을 학습시키자. 이를 위해서 requires_grad = False 를 설정하여 backward( ) 즉 backpropagation 그라디언트 값들이 계산되지 않도록 하자. 알고리듬의 구체적인 내용에 관해서는 블로그 본문의 here 를 클릭하여 들어가 보도록 한다. 어쨋든 결론적으로 backporpagation 의 상당 부분 컴퓨팅 부담을 경감하므로 실행 시간이 반 이하로 줄어들 수 있다. 

실행해보면 2분이 채 안걸림을 확인할 수 있다.

결과 이미지를 출력해 보자.

 

이상 실행했던 코드는 블로그 주소(https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html) 에서 복사하여 실행해 보기 바란다. 단 초반에 설명했던 것처럼 데이터는 사용자가 준비하여 구글 마운트 작업을 해야 할 것이다.