HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
장지원 페이지/
📕
2024 UGRP
/
Member Page
Member Page
/
권태완
권태완
/
2024/09/09 - 모델 학습

2024/09/09 - 모델 학습

Tags

1. WSL환경에서 VSCODE를 이용해서 모델 LoRA 파인튜닝하기

사용한 모델 및 데이터 셋
  • Model:
  • Dataset: xodhks/EmoSet118K & xodhks/Children_Sketch
원래는 dima806/facial_emotions_image_detection 이 모델을 사용하려고 했으나 데이터 셋과의 라벨 개수(감정 종류)가 달라서 실패함.
모델 학습 환경(Conda)
  • WSL에서 cuda 12.1 버전을 기반으로 python 3.9.17의 가상 환경을 구축. 사용한 가상 환경의 각종 의존성 버전은 다음과 같다.
    • # packages in environment at /home/rnjsxodhks/anaconda3/envs/UGRP: # # Name Version Build Channel _libgcc_mutex 0.1 conda_forge conda-forge _openmp_mutex 4.5 2_gnu conda-forge aiohappyeyeballs 2.4.0 pypi_0 pypi aiohttp 3.10.5 pypi_0 pypi aiosignal 1.3.1 pypi_0 pypi asttokens 2.4.1 pyhd8ed1ab_0 conda-forge async-timeout 4.0.3 pypi_0 pypi attrs 24.2.0 pypi_0 pypi ca-certificates 2024.8.30 hbcca054_0 conda-forge certifi 2024.8.30 pypi_0 pypi charset-normalizer 3.3.2 pypi_0 pypi comm 0.2.2 pyhd8ed1ab_0 conda-forge datasets 2.21.0 pypi_0 pypi debugpy 1.8.5 py39hf88036b_1 conda-forge decorator 5.1.1 pyhd8ed1ab_0 conda-forge dill 0.3.8 pypi_0 pypi exceptiongroup 1.2.2 pyhd8ed1ab_0 conda-forge executing 2.1.0 pyhd8ed1ab_0 conda-forge filelock 3.15.4 pypi_0 pypi frozenlist 1.4.1 pypi_0 pypi fsspec 2024.6.1 pypi_0 pypi huggingface-hub 0.24.6 pypi_0 pypi idna 3.8 pypi_0 pypi importlib-metadata 8.4.0 pyha770c72_0 conda-forge importlib_metadata 8.4.0 hd8ed1ab_0 conda-forge ipykernel 6.29.5 pyh3099207_0 conda-forge ipython 8.18.1 pyh707e725_3 conda-forge jedi 0.19.1 pyhd8ed1ab_0 conda-forge jinja2 3.1.4 pypi_0 pypi joblib 1.4.2 pypi_0 pypi jupyter_client 8.6.2 pyhd8ed1ab_0 conda-forge jupyter_core 5.7.2 py39hf3d152e_0 conda-forge ld_impl_linux-64 2.38 h1181459_1 libffi 3.4.4 h6a678d5_1 libgcc 14.1.0 h77fa898_1 conda-forge libgcc-ng 14.1.0 h69a702a_1 conda-forge libgomp 14.1.0 h77fa898_1 conda-forge libsodium 1.0.18 h36c2ea0_1 conda-forge libstdcxx 14.1.0 hc0a3c3a_1 conda-forge libstdcxx-ng 11.2.0 h1234567_1 markupsafe 2.1.5 pypi_0 pypi matplotlib-inline 0.1.7 pyhd8ed1ab_0 conda-forge mpmath 1.3.0 pypi_0 pypi multidict 6.0.5 pypi_0 pypi multiprocess 0.70.16 pypi_0 pypi ncurses 6.4 h6a678d5_0 nest-asyncio 1.6.0 pyhd8ed1ab_0 conda-forge networkx 3.2.1 pypi_0 pypi numpy 2.0.2 pypi_0 pypi nvidia-cublas-cu12 12.1.3.1 pypi_0 pypi nvidia-cuda-cupti-cu12 12.1.105 pypi_0 pypi nvidia-cuda-nvrtc-cu12 12.1.105 pypi_0 pypi nvidia-cuda-runtime-cu12 12.1.105 pypi_0 pypi nvidia-cudnn-cu12 9.1.0.70 pypi_0 pypi nvidia-cufft-cu12 11.0.2.54 pypi_0 pypi nvidia-curand-cu12 10.3.2.106 pypi_0 pypi nvidia-cusolver-cu12 11.4.5.107 pypi_0 pypi nvidia-cusparse-cu12 12.1.0.106 pypi_0 pypi nvidia-nccl-cu12 2.20.5 pypi_0 pypi nvidia-nvjitlink-cu12 12.6.68 pypi_0 pypi nvidia-nvtx-cu12 12.1.105 pypi_0 pypi openssl 3.3.2 hb9d3cd8_0 conda-forge packaging 24.1 pyhd8ed1ab_0 conda-forge pandas 2.2.2 pypi_0 pypi parso 0.8.4 pyhd8ed1ab_0 conda-forge pexpect 4.9.0 pyhd8ed1ab_0 conda-forge pickleshare 0.7.5 py_1003 conda-forge pillow 10.4.0 pypi_0 pypi pip 24.2 py39h06a4308_0 platformdirs 4.2.2 pyhd8ed1ab_0 conda-forge prompt-toolkit 3.0.47 pyha770c72_0 conda-forge psutil 6.0.0 py39hd3abc70_0 conda-forge ptyprocess 0.7.0 pyhd3deb0d_0 conda-forge pure_eval 0.2.3 pyhd8ed1ab_0 conda-forge pyarrow 17.0.0 pypi_0 pypi pygments 2.18.0 pyhd8ed1ab_0 conda-forge python 3.9.17 h955ad1f_0 python-dateutil 2.9.0.post0 pypi_0 pypi python_abi 3.9 2_cp39 conda-forge pytz 2024.1 pypi_0 pypi pyyaml 6.0.2 pypi_0 pypi pyzmq 26.2.0 py39h4e4fb57_1 conda-forge readline 8.2 h5eee18b_0 regex 2024.7.24 pypi_0 pypi requests 2.32.3 pypi_0 pypi safetensors 0.4.5 pypi_0 pypi scikit-learn 1.5.1 pypi_0 pypi scipy 1.13.1 pypi_0 pypi setuptools 72.1.0 py39h06a4308_0 six 1.16.0 pyh6c4a22f_0 conda-forge sqlite 3.45.3 h5eee18b_0 stack_data 0.6.2 pyhd8ed1ab_0 conda-forge sympy 1.13.2 pypi_0 pypi threadpoolctl 3.5.0 pypi_0 pypi timm 1.0.9 pypi_0 pypi tk 8.6.14 h39e8969_0 tokenizers 0.19.1 pypi_0 pypi torch 2.4.1 pypi_0 pypi torchvision 0.19.1 pypi_0 pypi tornado 6.4.1 py39h8cd3c5a_1 conda-forge tqdm 4.66.5 pypi_0 pypi traitlets 5.14.3 pyhd8ed1ab_0 conda-forge transformers 4.44.2 pypi_0 pypi triton 3.0.0 pypi_0 pypi typing_extensions 4.12.2 pyha770c72_0 conda-forge tzdata 2024.1 pypi_0 pypi urllib3 2.2.2 pypi_0 pypi wcwidth 0.2.13 pyhd8ed1ab_0 conda-forge wheel 0.43.0 py39h06a4308_0 xxhash 3.5.0 pypi_0 pypi xz 5.4.6 h5eee18b_1 yarl 1.10.0 pypi_0 pypi zeromq 4.3.5 h6a678d5_0 zipp 3.20.1 pyhd8ed1ab_0 conda-forge zlib 1.2.13 h5eee18b_1
       
      Q. 왜 하필 3.9.17 ?
      A. 3.9 버전이 대체로 안정적이고 그 중에 가장 최신의 마이크로 버전이 3.9.17 이기 때문!
 
