6.3 KiB
6.3 KiB
Implementation Plan — Potter et al. Data Leakage Reproduction
Manuscript pipeline (from docx)
- Feature extraction — 5 CNNs (VGG16, DenseNet121, EfficientNetB1, MobileNetV2, ResNet50), frozen, include_top=False
- PCA + t-SNE — visualize feature space (Figure 5 / S2)
- Patient clustering — K-means on 64×64 grayscale thumbnails, per-class (15/40/55)
- Random Forest — feature importance ranking (2000 trees → we use 500, equivalent)
- SVM with GridSearchCV — grid over γ per nfeatures, C=10 fixed, 5-fold CV
- Image-level vs patient-level — compare test accuracy with both split types
- 20-seed repetition — boxplots showing distribution (Figure 6 / S4)
Current status
✅ Implemented & Working
| Component | Location | Notes |
|---|---|---|
| Feature extraction (5 models, PyTorch) | classes/features.py |
ResNet50 GAP stripped (100K-d). EfficientNetB1 dim error documented |
| Patient clustering (K-means) | classes/patient_identifier.py |
Thumbnail + feature-based modes |
| Classification pipeline | classes/classifier.py |
PatientLeakageClassifier.run() — RF→GridSearchCV→SVM |
| t-SNE visualization | scripts/visualizations/simple_patient_tsne.py |
Per-class patient coloring |
| Figure 6 (20-seed boxplots) | scripts/visualizations/figure6.py |
Image vs patient distributions |
| Figure S4 (CV accuracy curves) | scripts/visualizations/figure_s4.py |
Per-model, log₁₀ x-scale, patient-level |
| C×γ grid search | archived | Confirmed C=10 is adequate |
| SVM class-weight analysis | archived | Confirmed no benefit |
| Task06 NIfTI dataset loader | classes/nifti_dataset.py |
HU windowing, orientation control |
| Clustering validation (Task06) | scripts/validate_clustering_task06.py |
Thumbnail + feature K-means vs ground truth |
| Clustering comparison (IQ-OTH) | scripts/analysis/compare_clustering_methods.py |
Thumbnail vs feature vs v8 reference |
| Siamese patient matching | classes/siamese.py |
SiamesePatientMatcher class |
| Siamese training | scripts/train_siamese.py |
Task06 train/test split, hard negatives |
🚧 In Progress
| Component | Status |
|---|---|
| Siamese-based patient manifest for IQ-OTH | scripts/siamese_identify.py written, needs trained model |
❌ Still Needed
| Manuscript Figure/Table | What we need | Priority |
|---|---|---|
| Figure 5 (PCA + t-SNE) | Per-model t-SNE plots, matching manuscript style | Medium |
| Figure S1 (image-level CV curves) | 5 panels, image-level split, log₁₀ x-scale. Nearly identical to S4 but with image split | Low |
| Figure S2 (PCA/t-SNE per model) | Like Figure 5 but for all 5 models | Medium |
| Figure S3 (example cluster images) | 5 example slices from a single K-means cluster per class | Low |
| Figure S5 (confusion matrix) | VGG16 patient-level confusion matrix | Low |
| Table 2 comparison | Run classification with thumbnail K-means manifest to match manuscript numbers | High |
| Siamese results integration | Once trained: run siamese_identify, compare manifest against K-means manifests | High |
| Final patient manifest | Choose best method, produce canonical patient assignments | High |
Proposed final structure
patient_leakage_detector/
├── classes/
│ ├── features.py # FeatureExtractor (5 CNNs)
│ ├── patient_identifier.py # PatientIdentifier (K-means clustering)
│ ├── classifier.py # PatientLeakageClassifier (RF→SVM pipeline)
│ ├── nifti_dataset.py # NiftiSliceDataset (Task06 loader)
│ └── siamese.py # SiamesePatientMatcher (learned matching)
│
├── scripts/
│ ├── classification.py # Core: single-seed classification
│ ├── train_siamese.py # Core: siamese training on Task06
│ ├── siamese_identify.py # Core: IQ-OTH patient manifest via siamese
│ ├── validate_clustering_task06.py # Core: Task06 validation
│ │
│ ├── visualizations/
│ │ ├── figure5.py # [TODO] PCA + t-SNE plots
│ │ ├── figure6.py # ✅ 20-seed boxplots
│ │ ├── figure_s1.py # [TODO] Image-level CV curves
│ │ ├── figure_s2.py # [TODO] PCA/t-SNE per model
│ │ ├── figure_s3.py # [TODO] Example cluster images
│ │ ├── figure_s4.py # ✅ Patient-level CV curves
│ │ ├── figure_s5.py # [TODO] Confusion matrix
│ │ └── simple_patient_tsne.py # ✅ t-SNE with patient coloring
│ │
│ └── analysis/
│ ├── compare_clustering_methods.py # ✅ Thumbnail vs feature vs v8
│ └── verify_feature_dims.py # ✅ TF dimension verification
│
├── features/
│ ├── VGG16_features.npz # Extracted features (all 5 models)
│ └── task06_lung/ # Cached Task06 features
│
├── models/
│ └── siamese_resnet18.pt # Trained siamese model
│
├── results/
│ ├── simple_patient_manifest.csv # Feature-based K-means manifest
│ ├── siamese_manifest.csv # [TODO] Siamese-based manifest
│ ├── classification_results.json # Single-seed results (all 5 models)
│ ├── figure6_data.json # 20-seed data
│ ├── task06_clustering_validation.json # Task06 validation results
│ └── ...
│
├── plots/
│ ├── figure6.png
│ ├── figure_s4.png
│ └── ...
│
├── plan.md # This file
├── notes.md # Review notes for supervisor
├── .gitignore
└── .archive/ # Superseded scripts and results
Immediate next steps
- Finish siamese training → run
python scripts/siamese_identify.py→ producesiamese_manifest.csv - Run classification with thumbnail K-means manifest to reproduce manuscript Table 2 numbers
- Compare manifests: K-means thumbnail vs K-means feature vs siamese — which gives the best patient-level split?
- Choose canonical manifest and produce final classification results
- Generate remaining figures (Figure 5, S1, S2, S3, S5)
- Draft findings for supervisor discussion