Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🌐 [i18n-KO] Translated `knowledge_distillation_for_image_classification.md to Korean" #32334

Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/source/ko/_toctree.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@
title: 이미지 νŠΉμ§• μΆ”μΆœ
- local: tasks/mask_generation
title: 마슀크 생성
- local: in_translation
title: (λ²ˆμ—­μ€‘) Knowledge Distillation for Computer Vision
- local: tasks/knowledge_distillation_for_image_classification
title: 컴퓨터 λΉ„μ „(이미지 λΆ„λ₯˜)λ₯Ό μœ„ν•œ 지식 증λ₯˜(knowledge distillation)
title: 컴퓨터 λΉ„μ „
- isExpanded: false
sections:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
<!--Copyright 2023 The HuggingFace Team. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

⚠️ Note that this file is in Markdown but contain specific syntax for our doc-builder (similar to MDX) that may not be
rendered properly in your Markdown viewer.

-->
# 컴퓨터 비전을 μœ„ν•œ 지식 증λ₯˜[[Knowledge-Distillation-for-Computer-Vision]]

[[open-in-colab]]

지식 증λ₯˜(Knowledge distillation)λŠ” 더 크고 λ³΅μž‘ν•œ λͺ¨λΈ(ꡐ사)μ—μ„œ 더 μž‘κ³  κ°„λ‹¨ν•œ λͺ¨λΈ(학생)둜 지식을 μ „λ‹¬ν•˜λŠ” κΈ°μˆ μž…λ‹ˆλ‹€. ν•œ λͺ¨λΈμ—μ„œ λ‹€λ₯Έ λͺ¨λΈλ‘œ 지식을 증λ₯˜ν•˜κΈ° μœ„ν•΄, νŠΉμ • μž‘μ—…(이 경우 이미지 λΆ„λ₯˜)에 λŒ€ν•΄ ν•™μŠ΅λœ 사전 ν›ˆλ ¨λœ ꡐ사 λͺ¨λΈμ„ μ‚¬μš©ν•˜κ³ , 랜덀으둜 μ΄ˆκΈ°ν™”λœ 학생 λͺ¨λΈμ„ 이미지 λΆ„λ₯˜ μž‘μ—…μ— λŒ€ν•΄ ν•™μŠ΅ν•©λ‹ˆλ‹€. κ·Έλ‹€μŒ, 학생 λͺ¨λΈμ΄ ꡐ사 λͺ¨λΈμ˜ 좜λ ₯을 λͺ¨λ°©ν•˜μ—¬ 두 λͺ¨λΈμ˜ 좜λ ₯ 차이λ₯Ό μ΅œμ†Œν™”ν•˜λ„λ‘ ν›ˆλ ¨ν•©λ‹ˆλ‹€. 이 기법은 Hinton λ“± μ—°κ΅¬μ§„μ˜ [Distilling the Knowledge in a Neural Network](https://arxiv.org/abs/1503.02531)μ—μ„œ 처음 μ†Œκ°œλ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이 κ°€μ΄λ“œμ—μ„œλŠ” νŠΉμ • μž‘μ—…μ— 맞좘 지식 증λ₯˜λ₯Ό μˆ˜ν–‰ν•  κ²ƒμž…λ‹ˆλ‹€. μ΄λ²ˆμ—λŠ” [beans dataset](https://huggingface.co/datasets/beans)을 μ‚¬μš©ν•  κ²ƒμž…λ‹ˆλ‹€.

이 κ°€μ΄λ“œλŠ” [λ―Έμ„Έ μ‘°μ •λœ ViT λͺ¨λΈ](https://huggingface.co/merve/vit-mobilenet-beans-224) (ꡐ사 λͺ¨λΈ)을 [MobileNet](https://huggingface.co/google/mobilenet_v2_1.4_224) (학생 λͺ¨λΈ)으둜 증λ₯˜ν•˜λŠ” 방법을 πŸ€— Transformers의 [Trainer API](https://huggingface.co/docs/transformers/en/main_classes/trainer#trainer) λ₯Ό μ‚¬μš©ν•˜μ—¬ λ³΄μ—¬μ€λ‹ˆλ‹€.

증λ₯˜μ™€ κ³Όμ • 평가λ₯Ό μœ„ν•΄ ν•„μš”ν•œ 라이브러리λ₯Ό μ„€μΉ˜ν•΄ λ΄…μ‹œλ‹€.


```bash
pip install transformers datasets accelerate tensorboard evaluate --upgrade
```

이 μ˜ˆμ œμ—μ„œλŠ” `merve/beans-vit-224` λͺ¨λΈμ„ ꡐ사 λͺ¨λΈλ‘œ μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 이 λͺ¨λΈμ€ beans λ°μ΄ν„°μ…‹μ—μ„œ 파인 νŠœλ‹λœ `google/vit-base-patch16-224-in21k` 기반의 이미지 λΆ„λ₯˜ λͺ¨λΈμž…λ‹ˆλ‹€. 이 λͺ¨λΈμ„ λ¬΄μž‘μœ„λ‘œ μ΄ˆκΈ°ν™”λœ MobileNetV2둜 증λ₯˜ν•΄λ³Ό κ²ƒμž…λ‹ˆλ‹€.

이제 데이터셋을 λ‘œλ“œν•˜κ² μŠ΅λ‹ˆλ‹€.

```python
from datasets import load_dataset