사용한 코드
import torch import os from transformers import AutoModelForImageClassification, AutoImageProcessor from datasets import load_dataset from torch.utils.data import DataLoader from torch.optim import Adam import torch.nn as nn from sklearn.preprocessing import LabelEncoder from peft import get_peft_model, LoraConfig # GPU 사용 설정 device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') #------------------------------------------------------ print("Device:", device) #------------------------------------------------------ # 데이터셋 로드 train_dataset = load_dataset("xodhks/EmoSet118K", split="train") test_dataset = load_dataset("xodhks/Children_Sketch", split="train") # 학습 및 테스트 데이터셋을 모두 사용하여 LabelEncoder 학습 all_labels = [item['label'] for item in train_dataset] + [item['label'] for item in test_dataset] label_encoder = LabelEncoder() label_encoder.fit(all_labels) # 테스트 데이터셋의 레이블 목록을 따로 저장 (children_sketch의 레이블만 포함) test_valid_labels = ['anger', 'fear', 'sadness'] test_valid_label_indices = label_encoder.transform(test_valid_labels) # 테스트 레이블의 인덱스 얻기 # 이미지 처리기와 모델 로드 processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224", use_fast=True) model = AutoModelForImageClassification.from_pretrained( "google/vit-base-patch16-224", num_labels=len(label_encoder.classes_), # 전체 레이블의 수 ignore_mismatched_sizes=True # 크기 불일치를 무시 ).to(device) # LoRA 구성 및 적용 config = LoraConfig( r=8, # Rank 설정 lora_alpha=32, lora_dropout=0.1, target_modules=["query", "key", "value"], # LoRA를 적용할 모듈 ) model = get_peft_model(model, config) # top_models 폴더가 없으면 생성 os.makedirs("top_models", exist_ok=True) # 상위 모델을 저장할 리스트 초기화 top_models = [] # DataLoader 설정 def collate_fn(batch): images = [item['image'] for item in batch] labels = [item['label'] for item in batch] # 문자열 레이블을 숫자로 변환 labels = label_encoder.transform(labels) inputs = processor(images=images, return_tensors="pt") inputs['labels'] = torch.tensor(labels, dtype=torch.long) # 레이블을 숫자 텐서로 변환 return inputs train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, collate_fn=collate_fn, num_workers=4) test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False, collate_fn=collate_fn, num_workers=4) # 손실 함수 및 옵티마이저 정의 criterion = nn.CrossEntropyLoss() optimizer = Adam(model.parameters(), lr=1e-4) # 정확도 평가 함수 def evaluate(model, data_loader): model.eval() correct = 0 total = 0 with torch.no_grad(): for batch in data_loader: inputs = {k: v.to(device) for k, v in batch.items()} outputs = model(**inputs) _, preds = torch.max(outputs.logits, 1) # 테스트 데이터셋의 레이블로만 결과를 평가 for pred, label in zip(preds, inputs['labels']): if pred.item() in test_valid_label_indices: # 예측이 테스트 레이블 중 하나라면 if pred.item() == label.item(): correct += 1 total += 1 accuracy = 100 * correct / total return accuracy # 모델 저장 함수 def save_top_models(epoch, accuracy, model, top_models): # 모델을 저장할 파일명 model_filename = f"model_epoch_{epoch + 1}_accuracy_{accuracy:.2f}.pth" model_path = os.path.join("top_models", model_filename) # 현재 모델을 top_models에 추가 top_models.append((accuracy, model_path)) # 정확도 순으로 상위 10개 모델만 유지 top_models = sorted(top_models, key=lambda x: x[0], reverse=True)[:10] # 모델 저장 torch.save(model.state_dict(), model_path) # 상위 10개의 모델 출력 print("\nTop 10 Models (by accuracy):") for i, (acc, path) in enumerate(top_models, 1): print(f"Rank {i}: Accuracy = {acc:.2f}%, Model Path = {path}") return top_models # 모델 학습 루프 num_epochs = 100 for epoch in range(num_epochs): model.train() running_loss = 0.0 for batch in train_loader: optimizer.zero_grad() inputs = {k: v.to(device) for k, v in batch.items()} outputs = model(**inputs) loss = outputs.loss loss.backward() optimizer.step() running_loss += loss.item() #------------------------------------------------------ # Epoch마다 학습 손실 및 테스트 정확도 출력 print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss/len(train_loader):.4f}") # 테스트 데이터로 정확도 평가 test_accuracy = evaluate(model, test_loader) print(f"Test Accuracy after Epoch {epoch+1}: {test_accuracy:.2f}%") # 상위 10개의 모델 저장 및 정확도 출력 top_models = save_top_models(epoch, test_accuracy, model, top_models) #------------------------------------------------------ print("Finished Training")
 
