logo

전이 학습

기존의 머신러닝에서 문제점

  • 과업에 맞춰 모델과 데이터를 만들어야 함
    • 모델 만들기 → 어렵다
    • 데이터 수집 및 레이블링 → 어렵고 비용이 큼
  • 딥러닝은 매우 많은 데이터가 필요
    • 데이터 처리를 위해서 고성능의 컴퓨터가 필요

전이 학습 Transfer Learning

  • 근원 문제(source)에 학습시킨 모형을 새로운 대상 문제(target)에 적용하는 것
  • 사전 학습(pretraining): 근원 문제에 학습시키는 것
    • 많은 데이터를 사용
  • 미세 조정(fine tuning): 대상 문제에 학습시키는 것
    • 적은 데이터를 사용
    • 무작위로 초기화된 모형을 처음부터 학습시키는 것보다, 다른 문제에라도 학습시킨 모형을 추가 학습시키는 것이 유리할 가능성이 높음
    • 이미지 처리 과제는 비슷한 특징들을 공유하므로 무작위로 초기화된 것보다는 유사할 가능성이 높음
    • 일반적으로 근원 문제에 학습시킬 때보다 작은 학습률을 사용
  • 기초 모델(foundation model): 컴퓨터 비전이나 자연어 처리처럼 넓은 종류의 분야에 적용할 수 있는 모델

전이학습의 효과

  • 기존의 다른 문제에 학습시킨 모형을 약간의 미세 조정으로 높은 성능을 낼 수 있다면 데이터와 계산 비용을 절감할 수 있음
  • 성능은 높아지고 활용의 난이도가 낮아짐
  • 사전학습된 모델을 가져다가 쓰면 내가 하고자 하는 과업에 맞춰 약간의 데이터만 모아서 미세 조정하면 됨
  • 어떤 경우에는 미세조정 없이 쓸 수 있는 경우도 있음
  • 비전문가도 높은 성능의 모델을 쉽게 활용할 수 있게 됨

전이 학습의 방식

  • 사전 학습된 부분을 포함해서 전체적으로 미세 조정
  • 사전학습된 모형의 전반부를 특징 추출기로 사용 + 후반부에 분류기만 추가하고 추가된 부분만 학습
  • 사전학습된 모형을 추가 학습 없이 그대로 사용(zero-shot learning)

전이 학습의 세 가지 방식

언제 어떤 방법을 사용해야 하나?

방법데이터과업의 종류이미지필요한 하드웨어 성능
OpenCV 등으로 고정된 알고리즘없음단순 (직선, 원 찾기, 기하학적 변환)무관낮음
직접 모델을 만들어 머신러닝/딥러닝많음중간 (이미지 분류)해상도 낮고 크기 작음보통
기존의 모델을 전이 학습적음복잡하고 고유함 (탐지, 생성, 변환 등)해상도 높고 크기 큼높음
zero-shot learning없음복잡하지만 일반적 (예: 사람, 자동차의 탐지 등)무관낮음

허깅페이스 Hugging Face

허깅페이스는 사전 학습된 모델과 데이터셋을 찾아 사용할 수 있는 플랫폼이다. 컴퓨터 비전에서는 이미지 분류, 객체 탐지, 이미지 분할, 이미지-텍스트 변환 등 여러 과업에 맞는 모델을 검색할 수 있다.

허깅페이스 모델 허브의 컴퓨터 비전 모델 목록

허깅페이스 트랜스포머스

  • 최신 사전 학습 트랜스포머 계통 모델을 간편하게 사용할 수 있는 Python 라이브러리
  • 모델 구축과 학습 과정을 건너뛰고 바로 사용 가능
  • 자신의 데이터에 추가 학습시켜 미세 조정 가능
!pip install transformers[torch] datasets evaluate

모델 찾기

  • huggingface.co 방문
  • Models 메뉴 선택
  • Task 선택