dataset = load_dataset("beans")
```

이 경우 두 λͺ¨λΈμ˜ 이미지 ν”„λ‘œμ„Έμ„œκ°€ λ™μΌν•œ ν•΄μƒλ„λ‘œ λ™μΌν•œ 좜λ ₯을 λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ—, 두가지λ₯Ό λͺ¨λ‘ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ°μ΄ν„°μ…‹μ˜ λͺ¨λ“  λΆ„ν• λ§ˆλ‹€ μ „μ²˜λ¦¬λ₯Ό μ μš©ν•˜κΈ° μœ„ν•΄ `dataset`의 `map()` λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•  것 μž…λ‹ˆλ‹€.


```python
from transformers import AutoImageProcessor
teacher_processor = AutoImageProcessor.from_pretrained("merve/beans-vit-224")

def process(examples):
processed_inputs = teacher_processor(examples["image"])
return processed_inputs

processed_datasets = dataset.map(process, batched=True)
```

학생 λͺ¨λΈ(λ¬΄μž‘μœ„λ‘œ μ΄ˆκΈ°ν™”λœ MobileNet)이 ꡐ사 λͺ¨λΈ(파인 νŠœλ‹λœ λΉ„μ „ 트랜슀포머)을 λͺ¨λ°©ν•˜λ„둝 ν•  것 μž…λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄ λ¨Όμ € ꡐ사와 학생 λͺ¨λΈμ˜ λ‘œμ§“ 좜λ ₯값을 κ΅¬ν•©λ‹ˆλ‹€. 그런 λ‹€μŒ 각 좜λ ₯값을 λ§€κ°œλ³€μˆ˜ `temperature` κ°’μœΌλ‘œ λ‚˜λˆ„λŠ”λ°, 이 λ§€κ°œλ³€μˆ˜λŠ” 각 μ†Œν”„νŠΈ νƒ€κ²Ÿμ˜ μ€‘μš”λ„λ₯Ό μ‘°μ ˆν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€. λ§€κ°œλ³€μˆ˜ `lambda` λŠ” 증λ₯˜ μ†μ‹€μ˜ μ€‘μš”λ„μ— κ°€μ€‘μΉ˜λ₯Ό μ€λ‹ˆλ‹€. 이 μ˜ˆμ œμ—μ„œλŠ” `temperature=5`와 `lambda=0.5`λ₯Ό μ‚¬μš©ν•  κ²ƒμž…λ‹ˆλ‹€. 학생과 ꡐ사 κ°„μ˜ λ°œμ‚°μ„ κ³„μ‚°ν•˜κΈ° μœ„ν•΄ Kullback-Leibler Divergence 손싀을 μ‚¬μš©ν•©λ‹ˆλ‹€. 두 데이터 P와 Qκ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, KL DivergenceλŠ” Qλ₯Ό μ‚¬μš©ν•˜μ—¬ Pλ₯Ό ν‘œν˜„ν•˜λŠ” 데 μ–Όλ§ŒνΌμ˜ μΆ”κ°€ 정보가 ν•„μš”ν•œμ§€λ₯Ό λ§ν•΄μ€λ‹ˆλ‹€. 두 데이터가 λ™μΌν•˜λ‹€λ©΄, KL DivergenceλŠ” 0이며, Q둜 Pλ₯Ό μ„€λͺ…ν•˜λŠ” 데 μΆ”κ°€ 정보가 ν•„μš”ν•˜μ§€ μ•ŠμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€. λ”°λΌμ„œ 지식 증λ₯˜μ˜ λ§₯λ½μ—μ„œ KL DivergenceλŠ” μœ μš©ν•©λ‹ˆλ‹€.


```python
from transformers import TrainingArguments, Trainer
import torch
import torch.nn as nn
import torch.nn.functional as F


