# MedGemma 파인튜닝으로 유방암 영상 분류하기: 초보자를 위한 단계별 실전 가이드 (55자)

---

# # 📌 서론 – 왜 MedGemma와 유방암 영상 분류가 중요한가?

유방암은 여성에게 가장 흔히 발생하는 암 중 하나이며, 조기 발견이 치료 성공률을 크게 높입니다. 최근 의료 영상 데이터에 딥러닝을 적용해 **정확한 종양 판별**이 가능해졌지만, **전문 모델을 직접 구축하기는 어렵다**는 장벽이 남아 있습니다.

여기서 등장하는 것이 **MedGemma**입니다. MedGemma는 의료 영상에 특화된 사전 학습 모델로, 비교적 적은 데이터와 컴퓨팅 자원만으로도 높은 성능을 낼 수 있습니다. 하지만 “파인튜닝”이라는 용어가 생소하고, 실제 코드를 어떻게 적용해야 할지 막막한 분들이 많습니다.

이 글에서는 **초보자도 따라 할 수 있는** 단계별 가이드를 통해 MedGemma를 **유방암 종양 분류** 작업에 맞게 파인튜닝하는 전체 흐름을 상세히 설명합니다.

> **키워드**: MedGemma 파인튜닝, 유방암 영상 분류, 머신러닝 가이드

---

# # 🛠️ 본론

## # 1️⃣ 환경 준비 – 필수 도구와 데이터셋 확보

| 항목 | 권장 버전 | 설치 명령 |

|------|-----------|-----------|

| Python | 3.9 이상 | `pip install python==3.9` |

| PyTorch | 2.0 이상 | `pip install torch torchvision` |

| Hugging Face 🤗 Transformers | 최신 | `pip install transformers` |

| MedGemma 모델 파일 | `medgemma-base` | `git clone https://github.com/google/medgemma` |

| 데이터셋 | **CBIS‑DD‑SM** (유방암 초음파·MRI) | `wget https://example.com/cbis-dd-sm.zip` |

> **Tip**: GPU가 있는 환경이면 `torch.cuda.is_available()` 로 확인하고, 없는 경우 `torch.device('cpu')` 로 자동 전환하도록 코드를 작성합니다.

### # 데이터 전처리 핵심 포인트

- **이미지 크기統一**: 224×224 로 리사이즈

- **정규화**: ImageNet 평균·표준편차 사용 (`mean=[0.485,0.456,0.406]`, `std=[0.229,0.224,0.225]`)

- **라벨 인코딩**: 악성(1) / 양성(0) 이진 라벨

```
python

from torchvision import transforms

train_transform = transforms.Compose([

    transforms.Resize((224,224)),

    transforms.RandomHorizontalFlip(),

    transforms.ToTensor(),

    transforms.Normalize(mean=[0.485,0.456,0.406],

                         std=[0.229,0.224,0.225])

])

```

---

## # 2️⃣ MedGemma 모델 로드 및 구조 이해

```
python

from transformers import AutoModelForImageClassification, AutoFeatureExtractor

model_name = 'google/medgemma-base'

feature_extractor = AutoFeatureExtractor.from_pretrained(model_name)

model = AutoModelForImageClassification.from_pretrained(

    model_name,

    num_labels=2,          # 악성 / 양성

    id2label={0:'Benign',1:'Malignant'},

    label2id={'Benign':0,'Malignant':1}

)

```

- **Backbone**: Vision Transformer (ViT) 기반, 12개의 트랜스포머 블록

- **Head**: 기본적으로 1000개의 클래스용 Linear 레이어 → `num_labels=2` 로 교체

- **왜 파인튜닝이 필요한가?**: 사전 학습은 일반 의료 이미지(CT, X‑ray 등)로 이루어졌으며, 유방암 초음파·MRI와는 도메인 차이가 존재합니다. 마지막 레이어만 교체하고 전체 네트워크를 **미세 조정**하면 도메인 적응이 가능합니다.

---

## # 3️⃣ 학습 파라미터 설정 및 트레이닝 루프 구현

| 파라미터 | 값 | 설명 |

|----------|----|------|

| 배치 크기 | 16 | GPU 메모리 기준 조절 |

| 학습률 | 3e-4 | Warm‑up 후 1e-5 로 감소 |

| Epoch | 10 | 조기 종료(Early Stopping) 적용 |

| Optimizer | AdamW | 가중치 감쇠 0.01 |

| Scheduler | CosineAnnealingLR | 학습률 스케줄링 |