주요 확인점
  • dataloader는 전체 데이터 셋을 활용하였음.
  • 저장하는 모델을 가장 높은 정확도를 보이는 모델로 중간 중간 변경하는 방식으로 저장
 
학습하는 과정에서 GPU의 사용량을 확인할 수 있다
nvidia-smi 명령어를 통해 확인 가능
 
결과
Epoch [26/100], Loss: 0.0447 Test Accuracy after Epoch 26: 19.39% Top 10 Models (by accuracy): Rank 1: Accuracy = 23.17%, Model Path = top_models/model_epoch_3_accuracy_23.17.pth Rank 2: Accuracy = 22.93%, Model Path = top_models/model_epoch_12_accuracy_22.93.pth Rank 3: Accuracy = 22.32%, Model Path = top_models/model_epoch_2_accuracy_22.32.pth Rank 4: Accuracy = 22.32%, Model Path = top_models/model_epoch_5_accuracy_22.32.pth Rank 5: Accuracy = 22.20%, Model Path = top_models/model_epoch_1_accuracy_22.20.pth Rank 6: Accuracy = 22.20%, Model Path = top_models/model_epoch_4_accuracy_22.20.pth Rank 7: Accuracy = 21.71%, Model Path = top_models/model_epoch_14_accuracy_21.71.pth Rank 8: Accuracy = 21.46%, Model Path = top_models/model_epoch_13_accuracy_21.46.pth Rank 9: Accuracy = 21.46%, Model Path = top_models/model_epoch_25_accuracy_21.46.pth Rank 10: Accuracy = 21.34%, Model Path = top_models/model_epoch_8_accuracy_21.34.pth
이런 식으로 상위 10개에 대한 정보가 나열된다.
 
model_epoch_3_accuracy_23.17.pth
337057.3KB
 
 

2. 지금까지 나왔던 의문점들을 GPT-4O 에게 물어보았다.

 
질문
pretrained모델에 대해서 궁금한 점이 있어. 만약 ViT한테 얼굴 감정을 학습시켜서 happy, angry, sad 세가지의 감정을 분류하는 모델을 만들었다고 해보자. 그 다음에 LoRA 방식을 통해서 이번에는 총 8개의 감정을 분류하는 모델로 변형시키려고 하는데, 이 방법이 가능한거야?
 
대답
네, LoRA (Low-Rank Adaptation) 방식을 사용해서 기존에 학습된 모델을 더 큰 범위로 확장하는 것은 가능합니다. 특히, LoRA는 원래 모델의 가중치를 고정한 채로, 새로운 저차원 행렬을 학습시키는 방식으로 추가적인 작업을 수행합니다. 이를 통해 기존의 학습된 지식(예: ViT 모델에서 얼굴 감정을 happy, angry, sad로 분류하는 기능)을 유지하면서, 새로운 정보를 더 적은 연산 비용으로 추가할 수 있습니다. 즉, 기존에 학습된 happy, angry, sad와 같은 감정 분류 작업을 그대로 유지하면서, LoRA를 활용해 추가적인 감정(예: surprised, disgusted 등)을 학습시키는 것이 가능합니다. 이 방식은 크게 두 가지 이점을 가집니다: 기존 모델의 유지: LoRA는 기존 모델의 가중치를 변경하지 않으므로, happy, angry, sad에 대한 분류 성능을 유지할 수 있습니다. 추가 학습 효율성: LoRA를 사용하면 새로운 감정(총 8개의 감정)에 대해 추가적인 학습을 하면서도 학습 비용을 줄일 수 있습니다. 이렇게 LoRA를 사용해 모델을 확장하는 방식은 특히 자원이 제한된 환경에서 효과적이며, 기존 학습된 지식을 그대로 유지하고 새로운 작업을 추가하고 싶을 때 매우 유용합니다. 따라서, ViT 모델에 LoRA를 적용하여 8개의 감정을 분류하는 모델로 변형시키는 것이 가능합니다.

 
질문
만약 happy에 대한 label을 지우고 2개로 세분화 하고 싶으면 어떻게 할 수 있을까
 
