Skip to content
 
 

Repository files navigation

🦴 X-Ray Bone Segmentation

손 X-Ray 이미지에서 뼈를 29개 클래스로 세그멘테이션하는 딥러닝 프로젝트입니다. 자세한 프로젝트 진행 내용은 WrapUpReport를 참고해주세요!

WrapUpReport

📋 목차

  1. 프로젝트 구조
  2. 환경 설정
  3. 빠른 시작
  4. 실험 진행 방법
  5. 설정 파일 가이드
  6. WandB 사용법
  7. TTA (Test Time Augmentation)
  8. 앙상블 (Ensemble)
  9. 협업 규칙
  10. 대회 제출용 CSV 생성
  11. 트러블슈팅
  12. 실험 체크리스트
  13. 29개 클래스 목록

📁 프로젝트 구조

Xray-Segmentation/
├── .gitignore          # Git 무시 파일 목록
├── README.md           # 이 파일
├── requirements.txt    # 필요 라이브러리 목록
├── main.py             # 학습/추론 메인 코드
├── configs/            # 실험 설정 파일 (YAML)
│   ├── base_config.yaml         # 기본 설정 템플릿
│   ├── exp01_fcn_resnet50.yaml  # 실험 1: FCN 베이스라인
│   ├── exp02_loss_experiment.yaml    # 실험 2: Loss 실험
│   └── exp03_augmentation.yaml  # 실험 3: Augmentation 실험
├── src/                # 핵심 코드 모듈
│   ├── __init__.py
│   ├── dataset.py      # 데이터셋 클래스
│   ├── models.py       # 모델 정의
│   ├── losses.py       # Loss 함수
│   └── utils.py        # 유틸리티 함수
├── notebooks/          # (생성 필요) EDA, 개인 실험용 노트북
├── data/               # (Git 무시) 데이터셋 심볼릭 링크 또는 복사
└── saved_models/       # (Git 무시) 학습된 모델 저장

⚙️ 환경 설정

1. 저장소 클론

git clone [repository-url]
cd Xray-Segmentation

2. 가상환경 생성 (권장)

# conda 사용시
conda create -n xray python=3.10
conda activate xray

# 또는 venv 사용시
python -m venv venv
source venv/bin/activate  # Linux/Mac
# venv\Scripts\activate   # Windows

3. 라이브러리 설치

pip install -r requirements.txt

# PyTorch GPU 버전 설치 (CUDA 11.8 기준)
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118

4. 데이터 경로 설정

데이터는 Git에 올리지 않으므로 심볼릭 링크 또는 config 파일 수정으로 연결합니다.

# 방법 1: 심볼릭 링크 생성
ln -s /path/to/Xray-Segmentation/data/train
ln -s /path/to/Xray-Segmentation/data/test

# 방법 2: config 파일에서 직접 경로 수정
# configs/base_config.yaml의 data 섹션 수정

🚀 빠른 시작

학습 실행

# 기본 실험 (FCN ResNet50)
python main.py --config configs/exp01_fcn_resnet50.yaml --mode train

# Loss 실험 (BCE + Dice)
python main.py --config configs/exp02_loss_experiment.yaml --mode train

# Augmentation 실험
python main.py --config configs/exp03_augmentation.yaml --mode train

추론 실행

# 방법 1: main.py 사용 (config 파일 필요)
python main.py --config configs/exp01_fcn_resnet50.yaml --mode inference

# 방법 2: inference.py 사용 (더 간단!)
python inference.py --config configs/exp01_fcn_resnet50.yaml

# 방법 3: 모델 경로 직접 지정
python inference.py --model saved_models/exp01/best_model.pt --output output.csv

# 방법 4: 상세 옵션 지정
python inference.py --model saved_models/exp01/best_model.pt \
                    --model_name fcn_resnet50 \
                    --test_root data/test/DCM \
                    --output my_submission.csv \
                    --threshold 0.5

# 방법 5: TTA 사용 (성능 향상!)
python inference.py --config configs/exp01_fcn_resnet50.yaml --tta
python inference.py --model saved_models/exp01/best_model.pt --tta --output output_tta.csv

학습 + 추론 한번에

python main.py --config configs/exp01_fcn_resnet50.yaml --mode all

🧪 실험 진행 방법

Step 1: 새 실험 설정 파일 생성