class ImageDistilTrainer(Trainer):
def __init__(self, teacher_model=None, student_model=None, temperature=None, lambda_param=None, *args, **kwargs):
super().__init__(model=student_model, *args, **kwargs)
self.teacher = teacher_model
self.student = student_model
self.loss_function = nn.KLDivLoss(reduction="batchmean")
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
self.teacher.to(device)
self.teacher.eval()
self.temperature = temperature
self.lambda_param = lambda_param

def compute_loss(self, student, inputs, return_outputs=False):
student_output = self.student(**inputs)

with torch.no_grad():
teacher_output = self.teacher(**inputs)

# Compute soft targets for teacher and student
JinukHong marked this conversation as resolved.
Show resolved Hide resolved
JinukHong marked this conversation as resolved.
Show resolved Hide resolved
soft_teacher = F.softmax(teacher_output.logits / self.temperature, dim=-1)
soft_student = F.log_softmax(student_output.logits / self.temperature, dim=-1)

# Compute the loss
JinukHong marked this conversation as resolved.
Show resolved Hide resolved
distillation_loss = self.loss_function(soft_student, soft_teacher) * (self.temperature ** 2)

# Compute the true label loss
JinukHong marked this conversation as resolved.
Show resolved Hide resolved
student_target_loss = student_output.loss

# Calculate final loss
JinukHong marked this conversation as resolved.
Show resolved Hide resolved
loss = (1. - self.lambda_param) * student_target_loss + self.lambda_param * distillation_loss
return (loss, student_output) if return_outputs else loss
```

이제 Hugging Face Hub에 λ‘œκ·ΈμΈν•˜μ—¬ `Trainer`λ₯Ό 톡해 Hugging Face Hub에 λͺ¨λΈμ„ ν‘Έμ‹œν•  수 μžˆλ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.


```python
from huggingface_hub import notebook_login

notebook_login()
```

이제 `TrainingArguments`, ꡐ사 λͺ¨λΈκ³Ό 학생 λͺ¨λΈμ„ μ„€μ •ν•˜κ² μŠ΅λ‹ˆλ‹€.


```python
from transformers import AutoModelForImageClassification, MobileNetV2Config, MobileNetV2ForImageClassification

training_args = TrainingArguments(
output_dir="my-awesome-model",
num_train_epochs=30,
fp16=True,
logging_dir=f"{repo_name}/logs",
logging_strategy="epoch",
eval_strategy="epoch",
save_strategy="epoch",
load_best_model_at_end=True,
metric_for_best_model="accuracy",
report_to="tensorboard",
push_to_hub=True,
hub_strategy="every_save",
hub_model_id=repo_name,
)

num_labels = len(processed_datasets["train"].features["labels"].names)

# λͺ¨λΈ μ΄ˆκΈ°ν™”
teacher_model = AutoModelForImageClassification.from_pretrained(
"merve/beans-vit-224",
num_labels=num_labels,
ignore_mismatched_sizes=True
)

# MobileNetV2 λ°‘λ°”λ‹₯λΆ€ν„° ν•™μŠ΅
student_config = MobileNetV2Config()
student_config.num_labels = num_labels
student_model = MobileNetV2ForImageClassification(student_config)
```

`compute_metrics` ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ ν…ŒμŠ€νŠΈ μ„ΈνŠΈμ—μ„œ λͺ¨λΈμ„ 평가할 수 μžˆμŠ΅λ‹ˆλ‹€. 이 ν•¨μˆ˜λŠ” ν›ˆλ ¨ κ³Όμ •μ—μ„œ λͺ¨λΈμ˜ `accuracy`와 `f1`을 κ³„μ‚°ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.


```python
import evaluate
import numpy as np

accuracy = evaluate.load("accuracy")

def compute_metrics(eval_pred):
predictions, labels = eval_pred
acc = accuracy.compute(references=labels, predictions=np.argmax(predictions, axis=1))
return {"accuracy": acc["accuracy"]}
```

μ •μ˜ν•œ ν›ˆλ ¨ 인수둜 `Trainer`λ₯Ό μ΄ˆκΈ°ν™”ν•΄λ΄…μ‹œλ‹€. λ˜ν•œ 데이터 μ½œλ ˆμ΄ν„°(data collator)λ₯Ό μ΄ˆκΈ°ν™”ν•˜κ² μŠ΅λ‹ˆλ‹€.

```python
from transformers import DefaultDataCollator

data_collator = DefaultDataCollator()
trainer = ImageDistilTrainer(
student_model=student_model,
teacher_model=teacher_model,
training_args=training_args,
train_dataset=processed_datasets["train"],
eval_dataset=processed_datasets["validation"],
data_collator=data_collator,
tokenizer=teacher_processor,
compute_metrics=compute_metrics,
temperature=5,
lambda_param=0.5
)
```

이제 λͺ¨λΈμ„ ν›ˆλ ¨ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

```python
trainer.train()
```

λͺ¨λΈμ„ ν…ŒμŠ€νŠΈ μ„ΈνŠΈμ—μ„œ 평가할 수 μžˆμŠ΅λ‹ˆλ‹€.

```python
trainer.evaluate(processed_datasets["test"])
```


ν…ŒμŠ€νŠΈ μ„ΈνŠΈμ—μ„œ λͺ¨λΈμ˜ μ •ν™•λ„λŠ” 72%에 λ„λ‹¬ν–ˆμŠ΅λ‹ˆλ‹€. 증λ₯˜μ˜ νš¨μœ¨μ„±μ„ κ²€μ¦ν•˜κΈ° μœ„ν•΄ λ™μΌν•œ ν•˜μ΄νΌνŒŒλΌλ―Έν„°λ‘œ beans λ°μ΄ν„°μ…‹μ—μ„œ MobileNet을 μ²˜μŒλΆ€ν„° ν›ˆλ ¨ν•˜μ˜€κ³ , ν…ŒμŠ€νŠΈ μ„ΈνŠΈμ—μ„œμ˜ μ •ν™•λ„λŠ” 63% μ˜€μŠ΅λ‹ˆλ‹€. λ‹€μ–‘ν•œ 사전 ν›ˆλ ¨λœ ꡐ사 λͺ¨λΈ, 학생 ꡬ쑰, 증λ₯˜ λ§€κ°œλ³€μˆ˜λ₯Ό μ‹œλ„ν•΄λ³΄μ‹œκ³  κ²°κ³Όλ₯Ό λ³΄κ³ ν•˜κΈ°λ₯Ό ꢌμž₯ν•©λ‹ˆλ‹€. 증λ₯˜λœ λͺ¨λΈμ˜ ν›ˆλ ¨ λ‘œκ·Έμ™€ μ²΄ν¬ν¬μΈνŠΈλŠ” [이 μ €μž₯μ†Œ](https://huggingface.co/merve/vit-mobilenet-beans-224)μ—μ„œ 찾을 수 있으며, μ²˜μŒλΆ€ν„° ν›ˆλ ¨λœ MobileNetV2λŠ” 이 [μ €μž₯μ†Œ](https://huggingface.co/merve/resnet-mobilenet-beans-5)μ—μ„œ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.
Loading