Skip to main content

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

Published 4 min readMarkdown

# 📌 서론 – 왜 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 생태계를 만들어 갑시다! 🚀

No comments yet. Be the first to comment.

More from this blog