대답
만약 기존에 있던 `happy` 레이블을 삭제하고, 이를 더 세분화하여 두 가지 새로운 감정 (예: `joyful`과 `content`)으로 나누고 싶다면, 몇 가지 단계를 통해 이 작업을 수행할 수 있습니다. LoRA를 사용한 방식에서도 이런 변경을 적용할 수 있으며, 다음과 같은 절차를 따르게 됩니다. ### 1. **기존 모델 기반 수정** (LoRA 활용) - **기존 모델 구조 유지**: ViT 기반 모델은 그대로 유지하고, 기존의 `happy` 레이블을 새로운 두 개의 세부 감정 레이블 (`joyful`, `content`)로 교체하는 추가적인 학습을 진행할 수 있습니다. - **데이터 레이블 수정**: 먼저, 기존 데이터에서 `happy`로 라벨링된 데이터를 `joyful`과 `content`로 나눠서 새롭게 레이블링합니다. 이 작업은 데이터 수집 또는 주관적인 기준을 통해 이루어질 수 있습니다. - **LoRA를 통해 학습**: LoRA 방식은 기존 모델의 가중치를 고정한 상태에서 새로운 세부 레이블에 맞게 추가적인 학습을 수행할 수 있습니다. 즉, `happy`에 대한 기존 지식은 유지하되, LoRA로 `joyful`과 `content`의 구분을 학습하는 것이 가능합니다. #### 이 과정의 단계: 1. **데이터셋 조정**: 기존의 `happy` 데이터를 수작업 또는 알고리즘을 사용해 `joyful`과 `content`로 나눕니다. 2. **모델 수정**: 출력 레이어의 차원을 변경해 새로운 레이블을 반영합니다. 기존의 3개 감정(happy, angry, sad)에서 happy를 세분화한 총 4개 감정 (`joyful`, `content`, `angry`, `sad`)으로 변경합니다. 3. **LoRA 학습 적용**: LoRA로 `joyful`과 `content`에 대해 추가적인 미세 조정을 수행합니다. 이 과정에서 기존의 `angry`, `sad`에 대한 지식은 보존되고, 새로운 감정에 대한 분류만 추가로 학습됩니다. ### 2. **새로운 레이블을 위한 재학습** (일반적인 미세 조정) - 기존 모델을 LoRA 없이 재학습하려면, 세분화된 레이블에 대해 모델 전체를 미세 조정(fine-tuning)할 수 있습니다. #### 이 과정의 단계: 1. **데이터 준비**: `happy`에 해당하는 데이터를 두 개의 새로운 레이블로 나눈 후, 이를 포함한 새 데이터셋을 준비합니다. 2. **출력 레이어 수정**: 모델의 마지막 레이어 (분류기)를 수정하여 기존의 감정에 더해 새로운 레이블을 반영할 수 있도록 합니다. 3. **미세 조정**: 모델을 새로운 데이터셋에 대해 재학습시킵니다. 이때, 학습률을 작게 설정하여 기존에 학습된 감정에 대한 정보를 최대한 유지하면서 새로운 레이블에 대한 학습이 진행되도록 합니다. ### 정리 LoRA를 통해 **기존 모델의 지식을 유지한 채**, `happy` 레이블을 `joyful`과 `content`로 세분화하여 학습할 수 있습니다. 또는, 기존 모델을 직접적으로 수정하고, 새로운 레이블에 대해 모델을 재학습하는 방법도 가능합니다.

 
질문
또 궁금한게 있어. 사진에서 웃는 것과 그림으로 그린 웃음을 AI는 같다고 인식해?
 
대답
AI 모델, 특히 이미지 분류나 감정 인식 모델은 **웃는 사진**과 **그림으로 그린 웃음**을 다르게 인식할 수 있습니다. 그 이유는 사진과 그림의 시각적 표현 방식이 다르기 때문입니다. 몇 가지 핵심 차이점을 살펴보면 AI가 이를 다르게 인식할 수 있는 이유가 명확해집니다: ### 1. **사진 vs. 그림의 시각적 차이** - **사진**은 실제 사람의 얼굴을 포착한 이미지로, 자연스럽게 빛, 질감, 그리고 섬세한 표정을 포함하고 있습니다. - **그림**은 이러한 요소들이 작가의 표현 방식에 따라 단순화되거나 과장될 수 있습니다. 예를 들어, 그림은 윤곽선이나 색상이 실제와 다르게 표현될 수 있고, 이는 AI에게 다른 시각적 패턴으로 인식될 수 있습니다. ### 2. **AI의 인식 방식** AI 모델은 **패턴**을 학습합니다. 예를 들어, 웃음의 주요 특징으로는 입꼬리의 상승, 눈 주위의 주름 등이 있을 수 있는데, 사진에서는 이를 자연스럽게 학습할 수 있습니다. 하지만, 그림에서는 이러한 특징이 단순화되거나 왜곡되기 때문에 AI가 학습한 패턴과는 다르게 인식될 수 있습니다. - **사진**에서 학습된 패턴: 실제 얼굴의 자연스러운 음영, 표정 변화, 피부 질감 등이 포함됩니다. - **그림**에서 학습된 패턴: 단순화된 형태, 과장된 윤곽선, 종종 실제와 다른 색조 등이 포함됩니다. 따라서 AI는 **사진과 그림의 웃음을 동일하게 인식하지 않을 수** 있으며, 모델이 이를 구분하는 능력은 주로 모델이 어떻게 학습되었는지, 어떤 데이터셋을 사용했는지에 따라 달라집니다. ### 3. **데이터셋의 중요성** AI가 웃는 사진과 웃는 그림을 비슷하게 인식하게 하려면, 두 가지 유형의 데이터를 모두 학습시켜야 합니다. 만약 AI가 **실제 사진**만을 사용해 학습되었다면, 그림에서의 웃음을 잘 인식하지 못할 가능성이 큽니다. 반대로, 그림을 포함한 데이터셋으로 학습된 AI는 다양한 스타일의 웃음을 더 잘 인식할 수 있습니다. ### 4. **스타일 변환**을 이용한 방법 만약 AI가 사진과 그림을 구분하지 않고 둘 다 **동일하게 인식하도록** 하려면, **스타일 변환**(style transfer) 기법을 사용할 수 있습니다. 예를 들어, GAN(Generative Adversarial Networks)이나 CLIP 기반 모델을 활용하여 서로 다른 스타일의 이미지를 동일한 개념으로 인식하도록 학습할 수 있습니다. ### 결론 기본적으로 AI는 **웃는 사진**과 **웃는 그림**을 다르게 인식할 수 있지만, 이를 같은 것으로 인식하게 하려면 **다양한 스타일의 이미지**로 학습시키거나 **스타일 변환** 등의 기법을 적용할 수 있습니다.

 
질문
GAN과 CLIP기반 모델에 대해 설명해줘
 