# base_config.yaml을 복사하여 새 실험 파일 생성
cp configs/base_config.yaml configs/exp04_your_experiment.yaml

Step 2: 설정 파일 수정

# configs/exp04_your_experiment.yaml

experiment:
  name: "exp04_deeplabv3"           # ✏️ 실험 이름 수정
  description: "DeepLabV3 실험"      # ✏️ 설명 추가
  author: "your_name"               # ✏️ 본인 이름

model:
  name: "deeplabv3_resnet101"       # ✏️ 모델 변경
  pretrained: true

loss:
  name: "bce_dice"                  # ✏️ Loss 변경
  bce_weight: 0.5
  dice_weight: 0.5

save:
  dir: "saved_models/exp04_deeplabv3"  # ✏️ 저장 폴더 수정

Step 3: 학습 실행

python main.py --config configs/exp04_your_experiment.yaml --mode train

Step 4: 결과 기록

실험 결과를 팀 노션이나 스프레드시트에 기록합니다.


📝 설정 파일 가이드

🏗️ 사용 가능한 모델

모델명 설명 메모리 사용량
fcn_resnet50 FCN with ResNet50 낮음
fcn_resnet101 FCN with ResNet101 중간
deeplabv3_resnet50 DeepLabV3 with ResNet50 중간
deeplabv3_resnet101 DeepLabV3 with ResNet101 높음
deeplabv3_mobilenet DeepLabV3 with MobileNet 낮음
model:
  name: "deeplabv3_resnet101"  # 원하는 모델 선택
  pretrained: true

📉 사용 가능한 Loss 함수

Loss명 설명 사용 상황
bce Binary Cross Entropy 기본 베이스라인
dice Dice Loss 클래스 불균형
bce_dice BCE + Dice 조합 안정적인 학습
focal Focal Loss 심한 클래스 불균형
tversky Tversky Loss FP/FN 가중치 조절
# BCE만 사용
loss:
  name: "bce"

# BCE + Dice 조합
loss:
  name: "bce_dice"
  bce_weight: 0.5    # BCE 가중치
  dice_weight: 0.5   # Dice 가중치

# Focal Loss
loss:
  name: "focal"
  alpha: 0.25        # 양성 클래스 가중치
  gamma: 2.0         # focusing parameter

# Tversky Loss
loss:
  name: "tversky"
  alpha: 0.3         # FP 가중치
  beta: 0.7          # FN 가중치

🔄 Augmentation 옵션

augmentation:
  train:
    resize: 512                # 이미지 크기
    horizontal_flip: false     # 좌우 반전 (X-ray는 주의)
    vertical_flip: false       # 상하 반전
    rotate: true               # 회전
    rotate_limit: 15           # 회전 각도 범위 (±15도)
    brightness_contrast: true  # 밝기/대비 조절
    elastic_transform: true    # Elastic 변형
    grid_distortion: true      # Grid 왜곡
  valid:
    resize: 512

🎓 학습 파라미터

training:
  epochs: 50              # 총 에폭 수
  batch_size: 8           # 배치 크기 (GPU 메모리에 따라 조절)
  learning_rate: 0.0001   # 학습률
  weight_decay: 0.000001  # 가중치 감쇠
  optimizer: "adam"       # adam, adamw, sgd
  scheduler: "cosine"     # null, cosine, step
  val_every: 5            # 검증 주기
  num_workers: 4          # DataLoader 워커 수
  n_splits: 5             # K-Fold 수
  fold: 0                 # 사용할 fold (0~4)

📊 WandB 사용법

1. WandB 초기 설정

# wandb 로그인 (처음 한 번만)
wandb login

# API 키 입력 (https://wandb.ai/authorize 에서 확인)

2. Config 파일 설정

# 📊 WandB 설정
wandb:
  enabled: true                       # false로 끄면 로깅 안함
  entity: "let_cv_03"                 # 팀 entity 이름 (변경 금지!)
  project: "segmentation"             # 프로젝트 이름 (변경 금지!)
  name: "gh_fcn_resnet50_epoch50"     # ⚠️ 실험 이름 (필수 수정!)
  tags: ["baseline", "fcn"]           # 태그 (선택)
  notes: "FCN 베이스라인 실험"          # 메모 (선택)