액세스 토큰

  • 개인 계정에 모델을 업로드하거나 개인 계정에서 모델을 다운로드할 때 사용
  • 회원 가입 후 로그인
  • 우측 상단 메뉴 → Access Tokens
  • Create new token 선택
  • 토큰 이름을 입력한 후 Create Token
  • Save your Access Token 창에서 토큰을 복사
    • 창을 닫으면 토큰 값을 다시 볼 수 없으므로 따로 저장해야 함

허깅페이스 Access Tokens 메뉴와 토큰 생성 화면

노트북 로그인

from huggingface_hub import notebook_login

notebook_login()

아래와 같은 창이 뜨면 액세스 토큰을 붙여 넣고 Login을 클릭한다.

허깅페이스 노트북 로그인 위젯

데이터 로딩

# transformers의 자체 데이터셋 함수
from datasets import load_dataset

dataset = load_dataset("imagefolder", data_dir="cats_and_dogs_filtered")

# 레이블
labels = dataset["train"].features["label"].names
label2id, id2label = dict(), dict()
for i, label in enumerate(labels):
    label2id[label] = str(i)
    id2label[str(i)] = label
id2label

이미지 프로세서

  • 모델의 이미지 프로세서를 불러옴
from transformers import AutoImageProcessor

checkpoint = "google/vit-base-patch16-224-in21k"
image_processor = AutoImageProcessor.from_pretrained(checkpoint)

# 모델이 처리하는 이미지 크기
size = (
    image_processor.size["shortest_edge"]  # 가장 짧은 변의 길이
    if "shortest_edge" in image_processor.size
    else (image_processor.size["height"], image_processor.size["width"])
)

전처리

from torchvision import transforms

_transforms = transforms.Compose([
    transforms.RandomResizedCrop(size),
    transforms.ToTensor(),
    transforms.Normalize(
        mean=image_processor.image_mean,
        std=image_processor.image_std,
    ),
])
def transform_function(examples):
    examples["pixel_values"] = [
        _transforms(img.convert("RGB")) for img in examples["image"]
    ]
    del examples["image"]
    return examples


dataset = dataset.with_transform(transform_function)  # 전처리 함수 일괄 적용

모델 로딩

from transformers import AutoModelForImageClassification

model = AutoModelForImageClassification.from_pretrained(
    checkpoint,
    num_labels=len(labels),
    id2label=id2label,
    label2id=label2id,
)

정확도 평가 함수

import evaluate
import numpy as np

accuracy = evaluate.load("accuracy")

def compute_metrics(eval_pred):
    predictions, labels = eval_pred
    predictions = np.argmax(predictions, axis=1)
    return accuracy.compute(predictions=predictions, references=labels)

훈련 설정

from transformers import DefaultDataCollator
from transformers import TrainingArguments, Trainer

data_collator = DefaultDataCollator()  # 데이터를 배치로 합침

training_args = TrainingArguments(
    output_dir="C:/my_model/",  # 경로명에 한글이 들어가면 안됨
    remove_unused_columns=False,
    eval_strategy="epoch",
    save_strategy="epoch",
    learning_rate=5e-5,
    per_device_train_batch_size=16,
    gradient_accumulation_steps=4,
    per_device_eval_batch_size=16,
    num_train_epochs=1,
    warmup_ratio=0.1,
    logging_steps=10,
    load_best_model_at_end=True,
    metric_for_best_model="accuracy",
)

훈련

trainer = Trainer(
    model=model,
    args=training_args,
    data_collator=data_collator,
    train_dataset=dataset["train"],
    eval_dataset=dataset["test"],
    processing_class=image_processor,
    compute_metrics=compute_metrics,
)

trainer.train()

모델 사용해보기

# 이미지 불러오기
from PIL import Image

image = Image.open("cats_and_dogs_filtered/test/dogs/dog.2000.jpg")

# 이미지 분류
x = _transforms(image)  # 변환
x = x.unsqueeze(0)  # 차원 추가
output = model(x)  # 모델에 입력
output.logits.argmax(dim=-1)  # 가장 확률이 높은 카테고리
Previous
Vision Transformer