대답
GAN과 CLIP은 각각 **생성**과 **멀티모달 학습**에서 중요한 역할을 하는 두 가지 AI 모델입니다. 이 모델들은 서로 다른 방식으로 작동하며, 각각의 장점이 있습니다. 아래에서 **GAN**과 **CLIP**의 개념과 작동 방식을 설명하겠습니다. ### 1. **GAN (Generative Adversarial Networks)** **GAN**은 이미지, 동영상, 텍스트 등을 **생성**하는 데 자주 사용되는 모델입니다. GAN의 핵심 아이디어는 두 개의 신경망(생성자와 판별자)이 서로 경쟁하면서 학습한다는 점입니다. 이 구조 덕분에 GAN은 매우 사실적인 이미지나 데이터를 생성할 수 있습니다. #### GAN의 구성 요소: - **생성자(Generator)**: 임의의 노이즈로부터 데이터를 생성하는 신경망입니다. 생성자는 가능한 한 **진짜처럼 보이는** 데이터를 만들어서 판별자를 속이려고 합니다. 예를 들어, 가짜 이미지를 생성합니다. - **판별자(Discriminator)**: 생성자가 만든 데이터가 진짜인지 가짜인지 구분하는 신경망입니다. 판별자는 생성자가 만든 데이터를 **가짜**로 인식하고, 실제 데이터를 **진짜**로 인식하려고 학습합니다. #### GAN의 작동 방식: - **생성자**는 처음에는 무작위 노이즈에서 시작하여 이미지를 생성하려고 하고, 판별자는 이를 가짜로 분류합니다. - 이 과정이 반복되면서 생성자는 점점 더 진짜처럼 보이는 데이터를 생성하게 되고, 판별자는 점점 더 정교한 기준으로 가짜와 진짜를 구분하게 됩니다. - **경쟁**이 계속되면서, 생성자는 매우 사실적인 데이터를 만들 수 있게 됩니다. #### GAN의 장점: - **이미지 생성**: GAN은 매우 사실적인 이미지를 생성하는 데 탁월합니다. 예를 들어, **딥페이크** 영상이나 **가상 이미지** 생성에 많이 사용됩니다. - **스타일 변환**: 한 이미지의 스타일을 다른 스타일로 변환하는 데에도 사용할 수 있습니다. 예를 들어, 사진을 그림 스타일로 변환하는 방식으로 사용할 수 있습니다. #### 한계: - **불안정한 학습**: GAN은 생성자와 판별자가 균형을 맞추지 못하면 학습이 불안정해질 수 있습니다. 이런 경우, 생성된 데이터의 품질이 낮아지거나 판별자가 쉽게 속여지는 문제가 생길 수 있습니다. --- ### 2. **CLIP (Contrastive Language-Image Pre-training)** **CLIP**은 OpenAI에서 개발한 모델로, **이미지와 텍스트를 멀티모달 방식**으로 연결해 학습하는 방식입니다. CLIP은 다양한 이미지와 텍스트 데이터를 연결하여 학습하고, 이를 바탕으로 주어진 텍스트 설명에 맞는 이미지를 찾거나 생성할 수 있습니다. #### CLIP의 특징: - **이미지-텍스트 연결**: CLIP은 텍스트와 이미지를 함께 학습함으로써, 텍스트 설명을 이미지로 변환하거나, 이미지를 텍스트로 설명하는 작업을 할 수 있습니다. - **멀티모달 학습**: 기존의 이미지 모델들은 이미지만을 학습하지만, CLIP은 **텍스트**와 **이미지**를 동시에 학습하여, 텍스트로 설명된 이미지를 이해하거나 생성하는 데 강력한 성능을 발휘합니다. #### CLIP의 작동 방식: - CLIP은 대규모 데이터셋을 사용해 **이미지**와 **텍스트 설명**을 함께 학습합니다. 예를 들어, "고양이"라는 텍스트와 고양이 사진을 연결시켜 학습한 다음, 이후에는 "고양이"라는 텍스트를 주면 모델이 고양이 이미지를 정확하게 인식하거나 생성할 수 있습니다. - 학습 중, 이미지와 텍스트는 서로 연결되어 고유한 표현 공간을 공유하게 되며, 이를 통해 CLIP은 특정한 이미지나 텍스트에 대응하는 벡터 표현을 생성합니다. #### CLIP의 응용: - **이미지 검색**: CLIP을 사용하면 텍스트를 입력해서 그에 맞는 이미지를 검색하거나, 반대로 이미지를 통해 텍스트 설명을 얻는 작업이 가능합니다. - **텍스트로 이미지 생성**: CLIP은 **DALL·E** 같은 텍스트 기반 이미지 생성 모델에 사용되어, 텍스트 설명을 바탕으로 이미지를 생성할 수 있습니다. #### CLIP의 장점: - **다양한 응용성**: 텍스트와 이미지를 동시에 학습하므로, 다양한 멀티모달 작업에 사용할 수 있습니다. 예를 들어, 이미지의 내용을 텍스트로 설명하거나, 텍스트에 맞는 이미지를 검색하거나 생성할 수 있습니다. - **광범위한 데이터 학습**: 인터넷에서 수집된 광범위한 이미지-텍스트 쌍을 사용해 학습함으로써 매우 다양한 상황에 적용이 가능합니다. #### CLIP의 한계: - **훈련 데이터의 질**: CLIP은 방대한 양의 인터넷 데이터를 기반으로 학습하므로, 데이터의 질이 균일하지 않을 수 있으며, 편향된 데이터를 학습할 가능성도 있습니다. --- ### 요약: - **GAN**은 두 네트워크 간의 경쟁을 통해 **사실적인 데이터 생성**에 초점을 맞춘 모델로, 이미지 생성 및 스타일 변환에 탁월합니다. - **CLIP**은 **텍스트와 이미지를 연결**하는 멀티모달 학습 모델로, 이미지와 텍스트를 동시에 이해하고 생성하는 데 강력한 성능을 발휘합니다. 이 두 모델은 서로 다른 목적을 위해 설계되었지만, 함께 사용하면 GAN이 생성한 이미지를 CLIP을 통해 텍스트와 연결하거나, CLIP을 활용해 GAN의 학습 효율을 높일 수 있는 방식으로 응용이 가능합니다.
 
질문
pretrained model에 대해서 궁금한 점이 있어. 만약에 내가 https://huggingface.co/dima806/facial_emotions_image_detection 이 모델을 가지고 LoRA학습을 진행하려고 해. 이 모델은 sad disgust angry neutral fear surprise happy 이렇게 7개의 label을 출력하도록 학습되어 있는 것을 확인할 수 있어. 근데 내가 학습시키고 싶은 데이터셋은 8개고 해당 모델의 output과는 다른 emotion을 출력하도록 되어있어. https://huggingface.co/datasets/xodhks/EmoSet118K 이게 사용할 데이터셋이야. 그런데 이거를 그대로 학습하는 것을 불가능하니까 이를 바꾸는 작업이 필요할 거 같은데 어떻게 해야할까
 
대답
현재 pretrained된 모델은 7개의 감정 레이블을 출력하도록 되어 있고, 새로운 데이터셋에서는 8개의 감정을 다루기 때문에 이를 맞추기 위한 몇 가지 작업이 필요합니다. 아래 단계에 따라 진행하시면 됩니다: 레이블 매핑 분석: 먼저, pretrained 모델의 7개 레이블(sad, disgust, angry, neutral, fear, surprise, happy)과 새로운 데이터셋의 8개 레이블(amusement, anger, awe, contentment, disgust, excitement, fear, sadness)을 비교하세요. 이때 중복되거나 비슷한 감정은 어떻게 처리할지 결정해야 합니다. 예를 들어: sad → sadness angry → anger disgust → disgust fear → fear neutral은 contentment와 같이 비슷한 감정으로 매핑할 수 있습니다. surprise, happy 등의 레이블은 새로운 레이블로 대체하거나 가장 적절한 감정과 매칭할 필요가 있습니다. 출력층 수정: pretrained 모델은 7개의 레이블을 출력하지만, 새 데이터셋은 8개를 출력해야 하기 때문에 모델의 마지막 분류 레이어를 수정해야 합니다. 이를 위해 다음과 같은 방법으로 진행할 수 있습니다: pretrained 모델을 불러옵니다. 마지막 분류 레이어(nn.Linear)를 8개의 클래스를 출력하도록 새롭게 변경합니다. 모델의 나머지 레이어들은 초기에는 동결(freeze)시켜두고, LoRA로 학습할 레이어와 마지막 분류 레이어만 학습 가능하게 설정합니다. LoRA 적용: 그 후, LoRA를 사용해 원하는 레이어에 저차원 적응(LoRA)을 적용하여 fine-tuning을 진행합니다. 이를 통해 pretrained된 모델의 대부분의 지식을 유지하면서도 새로운 데이터셋에 맞게 모델을 최소한의 추가 파라미터로 적응시킬 수 있습니다. 데이터 전처리: EmoSet 데이터셋의 레이블이 숫자 포맷으로 잘 인코딩되어 새 모델의 출력 클래스(0–7)에 맞도록 변환되었는지 확인하세요. 학습: 이제 LoRA를 사용해 새로운 데이터셋으로 모델을 fine-tuning할 수 있습니다. 학습할 때 pretrained 모델과 데이터셋의 차이를 고려해 과적합을 방지할 수 있도록 가중치 감쇠(weight decay)나 조기 종료(early stopping)와 같은 규제 기법을 적용하는 것이 좋습니다.
 
질문
내가 알기론 스타일 변환 기법에는 GAN기법과 CLIP기법이 있는 것으로 알고 있어. 그거랑 별개로 도메인 적응, 데이터 증강 및 특징 추출에서는 어떤 방법이 있는지 알고 싶고 각각의 방법을 어떻게 시도하면 좋을 지 조언해줘
 
대답
네, 스타일 변환 기법에 대해서는 잘 알고 계시네요! GAN과 CLIP 기법 외에도 다양한 스타일 변환 방법이 존재합니다. 그와 별개로, 도메인 적응, 데이터 증강, 특징 추출에서 사용할 수 있는 다양한 방법들을 소개하고, 각 기법을 어떻게 적용할 수 있을지에 대해 설명하겠습니다. ### 1. **도메인 적응(Domain Adaptation)** 도메인 적응은 서로 다른 도메인 간의 차이를 줄이기 위해 사용하는 기술입니다. 주요 기법들은 다음과 같습니다: #### a. **Domain-Adversarial Neural Networks (DANN)** - **방법**: DANN은 모델이 도메인 간 차이를 무시하도록 강제합니다. 네트워크는 피처 추출기(Feature Extractor), 분류기(Classifier), 도메인 분류기(Domain Classifier)로 구성됩니다. 도메인 분류기는 입력이 어느 도메인에서 온 것인지 예측하고, 반대로 피처 추출기는 이 도메인을 구분하기 어렵게 만들려고 학습합니다. - **적용 방법**: PyTorch에서 DANN을 구현하는 방법은, 기존의 모델에 도메인 분류기와 그라디언트 리버설 레이어(Gradient Reversal Layer, GRL)를 추가하여 도메인 적응 기능을 포함시키는 것입니다. 학습 중 도메인 분류기를 통한 손실을 최소화하면서, 피처 추출기를 통해 도메인 차이를 줄입니다. #### b. **Maximum Mean Discrepancy (MMD)** - **방법**: MMD는 서로 다른 도메인에서의 피처 분포 차이를 최소화하는 방법입니다. 두 도메인의 피처 분포가 서로 가까워지도록 학습을 진행합니다. - **적용 방법**: 피처 추출기에서 추출된 중간 레이어의 피처들이 원본 도메인과 타깃 도메인에서 서로 비슷하게 분포하도록 MMD 손실을 사용해 학습을 진행할 수 있습니다. #### c. **Domain-Transferred Learning (DTL)** - **방법**: DTL은 학습 도메인의 정보를 타깃 도메인으로 직접 전이하는 기법입니다. 사전 학습된 모델을 사용하거나, 특화된 특징을 학습한 후 그 모델을 그림 데이터에 맞추어 fine-tuning할 수 있습니다. - **적용 방법**: 사진 데이터로 모델을 먼저 학습한 후, 모델의 마지막 몇 개 레이어를 학습 가능하도록 열어두고 그림 데이터로 미세 조정(fine-tuning)을 진행하는 것이 일반적인 방법입니다. ### 2. **데이터 증강(Data Augmentation)** 데이터 증강은 적은 양의 데이터를 다양한 방식으로 변형하여 데이터의 크기와 다양성을 인위적으로 늘리는 기법입니다. 그림 데이터셋을 증강할 때는 그 특성을 고려해 보다 창의적인 증강 기법을 적용할 수 있습니다. #### a. **Standard Augmentation Techniques** - **방법**: 회전, 크기 조절, 자르기(cropping), 반전(flipping), 밝기/채도 변화와 같은 전통적인 데이터 증강 기법을 사용합니다. - **적용 방법**: `Albumentations`, `TorchVision`과 같은 라이브러리를 활용하여 다양한 증강 기법을 자동으로 적용할 수 있습니다. #### b. **GAN 기반 데이터 증강** - **방법**: **StyleGAN**이나 **CycleGAN**과 같은 GAN을 사용하여 새로운 그림 스타일을 생성하거나 두 도메인 간 변환을 통해 데이터 증강을 할 수 있습니다. - **적용 방법**: CycleGAN은 사진 이미지를 그림 스타일로 변환하는 데 효과적입니다. 이를 통해 사진 데이터에 그림 스타일을 입힌 새로운 데이터를 만들어 학습에 사용할 수 있습니다. #### c. **Mixup 및 CutMix** - **방법**: 두 개의 이미지를 섞어서 새로운 이미지를 만드는 기법입니다. Mixup은 두 이미지를 선형적으로 결합하고, CutMix는 이미지를 자른 후 결합합니다. - **적용 방법**: 이미지와 그 레이블을 섞어서 데이터 증강을 진행함으로써, 적은 데이터를 보완하고 모델의 일반화 성능을 높일 수 있습니다. ### 3. **특징 추출(Feature Extraction)** 특징 추출은 사전 학습된 모델에서 학습된 피처(중간 레이어의 출력)를 활용해 새로운 데이터를 처리하는 기법입니다. #### a. **Pretrained Models (ResNet, EfficientNet 등)** - **방법**: 사전 학습된 모델의 중간 레이어에서 이미지의 고수준 특징을 추출한 후, 이를 새로운 데이터셋에서 학습에 활용합니다. - **적용 방법**: 이미지넷(Imagenet) 등에서 학습된 모델의 중간 레이어 피처를 고정시키고, 마지막 분류 레이어만 새 데이터셋에 맞춰 재학습(fine-tuning)할 수 있습니다. #### b. **Self-Supervised Learning** - **방법**: 레이블이 없는 데이터에서 피처를 학습하는 기법으로, 사전 학습된 모델을 기반으로 타깃 도메인에 맞게 피처를 추출합니다. 대표적인 방법으로는 **SimCLR**, **BYOL**, **MoCo**가 있습니다. - **적용 방법**: 그림 데이터셋에서 레이블이 없어도 특징을 추출할 수 있도록 Self-Supervised Learning 방법을 적용한 후, 추출된 특징을 사용해 모델을 fine-tuning할 수 있습니다. #### c. **Multi-task Learning** - **방법**: 여러 태스크를 동시에 학습하여 특정 태스크에서 학습된 피처를 다른 태스크에서도 활용할 수 있도록 합니다. 감정 분류 외에도 스타일 분류 등의 태스크를 추가하여 학습을 진행할 수 있습니다. - **적용 방법**: 감정 분류 태스크와 함께 다른 유사한 태스크를 추가하여, 다양한 도메인에서 공통적으로 학습된 피처를 그림 데이터에 맞춰 활용합니다. ### 적용 순서 및 방법 1. **도메인 적응**: DANN이나 MMD 같은 도메인 적응 기법을 먼저 적용하여, 사진 데이터와 그림 데이터 간 도메인 차이를 줄여보세요. 2. **데이터 증강**: 그림 데이터셋이 적다면, GAN 기반 증강과 Mixup, CutMix 같은 기술로 그림 데이터의 양과 다양성을 늘립니다. 3. **특징 추출**: 사전 학습된 모델을 사용해 피처를 추출하고, 이 피처들을 사용해 그림 데이터셋에 맞게 fine-tuning을 시도합니다. 이 방법들을 순차적으로 또는 조합하여 적용해 보시면, 적은 양의 그림 데이터셋에서 보다 좋은 성능을 기대할 수 있을 것입니다. 더 구체적인 사항이나 추가적인 코드 예제가 필요하면 알려주세요!
 
질문
GAN 혹은 CLIP형식을 적용한다는 것은 사진 데이터셋을 임포트 한 후에 사진을 그림으로 변환하여 학습한다는 것으로 알면 되는걸까?
 
대답
네, 정확하게 이해하셨습니다! GAN이나 CLIP 기반 형식을 적용한다는 것은 **사진 데이터를 그림 스타일로 변환**하여 학습에 사용하는 것을 의미합니다. 이를 통해 모델이 그림 데이터셋에서 더 잘 작동할 수 있도록 도메인 차이를 줄이는 것이죠. ### 구체적인 적용 방법 1. **사진 데이터를 그림으로 변환** - **CycleGAN**이나 **StyleGAN**과 같은 GAN 모델을 사용하여 사진 데이터를 그림 스타일로 변환합니다. CycleGAN은 이미지 도메인 간 변환에 탁월하며, 이를 통해 사진 데이터를 그림과 유사한 스타일로 바꿀 수 있습니다. - 이때, 학습 중 CycleGAN으로 변환된 데이터를 추가하거나, 아예 변환된 데이터로만 학습을 진행할 수 있습니다. 2. **변환된 데이터를 학습에 사용** - 변환된 그림 스타일 이미지를 사용하여 모델을 학습시킵니다. 이 과정에서 원본 사진 데이터와 변환된 그림 데이터 모두를 학습에 활용할 수도 있고, 변환된 데이터만으로도 학습할 수 있습니다. - 이렇게 하면 모델이 그림 데이터의 특성에 더 적응할 수 있고, 그림 데이터셋에서 더 좋은 성능을 낼 수 있습니다. ### CLIP을 활용하는 경우 CLIP은 **이미지와 텍스트 간 연관성**을 학습한 모델입니다. CLIP을 사용하면 사진과 그림 간의 특징을 **다른 표현 방식을 이해하는 능력**을 통해 연결할 수 있습니다. 이 경우에는 사진 데이터를 그대로 학습하되, CLIP의 텍스트 설명을 이용해 감정 분류를 지원하는 방식으로 접근할 수 있습니다. 정리하자면: - **GAN 기반 방법**: 사진 데이터를 그림 스타일로 변환하여 그림 데이터셋과의 도메인 차이를 줄이려는 방법입니다. - **CLIP 기반 방법**: 이미지 간 도메인 차이를 직접 처리하기보다는 이미지와 텍스트 간의 관계를 학습한 CLIP 모델을 활용하여 감정 분류에 필요한 정보를 추출하는 방법입니다. 만약 CycleGAN이나 CLIP을 사용할 방법에 대해 더 구체적인 코드나 워크플로우가 필요하시면, 언제든지 말씀해 주세요!
 