3. 실험 이름 네이밍 규칙

형식: 이니셜_모델_추가정보

예시 설명
gh_fcn_resnet50_baseline 가현, FCN ResNet50 베이스라인
jh_deeplabv3_bce_dice 지훈, DeepLabV3 BCE+Dice Loss
sm_unet_augmentation 수민, UNet Augmentation 실험
yj_fcn_cosine_lr 영준, FCN Cosine LR 스케줄러

4. WandB 대시보드 확인

실험 실행 후 아래 주소에서 결과 확인:

5. 로깅되는 항목

항목 설명
train/step_loss 매 step loss
train/epoch_loss 에폭 평균 loss
train/learning_rate 현재 learning rate
val/loss 검증 loss
val/dice 검증 평균 Dice
val_dice/{class} 클래스별 Dice
val/predictions 🖼️ 시각화 이미지 (Input, GT, Prediction)
best_dice 최고 Dice (summary)
best_epoch 최고 성능 에폭 (summary)

5-1. 🖼️ Validation 시각화

validation마다 자동으로 예측 결과가 WandB에 이미지로 로깅됩니다!

시각화되는 내용:

  • Input: 원본 X-Ray 이미지
  • Ground Truth: 실제 정답 마스크 (색상별 클래스)
  • Prediction: 모델 예측 마스크

확인 방법:

  1. WandB 대시보드 접속
  2. 해당 run 클릭
  3. Media 탭 또는 Chartsval/predictions 확인

시각화 샘플 수 조절:

wandb:
  num_vis_samples: 4    # 0으로 설정하면 시각화 안함

6. WandB 끄기

로컬 테스트시 wandb를 끄려면:

wandb:
  enabled: false    # false로 변경

7. 자주 사용하는 WandB 기능

# 오프라인 모드로 실행 (인터넷 없을 때)
WANDB_MODE=offline python main.py --config configs/exp01.yaml --mode train

# 실행 후 나중에 sync
wandb sync ./wandb/offline-run-*

🔄 TTA (Test Time Augmentation)

TTA는 테스트/추론 시 여러 augmentation을 적용하여 예측을 앙상블하는 기법입니다. 일반적으로 0.5~2% Dice score 향상을 기대할 수 있습니다.

1. TTA 기본 사용법

# CLI에서 --tta 플래그 사용
python inference.py --config configs/exp01.yaml --tta

# 모델 직접 지정 + TTA
python inference.py --model saved_models/best_model.pt --tta --output output_tta.csv

2. Config 파일에서 TTA 설정

inference:
  threshold: 0.5
  batch_size: 2                    # TTA 사용 시 메모리 고려하여 작게
  output_csv: "output_tta.csv"
  
  # 🔄 TTA 설정
  tta:
    enabled: true                  # TTA 활성화
    horizontal_flip: true          # 수평 뒤집기 (권장)
    vertical_flip: false           # 수직 뒤집기
    rotate90: false                # 90도 단위 회전
    merge_mode: "mean"             # "mean" 또는 "max"

3. TTA 변환 옵션 설명

옵션 설명 효과 시간 증가
horizontal_flip 좌우 반전 ⭐⭐⭐ 가장 효과적 x2
vertical_flip 상하 반전 ⭐⭐ x2
rotate90 90/180/270도 회전 ⭐ X-ray에는 비추천 x4

4. TTA 조합별 추론 시간

조합 Transform 수 추론 시간 권장도
HFlip만 2 (원본 + HFlip) x2 ⭐⭐⭐ 기본 권장
HFlip + VFlip 4 (원본 + HFlip + VFlip + HVFlip) x4 ⭐⭐
모든 옵션 8 x8 ⭐ 과도할 수 있음

5. X-ray 이미지 권장 TTA 설정

X-ray 손 이미지 특성을 고려한 권장 설정:

tta:
  enabled: true
  horizontal_flip: true      # ✅ 좌/우 손 대칭, 매우 효과적
  vertical_flip: false       # ❌ 손은 특정 방향이라 효과 제한적
  rotate90: false            # ❌ X-ray 특성상 비추천
  merge_mode: "mean"         # mean이 max보다 안정적

6. 앙상블 방법 (merge_mode)

방법 설명 특징
mean 모든 예측의 평균 안정적, 노이즈 감소
max 모든 예측 중 최대값 민감도 높음, FP 증가 가능