```
python

import torch

from torch.utils.data import DataLoader

from transformers import get_cosine_schedule_with_warmup

train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)

val_loader   = DataLoader(val_dataset, batch_size=16)

optimizer = torch.optim.AdamW(model.parameters(), lr=3e-4, weight_decay=0.01)

scheduler = get_cosine_schedule_with_warmup(

    optimizer,

    num_warmup_steps=int(0.1*len(train_loader)*10),   # 10% warm-up

    num_training_steps=int(len(train_loader)*10)

)

criterion = torch.nn.CrossEntropyLoss()

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

model.to(device)

for epoch in range(10):

    model.train()

    for batch in train_loader:

        imgs, labels = batch['pixel_values'].to(device), batch['labels'].to(device)

        outputs = model(imgs)

        loss = criterion(outputs.logits, labels)

        loss.backward()

        optimizer.step()

        scheduler.step()

        optimizer.zero_grad()

    # 검증 단계

    model.eval()

    # (검증 로직 생략)

    print(f'Epoch {epoch+1} - loss: {loss.item():.4f}')

```

### # 체크포인트 저장

```
python

torch.save({

    'epoch': epoch,

    'model_state_dict': model.state_dict(),

    'optimizer_state_dict': optimizer.state_dict(),

}, f'checkpoint_epoch_{epoch}.pth')

```

---

## # 4️⃣ 모델 평가 및 실전 적용 팁

| 지표 | 목표값 (예시) |

|------|--------------|

| 정확도(Accuracy) | ≥ 0.92 |

| AUC‑ROC | ≥ 0.95 |

| F1‑Score | ≥ 0.90 |

- **Confusion Matrix** 로 FP(양성 오진)와 FN(음성 오진) 비율을 시각화

- **Grad‑CAM** 을 활용해 모델이 어떤 부위를 주목했는지 확인 → 의료 전문가와 협업 시 신뢰도 향상

```
python

from sklearn.metrics import classification_report, roc_auc_score

# predictions, true_labels 수집 후

print(classification_report(true_labels, preds, target_names=['Benign','Malignant']))

print('AUC-ROC:', roc_auc_score(true_labels, probas[:,1]))

```

**실전 팁**

1. **데이터 불균형**: 악성 사례가 적다면 `WeightedRandomSampler` 혹은 `Focal Loss` 적용.

2. **전이 학습**: 전체 레이어를 동결하고 Head만 학습 후, 전체 레이어를 **점진적 해동**(gradual unfreeze) 하면 안정적인 수렴을 기대.

3. **배포**: `torchscript` 로 모델을 변환 후, Flask 혹은 FastAPI 로 간단한 웹 서비스 구현 가능.

---

## # 5️⃣ 흔히 마주치는 오류와 해결 방법

| 오류 | 원인 | 해결책 |

|------|------|--------|

| `RuntimeError: CUDA out of memory` | 배치가 너무 큼 | 배치 크기 8 이하로 감소 혹은 `torch.cuda.empty_cache()` |

| `ValueError: num_labels mismatch` | Head 레이어 교체 누락 | `model.classifier = torch.nn.Linear(in_features, 2)` 로 명시적 교체 |

| `NaN loss` | 학습률 과다 | 학습률을 1e-5 수준으로 낮추고, `torch.nn.functional.cross_entropy` 사용 시 `ignore_index` 확인 |

---

# # 🎯 결론 – 이제 직접 MedGemma를 활용해 보세요!

MedGemma 파인튜닝은 **복잡한 의료 AI 개발**을 크게 낮춰줍니다. 위 5단계(환경 준비 → 모델 로드 → 학습 설정 → 평가 → 오류 해결)를 차근차근 따라 하면, 초보자도 **유방암 영상 분류 모델**을 직접 구축하고 검증할 수 있습니다.

> **지금 바로 실행해 보세요!**

> 1. GitHub에서 MedGemma 코드를 클론하고, 데이터셋을 다운로드합니다.

> 2. 위 코드 스니펫을 자신의 환경에 맞게 수정 후 실행합니다.

> 3. 모델이 만족스러운 성능을 보이면, 간단한 웹 API 로 배포해 의료 현장에서 테스트해 보세요.

---

## # 📢 행동 유도 (Call‑to‑Action)

- **무료 워크숍 신청**: “MedGemma와 함께하는 의료 AI 입문” 온라인 세미나 (링크 삽입)

- **GitHub 스타**: 이 가이드가 도움이 되었다면 프로젝트에 ⭐️를 눌러 주세요!

- **문의 및 피드백**: 댓글 또는 이메일(hello@yourblog.com) 로 언제든 질문해 주세요.

함께 더 나은 의료 AI 생태계를 만들어 갑시다! 🚀