질문
 
대답
좋습니다! 현재 Conda의 UGRP 가상환경에서 작업 중이시고, 명령어 실행 위치에 대해 좀 더 명확하게 설명을 원하시는군요. 각 명령어가 실행될 정확한 폴더 위치를 명시하면서, 전체 과정을 다시 정리해드릴게요. ### 1. **CycleGAN 설치 및 준비** #### Step 1: 가상환경 활성화 먼저 UGRP 가상환경을 활성화한 상태에서 작업을 진행합니다. ```bash conda activate UGRP # UGRP 가상환경 활성화 ``` #### Step 2: PyTorch 설치 가상환경에서 PyTorch를 설치합니다. 이때, CUDA를 사용하실 수 있다면, 맞는 버전을 설치해주세요. ```bash # (UGRP 가상환경에서) # PyTorch 설치 pip install torch torchvision torchaudio ``` #### Step 3: CycleGAN 코드 다운로드 CycleGAN 코드를 다운로드할 위치는 상관없지만, 프로젝트 폴더 안에 다운로드하는 것을 추천합니다. 예를 들어, 홈 디렉토리나 작업 디렉토리에서 실행할 수 있습니다. ```bash # 홈 디렉토리 혹은 원하는 작업 디렉토리에서 실행 cd ~/your_project_directory # 작업 디렉토리로 이동 git clone https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix # CycleGAN 코드 다운로드 cd pytorch-CycleGAN-and-pix2pix # CycleGAN 디렉토리로 이동 ``` #### Step 4: 필요한 패키지 설치 CycleGAN 프로젝트 폴더에서 패키지를 설치합니다. ```bash # (pytorch-CycleGAN-and-pix2pix 폴더 안에서 실행) pip install -r requirements.txt ``` ### 2. **사전 학습된 CycleGAN 모델 다운로드** CycleGAN의 사전 학습된 모델을 다운로드합니다. 이 명령어도 CycleGAN 코드가 있는 디렉토리 안에서 실행해야 합니다. ```bash # (pytorch-CycleGAN-and-pix2pix 폴더 안에서 실행) bash ./scripts/download_cyclegan_model.sh horse2zebra ``` 이 명령어는 `checkpoints/horse2zebra_pretrained/` 폴더에 사전 학습된 모델을 다운로드합니다. ### 3. **데이터 준비** #### Step 1: 사진 데이터셋 준비 사진 데이터셋을 `datasets/your_photo_dataset/` 폴더 안에 준비합니다. CycleGAN 폴더 안에서 `datasets` 폴더를 만들어서 진행하는 것이 좋습니다. ```bash # (pytorch-CycleGAN-and-pix2pix 폴더 안에서 실행) mkdir -p datasets/your_photo_dataset/trainA mkdir -p datasets/your_photo_dataset/testA # 여기서 trainA와 testA 폴더에 각각 사진 이미지를 넣습니다. ``` ### 4. **CycleGAN을 사용해 사진 데이터를 그림 스타일로 변환** #### Step 1: 변환 실행 CycleGAN 프로젝트 폴더 안에서 사진 데이터를 그림 스타일로 변환합니다. ```bash # (pytorch-CycleGAN-and-pix2pix 폴더 안에서 실행) python test.py --dataroot ./datasets/your_photo_dataset --name horse2zebra_cyclegan --model test --no_dropout ``` 이 명령어가 실행되면, 변환된 이미지는 `results/horse2zebra_cyclegan/test_latest/images/` 폴더에 저장됩니다. ### 5. **변환된 데이터 업로드 및 학습 준비** #### Step 1: 변환된 이미지 확인 및 업로드 변환된 이미지를 확인한 후, 업로드를 진행합니다. 업로드할 변환된 이미지는 `pytorch-CycleGAN-and-pix2pix/results/horse2zebra_cyclegan/test_latest/images/`에 저장되어 있습니다. Hugging Face나 Google Drive 등에 업로드할 수 있으며, Hugging Face에 업로드하는 경우, 다음과 같은 명령어를 사용할 수 있습니다. ```bash # (UGRP 가상환경에서 실행) pip install datasets huggingface_hub # Hugging Face 로그인 huggingface-cli login # 데이터셋 업로드 from datasets import load_dataset from huggingface_hub import HfApi # 업로드할 데이터셋 경로와 이름 설정 api = HfApi() api.create_repo("your_username/photo_to_sketch_transformed", private=True) # 데이터셋 업로드 !datasets-cli upload ./results/horse2zebra_cyclegan/test_latest/images --name your_username/photo_to_sketch_transformed ``` #### Step 2: 학습에 사용 업로드한 변환된 데이터를 사용해 감정 분류 모델을 학습할 준비를 마칩니다. ### 요약 1. **UGRP 가상환경 활성화**: `conda activate UGRP` 2. **CycleGAN 설치 및 데이터 준비**: `pytorch-CycleGAN-and-pix2pix` 폴더에서 작업. 3. **사진 -> 그림 변환**: 변환된 이미지가 `results/horse2zebra_cyclegan/test_latest/images/`에 저장됨. 4. **변환된 데이터 업로드**: Hugging Face 등에 업로드하여 학습에 사용. 이제 정확한 경로와 명령어 실행 위치를 알 수 있으니, 이대로 진행하시면 됩니다. 추가적으로 궁금한 점이나 문제가 발생하면 알려주세요!

 

좀 더 생각해 봐야 할 것

[논문리뷰] Cycle GAN: Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks
[논문리뷰] Cycle GAN: Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks

[논문리뷰] Cycle GAN: Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks

Paper review for Cycle GAN