7. TTA 사용 시 주의사항

⚠️ 메모리: TTA는 메모리를 더 사용합니다. batch_size를 줄이세요.

⚠️ 시간: Transform 수만큼 추론 시간이 증가합니다.

⚠️ 효과: 모든 transform이 항상 좋은 건 아닙니다. 검증 후 사용하세요.

# 메모리 부족 시
inference:
  batch_size: 1              # 배치 크기 줄이기
  tta:
    enabled: true
    horizontal_flip: true    # 필요한 것만 사용

🎯 앙상블 (Ensemble)

여러 모델의 예측 결과를 결합하여 성능을 향상시키는 방법입니다. 일반적으로 1~3% Dice score 향상을 기대할 수 있습니다.

1. 빠른 시작

# CSV 파일 앙상블 (가장 간단)
python ensemble.py --csvs output1.csv output2.csv output3.csv \
                   --output ensemble.csv

# 가중치 기반 앙상블 (성능 좋은 모델에 높은 가중치)
python ensemble.py --csvs output1.csv output2.csv output3.csv \
                   --weights 0.5 0.3 0.2 \
                   --method weighted_average \
                   --output ensemble_weighted.csv

# Config 파일 사용 (권장)
python ensemble.py --config configs/ensemble/ensemble_csv_simple.yaml

2. 지원하는 앙상블 방법

방법 설명
simple_average 모든 모델의 확률값 평균
weighted_average 성능 기반 가중치 평균
max_voting 각 픽셀에서 최대 확률값 선택
hard_voting 이진화 후 다수결
rank_average 순위 기반 평균
geometric_mean 기하평균

3. 실전 워크플로우

# Step 1: 여러 모델 학습
python main.py --config configs/exp01_unetpp_efficientb4.yaml
python main.py --config configs/exp02_unetpp_mobilenet.yaml
python main.py --config configs/exp03_deeplabv3_resnet50.yaml

# Step 2: 각 모델로 추론
python inference.py --config configs/exp01_unetpp_efficientb4.yaml
python inference.py --config configs/exp02_unetpp_mobilenet.yaml
python inference.py --config configs/exp03_deeplabv3_resnet50.yaml

# Step 3: 앙상블
python ensemble.py --csvs exp01_output.csv exp02_output.csv exp03_output.csv \
                   --method simple_average \
                   --output final_ensemble.csv

4. Config 파일 예시

# configs/ensemble/my_ensemble.yaml

ensemble:
  method: "weighted_average"
  
  csv_files:
    - "exp01_output.csv"  # dice: 0.95
    - "exp02_output.csv"  # dice: 0.93
    - "exp03_output.csv"  # dice: 0.91
  
  # Validation Dice Score 기반 가중치
  weights: [0.5, 0.3, 0.2]
  
  output_csv: "ensemble_output.csv"
  threshold: 0.5

5. 앙상블 팁

다양성 확보: 서로 다른 아키텍처, 백본, 이미지 크기 사용
가중치 설정: Validation Dice Score 기반으로 가중치 부여
적절한 개수: 3~5개 모델이 일반적으로 충분
방법 선택: Simple Average로 시작, 성능 차이 크면 Weighted Average

📚 상세 가이드

더 자세한 내용은 앙상블 가이드를 참고하세요.


🤝 협업 규칙

1. Git 브랜치 전략

# 새로운 실험은 본인 브랜치에서 진행
git checkout -b exp/홍길동/loss_experiment

# 작업 완료 후 main에 merge
git checkout main
git merge exp/홍길동/loss_experiment

2. 커밋 메시지 규칙

# 형식: [타입] 내용

# 예시
git commit -m "[exp] exp04 Loss 실험 추가"
git commit -m "[fix] dataset 경로 버그 수정"
git commit -m "[feat] Cosine scheduler 추가"
git commit -m "[docs] README 사용법 업데이트"

3. 실험 설정 파일 네이밍

exp[번호]_[실험내용].yaml

# 예시
exp01_fcn_resnet50.yaml      # 모델 실험
exp02_loss_bce_dice.yaml     # Loss 실험
exp03_augmentation.yaml       # Augmentation 실험
exp04_scheduler_cosine.yaml   # 스케줄러 실험

4. 결과 공유

