unnjena
궁금한이야기J
unnjena
전체 방문자
오늘
어제
  • 분류 전체보기 (28)
    • Graduate M.S. (0)
      • Paper Review (0)
      • Project Related (0)
    • Undergraduate (14)
      • ML & DL (9)
      • Otherwise (1)
      • Programming (4)
    • etc. (9)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 업스테이지
  • 지나영교수님
  • 세바시
  • AI_Production_Lifecycle
  • Coding
  • 카공
  • 서비스기획
  • 인생질문
  • TEST
  • 컴퓨터네트워크 #Traceroute
  • 취준생
  • PM
  • AI교육
  • 취준일기
  • Deepfake
  • Upstage
  • network #delay #loss #throughput #컴퓨터네트워크
  • 인공지능입문
  • Annotation #tool
  • Jump_into_the_AI_World
  • #computer_network #컴퓨터네트워크
  • network #edge #컴퓨터네트워크
  • 컴퓨터네트워크 #인터넷
  • Python

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
unnjena

궁금한이야기J

[PyTorch tutorial] 컴퓨터 비전(Vision)을 위한 전이학습(Transfer Learning)
Undergraduate/ML & DL

[PyTorch tutorial] 컴퓨터 비전(Vision)을 위한 전이학습(Transfer Learning)

2020. 5. 14. 10:13

원문

 

컴퓨터 비전(Vision)을 위한 전이학습(Transfer Learning) — PyTorch Tutorials 1.4.0 documentation

Note Click here to download the full example code 컴퓨터 비전(Vision)을 위한 전이학습(Transfer Learning) Author: Sasank Chilamkurthy번역: 박정환 이 튜토리얼에서는 전이학습(Transfer Learning)을 이용하여 이미지 분류를

tutorials.pytorch.kr

전이학습이란?

  • Deep하게 이미 학습된 알고리즘을 pretrained model로 가지고 와서 일무 layer만을 학습하는 방법
  • 모델 학습 시간을 파격적으로 줄일 수 있기 때문에 아주 유용

ILSVRC 역대 우승 알고리즘

  • torchvision에는 ILSVRC 우승 알고리즘을 pretrained 모델로 쓸 수 있는데, 단 한 줄로도 구현 가능함
model_ft = models.resnet18(pretrained=True)

전이학습 시나리오(2가지)

  • 합성곱 신경망의 미세조정(finetuning) : 무작위 초기화 대신, 신경망을 ImageNet1000 데이터셋 등으로 미리 학습한 신경망으로 초기화함(학습의 나머지 과정은 일반 신경망과 동일)
  • 고정된 특징 추출기로써의 합성곱 신경망 : full-connected 신경망을 제외한 모든 신경망의 가중치를 고정시킴. 마지막  full-connected layer만 무작위로 초기 세팅되어 이 계층만 학습함
# License: BSD
# Author: Sasank Chilamkurthy

from __future__ import print_function, division

import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
import numpy as np
import torchvision
from torchvision import datasets, models, transforms
import matplotlib.pyplot as plt
import time
import os
import copy

plt.ion()   # 대화형 모드

데이터 불러오기

  • 데이터는 여기 에서 다운로드(작업 디렉토리에 압축 풀기)
  • 개미와 벌 분류 문제
# 학습을 위해 데이터 증가(augmentation) 및 일반화(normalization)
# 검증을 위한 일반화
data_transforms = {
    'train': transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    'val': transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
}

data_dir = 'data/hymenoptera_data'
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),
                                          data_transforms[x])
                  for x in ['train', 'val']}
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4,
                                             shuffle=True, num_workers=4)
              for x in ['train', 'val']}
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
class_names = image_datasets['train'].classes

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

모델 학습하기

def train_model(model, criterion, optimizer, scheduler, num_epochs=25):
    since = time.time()

    best_model_wts = copy.deepcopy(model.state_dict())
    best_acc = 0.0

    for epoch in range(num_epochs):
        print('Epoch {}/{}'.format(epoch, num_epochs - 1))
        print('-' * 10)

        # 각 에폭(epoch)은 학습 단계와 검증 단계를 갖습니다.
        for phase in ['train', 'val']:
            if phase == 'train':
                model.train()  # 모델을 학습 모드로 설정
            else:
                model.eval()   # 모델을 평가 모드로 설정

            running_loss = 0.0
            running_corrects = 0

            # 데이터를 반복
            for inputs, labels in dataloaders[phase]:
                inputs = inputs.to(device)
                labels = labels.to(device)

                # 매개변수 경사도를 0으로 설정
                optimizer.zero_grad()

                # 순전파
                # 학습 시에만 연산 기록을 추적
                with torch.set_grad_enabled(phase == 'train'):
                    outputs = model(inputs)
                    _, preds = torch.max(outputs, 1)
                    loss = criterion(outputs, labels)

                    # 학습 단계인 경우 역전파 + 최적화
                    if phase == 'train':
                        loss.backward()
                        optimizer.step()

                # 통계
                running_loss += loss.item() * inputs.size(0)
                running_corrects += torch.sum(preds == labels.data)
            if phase == 'train':
                scheduler.step()

            epoch_loss = running_loss / dataset_sizes[phase]
            epoch_acc = running_corrects.double() / dataset_sizes[phase]

            print('{} Loss: {:.4f} Acc: {:.4f}'.format(
                phase, epoch_loss, epoch_acc))

            # 모델을 깊은 복사(deep copy)함
            if phase == 'val' and epoch_acc > best_acc:
                best_acc = epoch_acc
                best_model_wts = copy.deepcopy(model.state_dict())

        print()

    time_elapsed = time.time() - since
    print('Training complete in {:.0f}m {:.0f}s'.format(
        time_elapsed // 60, time_elapsed % 60))
    print('Best val Acc: {:4f}'.format(best_acc))

    # 가장 나은 모델 가중치를 불러옴
    model.load_state_dict(best_model_wts)
    return model

일부 이미지 예측값을 보여주는 함수

def visualize_model(model, num_images=6):
    was_training = model.training
    model.eval()
    images_so_far = 0
    fig = plt.figure()

    with torch.no_grad():
        for i, (inputs, labels) in enumerate(dataloaders['val']):
            inputs = inputs.to(device)
            labels = labels.to(device)

            outputs = model(inputs)
            _, preds = torch.max(outputs, 1)

            for j in range(inputs.size()[0]):
                images_so_far += 1
                ax = plt.subplot(num_images//2, 2, images_so_far)
                ax.axis('off')
                ax.set_title('predicted: {}'.format(class_names[preds[j]]))
                imshow(inputs.cpu().data[j])

                if images_so_far == num_images:
                    model.train(mode=was_training)
                    return
        model.train(mode=was_training)

합성곱 신경망 미세조정(finetuning)

  • 미리 학습한 모델을 불러온 후 마지막의 완전히 연결된 계층을 초기화
model_ft = models.resnet18(pretrained=True)
num_ftrs = model_ft.fc.in_features
# 여기서 각 출력 샘플의 크기는 2로 설정합니다.(개미, 벌)
# 또는, nn.Linear(num_ftrs, len (class_names))로 일반화할 수 있습니다.
model_ft.fc = nn.Linear(num_ftrs, 2)

model_ft = model_ft.to(device)

criterion = nn.CrossEntropyLoss()

# 모든 매개변수들이 최적화되었는지 관찰
optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)

# 7 에폭마다 0.1씩 학습율 감소
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)
  • CPU에서는 15-25분 가량, GPU에서는 1분 이내의 시간소요
model_ft = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler, num_epochs=25)
  • 예측 결과 일부 확인
visualize_model(model_ft)

고정된 특징 추출기로써의 합성곱 신경망

  • 마지막 계층을 제외한 신경망의 모든 부분 고정
  • requires_grad == False 로 설정하여 매개변수를 고정 => backward() 중에 경사도가 계산되지 않도록 해야함

관련문서

model_conv = torchvision.models.resnet18(pretrained=True)
for param in model_conv.parameters():
    param.requires_grad = False

# 새로 생성된 모듈의 매개변수는 기본값이 requires_grad=True 임
num_ftrs = model_conv.fc.in_features
model_conv.fc = nn.Linear(num_ftrs, 2)

model_conv = model_conv.to(device)

criterion = nn.CrossEntropyLoss()

# 이전과는 다르게 마지막 계층의 매개변수들만 최적화되는지 관찰
optimizer_conv = optim.SGD(model_conv.fc.parameters(), lr=0.001, momentum=0.9)

# 7 에폭마다 0.1씩 학습율 감소
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_conv, step_size=7, gamma=0.1)
  • 대부분의 레이어에서 backward 계산을 생략하므로 시간이 절반정도 걸림(forward는 계산함)
model_conv = train_model(model_conv, criterion, optimizer_conv, exp_lr_scheduler, num_epochs=25)
  • 예측 결과 확인
visualize_model(model_conv)

plt.ioff()
plt.show()

'Undergraduate > ML & DL' 카테고리의 다른 글

[winSCP] 서버 사용 시 유용한 프로그램  (0) 2020.05.20
[Face Recognition] 얼굴 인식 출입, 어떻게 하는걸까?  (0) 2020.05.20
[GPU] 다수의 GPU 중 원하는 GPU 타겟팅하기  (0) 2020.05.13
[PyTorch tutorial] PyTorch에서 GPU 활용하기  (0) 2020.05.12
[PyTorch tutorial] 파이토치로 딥러닝하기 : 60분만에 끝장내기  (0) 2020.05.12
    'Undergraduate/ML & DL' 카테고리의 다른 글
    • [winSCP] 서버 사용 시 유용한 프로그램
    • [Face Recognition] 얼굴 인식 출입, 어떻게 하는걸까?
    • [GPU] 다수의 GPU 중 원하는 GPU 타겟팅하기
    • [PyTorch tutorial] PyTorch에서 GPU 활용하기
    unnjena
    unnjena
    모든 궁금증과 그 해답을 담는 공간 Github : https://github.com/JaeheeRyu

    티스토리툴바