실험 후 아래 정보를 팀과 공유합니다:

항목 내용
실험 번호 exp04
실험자 홍길동
변경 사항 DeepLabV3 + Dice Loss
Best Dice 0.9523
학습 시간 2시간
특이사항 epoch 30에서 수렴

🏆 대회 제출용 CSV 생성

1. 학습 완료 후 CSV 생성

# Config 파일 사용 (권장)
python inference.py --config configs/exp01_fcn_resnet50.yaml

# 또는 직접 모델 경로 지정
python inference.py --model saved_models/exp01/best_model.pt \
                    --output submission.csv

2. inference.py 옵션 설명

옵션 설명 기본값
--config Config yaml 파일 경로 -
--model 학습된 모델 파일 (.pt) -
--model_name 모델 이름 fcn_resnet50
--test_root 테스트 이미지 경로 data/test/DCM
--output 출력 CSV 파일명 output.csv
--image_size 입력 이미지 크기 512
--threshold 이진화 임계값 0.5
--batch_size 배치 크기 2
--tta 🔄 TTA 사용 (성능 향상) false

3. 출력 CSV 형식

image_name,class,rle
image001.png,finger-1,1 5 10 3 ...
image001.png,finger-2,20 8 35 12 ...
...

4. 제출 체크리스트

  • 테스트 데이터 경로가 올바른가? (data/test/DCM)
  • 학습된 모델 파일(.pt)이 존재하는가?
  • 모델 이름(--model_name)이 학습 때와 동일한가?
  • CSV 파일이 정상적으로 생성되었는가?
  • CSV 파일 크기가 적절한가? (빈 파일 아닌지)
  • 🔄 TTA 사용 여부를 고려했는가? (--tta 플래그)

🔧 트러블슈팅

CUDA Out of Memory

# 배치 사이즈 줄이기
training:
  batch_size: 4  # 8 → 4

# 또는 이미지 크기 줄이기
image:
  size: 256  # 512 → 256

학습이 너무 느림

# num_workers 늘리기
training:
  num_workers: 8  # 4 → 8

# 또는 가벼운 모델 사용
model:
  name: "deeplabv3_mobilenet"

Dice Score가 오르지 않음

# 1. Loss 변경
loss:
  name: "bce_dice"

# 2. Learning rate 조절
training:
  learning_rate: 0.00001  # 줄이기

# 3. Augmentation 추가
augmentation:
  train:
    rotate: true
    brightness_contrast: true

데이터 경로 에러

# config 파일의 경로 확인
data:
  train_image_root: "../Segmentation/train/DCM"
  # 실제 경로가 맞는지 확인!

# 상대 경로 대신 절대 경로 사용
data:
  train_image_root: "/home/user/data/Segmentation/train/DCM"

✅ 실험 체크리스트

새로운 실험 전 확인사항:

  • 새 config 파일 생성했는가?
  • 실험 이름(experiment.name)을 고유하게 설정했는가?
  • 저장 폴더(save.dir)를 실험별로 다르게 설정했는가?
  • 출력 CSV(inference.output_csv)를 실험별로 다르게 설정했는가?
  • 실험자 이름(experiment.author)을 입력했는가?
  • 데이터 경로가 올바른가?
  • WandB 설정: wandb.name을 본인 이니셜 + 실험 정보로 설정했는가?
  • WandB 설정: wandb.tags에 실험 키워드를 추가했는가?

📊 29개 클래스 목록

번호 클래스명 설명
0-18 finger-1 ~ finger-19 손가락 뼈
19 Trapezium 대능형골
20 Trapezoid 소능형골
21 Capitate 유두골
22 Hamate 유구골
23 Scaphoid 주상골
24 Lunate 월상골
25 Triquetrum 삼각골
26 Pisiform 두상골
27 Radius 요골
28 Ulna 척골

👥 팀원

이름 역할 담당 실험
박상범 멋쟁이 EDA, data preprocessing, loss, augmentation
안진경 멋쟁이 model, augmentation, feature research
이가현 멋쟁이 setting, model, fine-tuning
이혜준 멋쟁이 EDA, data preprocessing, loss, feature research
황은배 멋쟁이 model, augmentation, feature research

📚 참고 자료


Happy Experimenting! 🚀

About

Hand Bone Segmentation Competition

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages