Spaces:
Sleeping
Sleeping
Hou commited on
Commit ·
ebbe758
1
Parent(s): 4b9b326
add src
Browse files- .gitignore +1 -0
- app.py +465 -0
- augmentations.py +85 -0
- dataloader.py +356 -0
- model.py +61 -0
- requirements.txt +13 -0
- runs/eyepacs_dr/inception_v3_fold0/best_model_only.pt +3 -0
- runs/eyepacs_dr/inception_v3_fold0/history.json +287 -0
- runs/eyepacs_dr/inception_v3_fold1/best_model_only.pt +3 -0
- runs/eyepacs_dr/inception_v3_fold1/history.json +287 -0
- runs/eyepacs_dr/inception_v3_fold2/best_model_only.pt +3 -0
- runs/eyepacs_dr/inception_v3_fold2/history.json +257 -0
- runs/eyepacs_dr/inception_v3_fold3/best_model_only.pt +3 -0
- runs/eyepacs_dr/inception_v3_fold3/history.json +257 -0
- runs/eyepacs_dr/inception_v3_fold4/best_model_only.pt +3 -0
- runs/eyepacs_dr/inception_v3_fold4/history.json +287 -0
- train.py +480 -0
.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
.idea
|
app.py
ADDED
|
@@ -0,0 +1,465 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# app.py
|
| 2 |
+
|
| 3 |
+
import argparse
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
import gradio as gr
|
| 7 |
+
import numpy as np
|
| 8 |
+
import pandas as pd
|
| 9 |
+
from PIL import Image
|
| 10 |
+
|
| 11 |
+
import torch
|
| 12 |
+
import torch.nn.functional as F
|
| 13 |
+
|
| 14 |
+
from augmentations import get_val_transforms
|
| 15 |
+
from model import DeepSeeNet
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
ID_TO_LABEL = {
|
| 19 |
+
0: "No DR",
|
| 20 |
+
1: "Mild NPDR",
|
| 21 |
+
2: "Moderate NPDR",
|
| 22 |
+
3: "Severe NPDR",
|
| 23 |
+
4: "PDR",
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
BUCKET_MODE_DESCRIPTIONS = {
|
| 28 |
+
"severity": "5-class DR severity",
|
| 29 |
+
"referral": "Non-referable vs referable DR",
|
| 30 |
+
"any_dr": "No DR vs any DR",
|
| 31 |
+
"stage": "No DR vs NPDR vs PDR",
|
| 32 |
+
"high_risk": "Non-severe vs severe/PDR",
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
class AlbumentationsTransform:
|
| 37 |
+
def __init__(self, transform):
|
| 38 |
+
self.transform = transform
|
| 39 |
+
|
| 40 |
+
def __call__(self, image):
|
| 41 |
+
return self.transform(image=np.asarray(image))["image"]
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def unwrap_logits(output):
|
| 45 |
+
if isinstance(output, (tuple, list)):
|
| 46 |
+
return output[0]
|
| 47 |
+
return output
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def find_fold_checkpoints(checkpoint_dir, checkpoint_name="best_model_only.pt"):
|
| 51 |
+
checkpoint_dir = Path(checkpoint_dir)
|
| 52 |
+
|
| 53 |
+
if not checkpoint_dir.exists():
|
| 54 |
+
raise FileNotFoundError(f"Checkpoint directory not found: {checkpoint_dir}")
|
| 55 |
+
|
| 56 |
+
paths = sorted(checkpoint_dir.glob(f"*_fold*/{checkpoint_name}"))
|
| 57 |
+
|
| 58 |
+
if len(paths) == 0:
|
| 59 |
+
# fallback: allow directly passing a folder containing checkpoints
|
| 60 |
+
paths = sorted(checkpoint_dir.glob(f"**/{checkpoint_name}"))
|
| 61 |
+
|
| 62 |
+
if len(paths) == 0:
|
| 63 |
+
raise FileNotFoundError(
|
| 64 |
+
f"No fold checkpoints named '{checkpoint_name}' found under {checkpoint_dir}"
|
| 65 |
+
)
|
| 66 |
+
|
| 67 |
+
return paths
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
def load_single_model(checkpoint_path, backbone, image_size, device):
|
| 71 |
+
checkpoint_path = Path(checkpoint_path)
|
| 72 |
+
ckpt = torch.load(checkpoint_path, map_location=device)
|
| 73 |
+
|
| 74 |
+
saved_args = ckpt.get("args", {})
|
| 75 |
+
backbone = saved_args.get("backbone", backbone)
|
| 76 |
+
image_size = int(saved_args.get("image_size", image_size))
|
| 77 |
+
|
| 78 |
+
model = DeepSeeNet(
|
| 79 |
+
n_classes=5,
|
| 80 |
+
backbone=backbone,
|
| 81 |
+
pretrained=False,
|
| 82 |
+
freeze_backbone=False,
|
| 83 |
+
)
|
| 84 |
+
|
| 85 |
+
model.load_state_dict(ckpt["model"], strict=True)
|
| 86 |
+
model.to(device)
|
| 87 |
+
model.eval()
|
| 88 |
+
|
| 89 |
+
return model, backbone, image_size, ckpt
|
| 90 |
+
|
| 91 |
+
|
| 92 |
+
def load_ensemble(checkpoint_dir, checkpoint_name, backbone, image_size, device):
|
| 93 |
+
checkpoint_paths = find_fold_checkpoints(
|
| 94 |
+
checkpoint_dir=checkpoint_dir,
|
| 95 |
+
checkpoint_name=checkpoint_name,
|
| 96 |
+
)
|
| 97 |
+
|
| 98 |
+
models = []
|
| 99 |
+
ckpts = []
|
| 100 |
+
resolved_backbone = backbone
|
| 101 |
+
resolved_image_size = image_size
|
| 102 |
+
|
| 103 |
+
for path in checkpoint_paths:
|
| 104 |
+
model, resolved_backbone, resolved_image_size, ckpt = load_single_model(
|
| 105 |
+
checkpoint_path=path,
|
| 106 |
+
backbone=resolved_backbone,
|
| 107 |
+
image_size=resolved_image_size,
|
| 108 |
+
device=device,
|
| 109 |
+
)
|
| 110 |
+
|
| 111 |
+
models.append(model)
|
| 112 |
+
ckpts.append(ckpt)
|
| 113 |
+
|
| 114 |
+
transform = AlbumentationsTransform(get_val_transforms(resolved_image_size))
|
| 115 |
+
|
| 116 |
+
return models, transform, resolved_backbone, resolved_image_size, checkpoint_paths, ckpts
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
def get_grouped_probs(probs, mode):
|
| 120 |
+
p0, p1, p2, p3, p4 = probs
|
| 121 |
+
|
| 122 |
+
if mode == "severity":
|
| 123 |
+
return {
|
| 124 |
+
"No DR": float(p0),
|
| 125 |
+
"Mild NPDR": float(p1),
|
| 126 |
+
"Moderate NPDR": float(p2),
|
| 127 |
+
"Severe NPDR": float(p3),
|
| 128 |
+
"PDR": float(p4),
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
if mode == "referral":
|
| 132 |
+
return {
|
| 133 |
+
"Non-referable DR": float(p0 + p1),
|
| 134 |
+
"Referable DR": float(p2 + p3 + p4),
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
if mode == "any_dr":
|
| 138 |
+
return {
|
| 139 |
+
"No DR": float(p0),
|
| 140 |
+
"Any DR": float(p1 + p2 + p3 + p4),
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
if mode == "stage":
|
| 144 |
+
return {
|
| 145 |
+
"No DR": float(p0),
|
| 146 |
+
"NPDR": float(p1 + p2 + p3),
|
| 147 |
+
"PDR": float(p4),
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
if mode == "high_risk":
|
| 151 |
+
return {
|
| 152 |
+
"Non-severe / non-PDR": float(p0 + p1 + p2),
|
| 153 |
+
"Severe NPDR or PDR": float(p3 + p4),
|
| 154 |
+
}
|
| 155 |
+
|
| 156 |
+
raise ValueError(f"Unknown bucket mode: {mode}")
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
def grouped_probs_to_fixed_dataframe(prob_dict, max_rows=5):
|
| 160 |
+
rows = [
|
| 161 |
+
{
|
| 162 |
+
"label": label,
|
| 163 |
+
"probability": f"{prob:.4f}",
|
| 164 |
+
}
|
| 165 |
+
for label, prob in prob_dict.items()
|
| 166 |
+
]
|
| 167 |
+
|
| 168 |
+
rows = sorted(rows, key=lambda x: float(x["probability"]), reverse=True)
|
| 169 |
+
|
| 170 |
+
while len(rows) < max_rows:
|
| 171 |
+
rows.append({"label": "", "probability": ""})
|
| 172 |
+
|
| 173 |
+
return pd.DataFrame(rows[:max_rows], columns=["label", "probability"])
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
def fold_probs_to_dataframe(fold_probs, checkpoint_paths):
|
| 177 |
+
rows = []
|
| 178 |
+
|
| 179 |
+
for i, probs in enumerate(fold_probs):
|
| 180 |
+
pred_grade = int(np.argmax(probs))
|
| 181 |
+
pred_label = ID_TO_LABEL[pred_grade]
|
| 182 |
+
|
| 183 |
+
rows.append(
|
| 184 |
+
{
|
| 185 |
+
"fold": Path(checkpoint_paths[i]).parent.name,
|
| 186 |
+
"prediction": pred_label,
|
| 187 |
+
"probability": f"{float(probs[pred_grade]):.4f}",
|
| 188 |
+
"p0_no_dr": f"{float(probs[0]):.4f}",
|
| 189 |
+
"p1_mild": f"{float(probs[1]):.4f}",
|
| 190 |
+
"p2_moderate": f"{float(probs[2]):.4f}",
|
| 191 |
+
"p3_severe": f"{float(probs[3]):.4f}",
|
| 192 |
+
"p4_pdr": f"{float(probs[4]):.4f}",
|
| 193 |
+
}
|
| 194 |
+
)
|
| 195 |
+
|
| 196 |
+
return pd.DataFrame(rows)
|
| 197 |
+
|
| 198 |
+
|
| 199 |
+
def ensemble_predict(models, x):
|
| 200 |
+
fold_probs = []
|
| 201 |
+
|
| 202 |
+
with torch.no_grad():
|
| 203 |
+
for model in models:
|
| 204 |
+
logits = unwrap_logits(model(x))
|
| 205 |
+
probs = F.softmax(logits, dim=1)[0].detach().cpu().numpy()
|
| 206 |
+
fold_probs.append(probs)
|
| 207 |
+
|
| 208 |
+
fold_probs = np.stack(fold_probs, axis=0)
|
| 209 |
+
ensemble_probs = fold_probs.mean(axis=0)
|
| 210 |
+
|
| 211 |
+
return ensemble_probs, fold_probs
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
def make_prediction_fn(models, transform, checkpoint_paths, device):
|
| 215 |
+
def predict(image, bucket_mode):
|
| 216 |
+
empty_df = pd.DataFrame(
|
| 217 |
+
[{"label": "", "probability": ""} for _ in range(5)],
|
| 218 |
+
columns=["label", "probability"],
|
| 219 |
+
)
|
| 220 |
+
|
| 221 |
+
empty_fold_df = pd.DataFrame(
|
| 222 |
+
columns=[
|
| 223 |
+
"fold",
|
| 224 |
+
"prediction",
|
| 225 |
+
"probability",
|
| 226 |
+
"p0_no_dr",
|
| 227 |
+
"p1_mild",
|
| 228 |
+
"p2_moderate",
|
| 229 |
+
"p3_severe",
|
| 230 |
+
"p4_pdr",
|
| 231 |
+
]
|
| 232 |
+
)
|
| 233 |
+
|
| 234 |
+
if image is None:
|
| 235 |
+
return (
|
| 236 |
+
None,
|
| 237 |
+
empty_df,
|
| 238 |
+
empty_fold_df,
|
| 239 |
+
"Upload a fundus image to run ensemble inference.",
|
| 240 |
+
)
|
| 241 |
+
|
| 242 |
+
if not isinstance(image, Image.Image):
|
| 243 |
+
image = Image.fromarray(image)
|
| 244 |
+
|
| 245 |
+
image = image.convert("RGB")
|
| 246 |
+
x = transform(image).unsqueeze(0).to(device)
|
| 247 |
+
|
| 248 |
+
probs, fold_probs = ensemble_predict(models, x)
|
| 249 |
+
|
| 250 |
+
pred_grade = int(np.argmax(probs))
|
| 251 |
+
pred_label = ID_TO_LABEL[pred_grade]
|
| 252 |
+
pred_prob = float(probs[pred_grade])
|
| 253 |
+
|
| 254 |
+
raw_probs = {
|
| 255 |
+
ID_TO_LABEL[i]: float(probs[i])
|
| 256 |
+
for i in range(5)
|
| 257 |
+
}
|
| 258 |
+
|
| 259 |
+
grouped_probs = get_grouped_probs(probs, bucket_mode)
|
| 260 |
+
bucket_label = max(grouped_probs, key=grouped_probs.get)
|
| 261 |
+
bucket_prob = grouped_probs[bucket_label]
|
| 262 |
+
bucket_df = grouped_probs_to_fixed_dataframe(grouped_probs, max_rows=5)
|
| 263 |
+
|
| 264 |
+
fold_df = fold_probs_to_dataframe(fold_probs, checkpoint_paths)
|
| 265 |
+
|
| 266 |
+
fold_preds = [ID_TO_LABEL[int(np.argmax(p))] for p in fold_probs]
|
| 267 |
+
agreement = fold_preds.count(pred_label) / len(fold_preds)
|
| 268 |
+
|
| 269 |
+
summary = (
|
| 270 |
+
f"Ensemble prediction: {pred_label} "
|
| 271 |
+
f"(grade {pred_grade}, probability {pred_prob:.3f})\n\n"
|
| 272 |
+
f"Probability grouping: {BUCKET_MODE_DESCRIPTIONS[bucket_mode]}\n"
|
| 273 |
+
f"Grouped result: {bucket_label} "
|
| 274 |
+
f"(probability {bucket_prob:.3f})\n\n"
|
| 275 |
+
f"Fold agreement with ensemble class: {agreement:.1%} "
|
| 276 |
+
f"({fold_preds.count(pred_label)}/{len(fold_preds)} folds)"
|
| 277 |
+
)
|
| 278 |
+
|
| 279 |
+
return raw_probs, bucket_df, fold_df, summary
|
| 280 |
+
|
| 281 |
+
return predict
|
| 282 |
+
|
| 283 |
+
|
| 284 |
+
def make_app(checkpoint_dir, checkpoint_name, backbone, image_size, device):
|
| 285 |
+
(
|
| 286 |
+
models,
|
| 287 |
+
transform,
|
| 288 |
+
backbone,
|
| 289 |
+
image_size,
|
| 290 |
+
checkpoint_paths,
|
| 291 |
+
ckpts,
|
| 292 |
+
) = load_ensemble(
|
| 293 |
+
checkpoint_dir=checkpoint_dir,
|
| 294 |
+
checkpoint_name=checkpoint_name,
|
| 295 |
+
backbone=backbone,
|
| 296 |
+
image_size=image_size,
|
| 297 |
+
device=device,
|
| 298 |
+
)
|
| 299 |
+
|
| 300 |
+
predict_fn = make_prediction_fn(
|
| 301 |
+
models=models,
|
| 302 |
+
transform=transform,
|
| 303 |
+
checkpoint_paths=checkpoint_paths,
|
| 304 |
+
device=device,
|
| 305 |
+
)
|
| 306 |
+
|
| 307 |
+
fold_names = [p.parent.name for p in checkpoint_paths]
|
| 308 |
+
|
| 309 |
+
best_metrics = [
|
| 310 |
+
ckpt.get("best_metric", None)
|
| 311 |
+
for ckpt in ckpts
|
| 312 |
+
]
|
| 313 |
+
|
| 314 |
+
model_info = (
|
| 315 |
+
f"Backbone: `{backbone}` | "
|
| 316 |
+
f"Input: `{image_size}×{image_size}` | "
|
| 317 |
+
f"Folds loaded: `{len(models)}` | "
|
| 318 |
+
f"Device: `{device}`"
|
| 319 |
+
)
|
| 320 |
+
|
| 321 |
+
# fold_info = "Loaded checkpoints: " + ", ".join(fold_names)
|
| 322 |
+
#
|
| 323 |
+
# if any(m is not None for m in best_metrics):
|
| 324 |
+
# metric_info = "Best metrics: " + ", ".join(
|
| 325 |
+
# "NA" if m is None else f"{float(m):.4f}"
|
| 326 |
+
# for m in best_metrics
|
| 327 |
+
# )
|
| 328 |
+
# else:
|
| 329 |
+
# metric_info = ""
|
| 330 |
+
|
| 331 |
+
with gr.Blocks(title="EyePACS DR Ensemble Classifier") as demo:
|
| 332 |
+
gr.Markdown("# EyePACS DR Ensemble Classifier")
|
| 333 |
+
gr.Markdown(model_info)
|
| 334 |
+
# gr.Markdown(fold_info)
|
| 335 |
+
# if metric_info:
|
| 336 |
+
# gr.Markdown(metric_info)
|
| 337 |
+
|
| 338 |
+
with gr.Row():
|
| 339 |
+
with gr.Column(scale=1):
|
| 340 |
+
image = gr.Image(
|
| 341 |
+
type="pil",
|
| 342 |
+
label="Fundus image",
|
| 343 |
+
)
|
| 344 |
+
|
| 345 |
+
bucket_mode = gr.Dropdown(
|
| 346 |
+
choices=[
|
| 347 |
+
"severity",
|
| 348 |
+
"referral",
|
| 349 |
+
"any_dr",
|
| 350 |
+
"stage",
|
| 351 |
+
"high_risk",
|
| 352 |
+
],
|
| 353 |
+
value="referral",
|
| 354 |
+
label="Probability grouping",
|
| 355 |
+
)
|
| 356 |
+
|
| 357 |
+
run_btn = gr.Button("Run inference", variant="primary")
|
| 358 |
+
|
| 359 |
+
with gr.Column(scale=1):
|
| 360 |
+
raw_probs = gr.Label(
|
| 361 |
+
num_top_classes=5,
|
| 362 |
+
label="Ensemble raw 5-class probabilities",
|
| 363 |
+
)
|
| 364 |
+
|
| 365 |
+
bucket_table = gr.Dataframe(
|
| 366 |
+
label="Grouped probabilities",
|
| 367 |
+
headers=["label", "probability"],
|
| 368 |
+
row_count=(5, "fixed"),
|
| 369 |
+
col_count=(2, "fixed"),
|
| 370 |
+
interactive=False,
|
| 371 |
+
wrap=True,
|
| 372 |
+
)
|
| 373 |
+
|
| 374 |
+
with gr.Accordion("Per-fold predictions", open=False):
|
| 375 |
+
fold_table = gr.Dataframe(
|
| 376 |
+
label="Per-fold probabilities",
|
| 377 |
+
interactive=False,
|
| 378 |
+
wrap=True,
|
| 379 |
+
)
|
| 380 |
+
|
| 381 |
+
summary = gr.Textbox(
|
| 382 |
+
label="Summary",
|
| 383 |
+
lines=7,
|
| 384 |
+
interactive=False,
|
| 385 |
+
)
|
| 386 |
+
|
| 387 |
+
inputs = [image, bucket_mode]
|
| 388 |
+
outputs = [raw_probs, bucket_table, fold_table, summary]
|
| 389 |
+
|
| 390 |
+
run_btn.click(
|
| 391 |
+
fn=predict_fn,
|
| 392 |
+
inputs=inputs,
|
| 393 |
+
outputs=outputs,
|
| 394 |
+
)
|
| 395 |
+
|
| 396 |
+
image.change(
|
| 397 |
+
fn=predict_fn,
|
| 398 |
+
inputs=inputs,
|
| 399 |
+
outputs=outputs,
|
| 400 |
+
)
|
| 401 |
+
|
| 402 |
+
bucket_mode.change(
|
| 403 |
+
fn=predict_fn,
|
| 404 |
+
inputs=inputs,
|
| 405 |
+
outputs=outputs,
|
| 406 |
+
)
|
| 407 |
+
|
| 408 |
+
return demo
|
| 409 |
+
|
| 410 |
+
|
| 411 |
+
def parse_args():
|
| 412 |
+
parser = argparse.ArgumentParser(
|
| 413 |
+
description="EyePACS DR Gradio ensemble inference app."
|
| 414 |
+
)
|
| 415 |
+
|
| 416 |
+
parser.add_argument(
|
| 417 |
+
"--checkpoint-dir",
|
| 418 |
+
default="runs/eyepacs_dr",
|
| 419 |
+
help="Folder containing fold checkpoint folders.",
|
| 420 |
+
)
|
| 421 |
+
parser.add_argument(
|
| 422 |
+
"--checkpoint-name",
|
| 423 |
+
default="best_model_only.pt",
|
| 424 |
+
help="Checkpoint filename inside each fold folder.",
|
| 425 |
+
)
|
| 426 |
+
parser.add_argument(
|
| 427 |
+
"--backbone",
|
| 428 |
+
default="inception_v3",
|
| 429 |
+
help="Fallback backbone if checkpoint args are unavailable.",
|
| 430 |
+
)
|
| 431 |
+
parser.add_argument(
|
| 432 |
+
"--image-size",
|
| 433 |
+
type=int,
|
| 434 |
+
default=1024,
|
| 435 |
+
help="Fallback image size if checkpoint args are unavailable.",
|
| 436 |
+
)
|
| 437 |
+
parser.add_argument("--host", default="0.0.0.0")
|
| 438 |
+
parser.add_argument("--port", type=int, default=7860)
|
| 439 |
+
parser.add_argument("--share", action="store_true")
|
| 440 |
+
|
| 441 |
+
return parser.parse_args()
|
| 442 |
+
|
| 443 |
+
|
| 444 |
+
def main():
|
| 445 |
+
args = parse_args()
|
| 446 |
+
|
| 447 |
+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 448 |
+
|
| 449 |
+
demo = make_app(
|
| 450 |
+
checkpoint_dir=args.checkpoint_dir,
|
| 451 |
+
checkpoint_name=args.checkpoint_name,
|
| 452 |
+
backbone=args.backbone,
|
| 453 |
+
image_size=args.image_size,
|
| 454 |
+
device=device,
|
| 455 |
+
)
|
| 456 |
+
|
| 457 |
+
demo.launch(
|
| 458 |
+
# server_name=args.host,
|
| 459 |
+
# server_port=args.port,
|
| 460 |
+
# share=args.share,
|
| 461 |
+
)
|
| 462 |
+
|
| 463 |
+
|
| 464 |
+
if __name__ == "__main__":
|
| 465 |
+
main()
|
augmentations.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
augmentations.py
|
| 3 |
+
|
| 4 |
+
Simple camera-style augmentations for color fundus photography (CFP)
|
| 5 |
+
classification.
|
| 6 |
+
|
| 7 |
+
Expected input:
|
| 8 |
+
RGB NumPy image, shape (H, W, 3)
|
| 9 |
+
|
| 10 |
+
Dependencies:
|
| 11 |
+
pip install albumentations opencv-python
|
| 12 |
+
"""
|
| 13 |
+
|
| 14 |
+
import cv2
|
| 15 |
+
import albumentations as A
|
| 16 |
+
from albumentations.pytorch import ToTensorV2
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
IMAGENET_MEAN = (0.485, 0.456, 0.406)
|
| 20 |
+
IMAGENET_STD = (0.229, 0.224, 0.225)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def get_train_transforms(
|
| 24 |
+
image_size=1024,
|
| 25 |
+
mean=IMAGENET_MEAN,
|
| 26 |
+
std=IMAGENET_STD,
|
| 27 |
+
):
|
| 28 |
+
return A.Compose([
|
| 29 |
+
A.Resize(image_size, image_size),
|
| 30 |
+
|
| 31 |
+
# Geometry is safe
|
| 32 |
+
A.HorizontalFlip(p=0.5),
|
| 33 |
+
|
| 34 |
+
A.ShiftScaleRotate(
|
| 35 |
+
shift_limit=0.02,
|
| 36 |
+
scale_limit=0.03, # slightly reduced
|
| 37 |
+
rotate_limit=5, # slightly reduced
|
| 38 |
+
border_mode=0,
|
| 39 |
+
value=0,
|
| 40 |
+
p=0.3,
|
| 41 |
+
),
|
| 42 |
+
|
| 43 |
+
# MUCH weaker photometric changes
|
| 44 |
+
A.RandomBrightnessContrast(
|
| 45 |
+
brightness_limit=0.08, # ↓ from 0.15
|
| 46 |
+
contrast_limit=0.08,
|
| 47 |
+
p=0.3,
|
| 48 |
+
),
|
| 49 |
+
|
| 50 |
+
# Remove or reduce gamma
|
| 51 |
+
A.RandomGamma(
|
| 52 |
+
gamma_limit=(95, 105), # very mild
|
| 53 |
+
p=0.2,
|
| 54 |
+
),
|
| 55 |
+
|
| 56 |
+
# Remove hue shift entirely (important)
|
| 57 |
+
# Hue shifts are not realistic for fundus physiology
|
| 58 |
+
# -> comment this out or reduce heavily
|
| 59 |
+
# A.HueSaturationValue(...)
|
| 60 |
+
|
| 61 |
+
# Keep mild quality perturbation
|
| 62 |
+
A.OneOf([
|
| 63 |
+
A.GaussianBlur(blur_limit=(3, 5)),
|
| 64 |
+
A.Downscale(scale_min=0.85, scale_max=0.95, interpolation=cv2.INTER_LINEAR),
|
| 65 |
+
A.ImageCompression(quality_lower=80, quality_upper=100),
|
| 66 |
+
], p=0.15),
|
| 67 |
+
|
| 68 |
+
A.Normalize(mean=mean, std=std),
|
| 69 |
+
ToTensorV2(),
|
| 70 |
+
])
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
def get_val_transforms(
|
| 74 |
+
image_size=1024,
|
| 75 |
+
mean=IMAGENET_MEAN,
|
| 76 |
+
std=IMAGENET_STD,
|
| 77 |
+
):
|
| 78 |
+
"""
|
| 79 |
+
Validation/test transforms.
|
| 80 |
+
"""
|
| 81 |
+
return A.Compose([
|
| 82 |
+
A.Resize(image_size, image_size),
|
| 83 |
+
A.Normalize(mean=mean, std=std),
|
| 84 |
+
ToTensorV2(),
|
| 85 |
+
])
|
dataloader.py
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pathlib import Path
|
| 2 |
+
from typing import Optional, Sequence
|
| 3 |
+
|
| 4 |
+
import pandas as pd
|
| 5 |
+
from PIL import Image
|
| 6 |
+
|
| 7 |
+
import torch
|
| 8 |
+
from torch.utils.data import Dataset
|
| 9 |
+
from sklearn.model_selection import StratifiedGroupKFold
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class EyePACSDataset(Dataset):
|
| 13 |
+
"""
|
| 14 |
+
EyePACS diabetic retinopathy dataset.
|
| 15 |
+
|
| 16 |
+
Expected structure:
|
| 17 |
+
root/
|
| 18 |
+
├── trainLabels.csv
|
| 19 |
+
├── testLabels.csv
|
| 20 |
+
├── train/
|
| 21 |
+
│ ├── xxx_left.jpeg
|
| 22 |
+
│ └── xxx_right.jpeg
|
| 23 |
+
└── test/
|
| 24 |
+
├── xxx_left.jpeg
|
| 25 |
+
└── xxx_right.jpeg
|
| 26 |
+
|
| 27 |
+
Supported splits:
|
| 28 |
+
train:
|
| 29 |
+
Uses trainLabels.csv only.
|
| 30 |
+
Applies fold CV.
|
| 31 |
+
Keeps samples where fold != selected fold.
|
| 32 |
+
|
| 33 |
+
val:
|
| 34 |
+
Uses trainLabels.csv only.
|
| 35 |
+
Applies fold CV.
|
| 36 |
+
Keeps samples where fold == selected fold.
|
| 37 |
+
|
| 38 |
+
test:
|
| 39 |
+
Uses testLabels.csv only.
|
| 40 |
+
Uses original test/ image folder.
|
| 41 |
+
No fold filtering.
|
| 42 |
+
|
| 43 |
+
all:
|
| 44 |
+
Uses trainLabels.csv + testLabels.csv.
|
| 45 |
+
Applies fold CV over the combined labeled pool.
|
| 46 |
+
If fold is not None:
|
| 47 |
+
keeps samples where fold != selected fold by default if all_mode="train"
|
| 48 |
+
keeps samples where fold == selected fold if all_mode="val"
|
| 49 |
+
If fold is None:
|
| 50 |
+
keeps all combined labeled samples.
|
| 51 |
+
|
| 52 |
+
Args:
|
| 53 |
+
root:
|
| 54 |
+
EyePACS root directory.
|
| 55 |
+
|
| 56 |
+
split:
|
| 57 |
+
One of {"train", "val", "test", "all"}.
|
| 58 |
+
|
| 59 |
+
transform:
|
| 60 |
+
Optional image transform.
|
| 61 |
+
|
| 62 |
+
seed:
|
| 63 |
+
Random seed for fold assignment.
|
| 64 |
+
|
| 65 |
+
fold:
|
| 66 |
+
Selected fold index. Required for split="train" and split="val".
|
| 67 |
+
Optional for split="all". Ignored for split="test".
|
| 68 |
+
|
| 69 |
+
n_folds:
|
| 70 |
+
Number of folds.
|
| 71 |
+
|
| 72 |
+
all_mode:
|
| 73 |
+
Only used when split="all" and fold is not None.
|
| 74 |
+
Options:
|
| 75 |
+
"train": keep fold != selected fold
|
| 76 |
+
"val": keep fold == selected fold
|
| 77 |
+
"all": keep all folds
|
| 78 |
+
|
| 79 |
+
return_path:
|
| 80 |
+
If True, return metadata dictionary.
|
| 81 |
+
|
| 82 |
+
image_exts:
|
| 83 |
+
File extensions to try.
|
| 84 |
+
"""
|
| 85 |
+
|
| 86 |
+
def __init__(
|
| 87 |
+
self,
|
| 88 |
+
root,
|
| 89 |
+
split: str = "train",
|
| 90 |
+
transform=None,
|
| 91 |
+
seed: int = 42,
|
| 92 |
+
fold: Optional[int] = 0,
|
| 93 |
+
n_folds: int = 5,
|
| 94 |
+
all_mode: str = "all",
|
| 95 |
+
return_path: bool = False,
|
| 96 |
+
image_exts: Sequence[str] = (".jpeg", ".jpg", ".png"),
|
| 97 |
+
):
|
| 98 |
+
self.root = Path(root)
|
| 99 |
+
self.split = split
|
| 100 |
+
self.transform = transform
|
| 101 |
+
self.seed = seed
|
| 102 |
+
self.fold = fold
|
| 103 |
+
self.n_folds = n_folds
|
| 104 |
+
self.all_mode = all_mode
|
| 105 |
+
self.return_path = return_path
|
| 106 |
+
self.image_exts = tuple(image_exts)
|
| 107 |
+
|
| 108 |
+
if split not in {"train", "val", "test", "all"}:
|
| 109 |
+
raise ValueError(
|
| 110 |
+
f"split must be one of {{'train', 'val', 'test', 'all'}}, got {split}"
|
| 111 |
+
)
|
| 112 |
+
|
| 113 |
+
if all_mode not in {"train", "val", "all"}:
|
| 114 |
+
raise ValueError(
|
| 115 |
+
f"all_mode must be one of {{'train', 'val', 'all'}}, got {all_mode}"
|
| 116 |
+
)
|
| 117 |
+
|
| 118 |
+
if split in {"train", "val"} and fold is None:
|
| 119 |
+
raise ValueError(f"fold must be provided for split='{split}'")
|
| 120 |
+
|
| 121 |
+
if fold is not None and not (0 <= fold < n_folds):
|
| 122 |
+
raise ValueError(f"fold must be in [0, {n_folds - 1}], got {fold}")
|
| 123 |
+
|
| 124 |
+
if split == "train":
|
| 125 |
+
df = self._load_train_dataframe()
|
| 126 |
+
df = self._assign_folds(df)
|
| 127 |
+
df = df[df["fold"] != fold].reset_index(drop=True)
|
| 128 |
+
|
| 129 |
+
elif split == "val":
|
| 130 |
+
df = self._load_train_dataframe()
|
| 131 |
+
df = self._assign_folds(df)
|
| 132 |
+
df = df[df["fold"] == fold].reset_index(drop=True)
|
| 133 |
+
|
| 134 |
+
elif split == "test":
|
| 135 |
+
df = self._load_test_dataframe()
|
| 136 |
+
df["fold"] = -1
|
| 137 |
+
|
| 138 |
+
elif split == "all":
|
| 139 |
+
df = self._load_combined_dataframe()
|
| 140 |
+
df = self._assign_folds(df)
|
| 141 |
+
|
| 142 |
+
if fold is not None:
|
| 143 |
+
if all_mode == "train":
|
| 144 |
+
df = df[df["fold"] != fold].reset_index(drop=True)
|
| 145 |
+
elif all_mode == "val":
|
| 146 |
+
df = df[df["fold"] == fold].reset_index(drop=True)
|
| 147 |
+
elif all_mode == "all":
|
| 148 |
+
df = df.reset_index(drop=True)
|
| 149 |
+
else:
|
| 150 |
+
df = df.reset_index(drop=True)
|
| 151 |
+
|
| 152 |
+
self.df = df.reset_index(drop=True)
|
| 153 |
+
self.samples = self._build_samples(self.df)
|
| 154 |
+
|
| 155 |
+
if len(self.samples) == 0:
|
| 156 |
+
raise RuntimeError(
|
| 157 |
+
f"No images found for split='{split}'. "
|
| 158 |
+
f"Check root path, CSV files, folders, and file extensions."
|
| 159 |
+
)
|
| 160 |
+
|
| 161 |
+
self._print_summary()
|
| 162 |
+
|
| 163 |
+
def _load_train_dataframe(self) -> pd.DataFrame:
|
| 164 |
+
path = self.root / "trainLabels.csv"
|
| 165 |
+
if not path.exists():
|
| 166 |
+
raise FileNotFoundError(f"Missing trainLabels.csv: {path}")
|
| 167 |
+
|
| 168 |
+
df = pd.read_csv(path)
|
| 169 |
+
return self._standardize_label_dataframe(df, source="train")
|
| 170 |
+
|
| 171 |
+
def _load_test_dataframe(self) -> pd.DataFrame:
|
| 172 |
+
path = self.root / "testLabels.csv"
|
| 173 |
+
if not path.exists():
|
| 174 |
+
raise FileNotFoundError(f"Missing testLabels.csv: {path}")
|
| 175 |
+
|
| 176 |
+
df = pd.read_csv(path)
|
| 177 |
+
return self._standardize_label_dataframe(df, source="test")
|
| 178 |
+
|
| 179 |
+
def _load_combined_dataframe(self) -> pd.DataFrame:
|
| 180 |
+
train_df = self._load_train_dataframe()
|
| 181 |
+
test_df = self._load_test_dataframe()
|
| 182 |
+
|
| 183 |
+
df = pd.concat([train_df, test_df], axis=0, ignore_index=True)
|
| 184 |
+
df = df.drop_duplicates(subset=["source", "image"]).reset_index(drop=True)
|
| 185 |
+
|
| 186 |
+
return df
|
| 187 |
+
|
| 188 |
+
@staticmethod
|
| 189 |
+
def _standardize_label_dataframe(df: pd.DataFrame, source: str) -> pd.DataFrame:
|
| 190 |
+
"""
|
| 191 |
+
Standardize label dataframe to:
|
| 192 |
+
image, level, source, patient_id
|
| 193 |
+
|
| 194 |
+
EyePACS image names usually look like:
|
| 195 |
+
10_left
|
| 196 |
+
10_right
|
| 197 |
+
|
| 198 |
+
patient_id is extracted as the part before the first underscore.
|
| 199 |
+
"""
|
| 200 |
+
|
| 201 |
+
if "image" not in df.columns:
|
| 202 |
+
raise ValueError(f"{source} labels CSV must contain column 'image'")
|
| 203 |
+
|
| 204 |
+
if "level" not in df.columns:
|
| 205 |
+
raise ValueError(f"{source} labels CSV must contain column 'level'")
|
| 206 |
+
|
| 207 |
+
df = df[["image", "level"]].copy()
|
| 208 |
+
df["image"] = df["image"].astype(str)
|
| 209 |
+
df["level"] = df["level"].astype(int)
|
| 210 |
+
df["source"] = source
|
| 211 |
+
df["patient_id"] = df["image"].str.split("_").str[0].astype(str)
|
| 212 |
+
|
| 213 |
+
return df
|
| 214 |
+
|
| 215 |
+
def _assign_folds(self, df: pd.DataFrame) -> pd.DataFrame:
|
| 216 |
+
"""
|
| 217 |
+
Assign stratified group folds.
|
| 218 |
+
|
| 219 |
+
Grouping:
|
| 220 |
+
patient_id
|
| 221 |
+
|
| 222 |
+
Stratification label:
|
| 223 |
+
max DR severity across all images for that patient_id.
|
| 224 |
+
|
| 225 |
+
This keeps left/right eyes from the same patient in the same fold.
|
| 226 |
+
"""
|
| 227 |
+
|
| 228 |
+
df = df.copy()
|
| 229 |
+
|
| 230 |
+
patient_df = (
|
| 231 |
+
df.groupby("patient_id", as_index=False)
|
| 232 |
+
.agg(patient_level=("level", "max"))
|
| 233 |
+
.reset_index(drop=True)
|
| 234 |
+
)
|
| 235 |
+
|
| 236 |
+
groups = patient_df["patient_id"].values
|
| 237 |
+
y = patient_df["patient_level"].values
|
| 238 |
+
|
| 239 |
+
splitter = StratifiedGroupKFold(
|
| 240 |
+
n_splits=self.n_folds,
|
| 241 |
+
shuffle=True,
|
| 242 |
+
random_state=self.seed,
|
| 243 |
+
)
|
| 244 |
+
|
| 245 |
+
patient_df["fold"] = -1
|
| 246 |
+
|
| 247 |
+
for fold_idx, (_, val_idx) in enumerate(
|
| 248 |
+
splitter.split(X=patient_df, y=y, groups=groups)
|
| 249 |
+
):
|
| 250 |
+
patient_df.loc[val_idx, "fold"] = fold_idx
|
| 251 |
+
|
| 252 |
+
if (patient_df["fold"] < 0).any():
|
| 253 |
+
raise RuntimeError("Some patients were not assigned to a fold")
|
| 254 |
+
|
| 255 |
+
fold_map = dict(zip(patient_df["patient_id"], patient_df["fold"]))
|
| 256 |
+
df["fold"] = df["patient_id"].map(fold_map).astype(int)
|
| 257 |
+
|
| 258 |
+
return df
|
| 259 |
+
|
| 260 |
+
def _build_samples(self, df: pd.DataFrame):
|
| 261 |
+
samples = []
|
| 262 |
+
missing = []
|
| 263 |
+
|
| 264 |
+
for _, row in df.iterrows():
|
| 265 |
+
image_id = str(row["image"])
|
| 266 |
+
label = int(row["level"])
|
| 267 |
+
source = str(row["source"])
|
| 268 |
+
patient_id = str(row["patient_id"])
|
| 269 |
+
fold = int(row["fold"])
|
| 270 |
+
|
| 271 |
+
image_dir = self.root / source
|
| 272 |
+
image_path = self._find_image_path(image_dir, image_id)
|
| 273 |
+
|
| 274 |
+
if image_path is None:
|
| 275 |
+
missing.append((source, image_id))
|
| 276 |
+
continue
|
| 277 |
+
|
| 278 |
+
samples.append(
|
| 279 |
+
{
|
| 280 |
+
"image_id": image_id,
|
| 281 |
+
"image_path": image_path,
|
| 282 |
+
"label": label,
|
| 283 |
+
"source": source,
|
| 284 |
+
"patient_id": patient_id,
|
| 285 |
+
"fold": fold,
|
| 286 |
+
}
|
| 287 |
+
)
|
| 288 |
+
|
| 289 |
+
if len(missing) > 0:
|
| 290 |
+
print(
|
| 291 |
+
f"[EyePACSDataset] Warning: {len(missing)} images listed in CSV "
|
| 292 |
+
f"were not found on disk."
|
| 293 |
+
)
|
| 294 |
+
print(f"[EyePACSDataset] First few missing: {missing[:5]}")
|
| 295 |
+
|
| 296 |
+
return samples
|
| 297 |
+
|
| 298 |
+
def _find_image_path(self, image_dir: Path, image_id: str):
|
| 299 |
+
for ext in self.image_exts:
|
| 300 |
+
path = image_dir / f"{image_id}{ext}"
|
| 301 |
+
if path.exists():
|
| 302 |
+
return path
|
| 303 |
+
return None
|
| 304 |
+
|
| 305 |
+
def _print_summary(self):
|
| 306 |
+
labels = [s["label"] for s in self.samples]
|
| 307 |
+
counts = pd.Series(labels).value_counts().sort_index()
|
| 308 |
+
|
| 309 |
+
print(f"[EyePACSDataset] split={self.split}")
|
| 310 |
+
print(f"[EyePACSDataset] root={self.root}")
|
| 311 |
+
print(f"[EyePACSDataset] n={len(self.samples)}")
|
| 312 |
+
|
| 313 |
+
if self.split != "test":
|
| 314 |
+
print(
|
| 315 |
+
f"[EyePACSDataset] seed={self.seed}, "
|
| 316 |
+
f"fold={self.fold}, "
|
| 317 |
+
f"n_folds={self.n_folds}"
|
| 318 |
+
)
|
| 319 |
+
|
| 320 |
+
if self.split == "all":
|
| 321 |
+
print(f"[EyePACSDataset] all_mode={self.all_mode}")
|
| 322 |
+
|
| 323 |
+
print("[EyePACSDataset] source counts:")
|
| 324 |
+
source_counts = pd.Series([s["source"] for s in self.samples]).value_counts()
|
| 325 |
+
for source, count in source_counts.items():
|
| 326 |
+
print(f" {source}: {int(count)}")
|
| 327 |
+
|
| 328 |
+
print("[EyePACSDataset] class counts:")
|
| 329 |
+
for cls in range(5):
|
| 330 |
+
print(f" class {cls}: {int(counts.get(cls, 0))}")
|
| 331 |
+
|
| 332 |
+
def __len__(self):
|
| 333 |
+
return len(self.samples)
|
| 334 |
+
|
| 335 |
+
def __getitem__(self, idx):
|
| 336 |
+
sample = self.samples[idx]
|
| 337 |
+
|
| 338 |
+
image = Image.open(sample["image_path"]).convert("RGB")
|
| 339 |
+
|
| 340 |
+
if self.transform is not None:
|
| 341 |
+
image = self.transform(image)
|
| 342 |
+
|
| 343 |
+
label = torch.tensor(sample["label"], dtype=torch.long)
|
| 344 |
+
|
| 345 |
+
if self.return_path:
|
| 346 |
+
return {
|
| 347 |
+
"image": image,
|
| 348 |
+
"label": label,
|
| 349 |
+
"image_id": sample["image_id"],
|
| 350 |
+
"image_path": str(sample["image_path"]),
|
| 351 |
+
"source": sample["source"],
|
| 352 |
+
"patient_id": sample["patient_id"],
|
| 353 |
+
"fold": sample["fold"],
|
| 354 |
+
}
|
| 355 |
+
|
| 356 |
+
return image, label
|
model.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""DeepSeeNet model definition."""
|
| 2 |
+
|
| 3 |
+
from torch import Tensor, nn
|
| 4 |
+
|
| 5 |
+
try:
|
| 6 |
+
import timm
|
| 7 |
+
except ImportError: # pragma: no cover - handled when timm is absent.
|
| 8 |
+
timm = None
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
class DeepSeeNet(nn.Module):
|
| 12 |
+
"""DeepSeeNet risk-factor classifier in PyTorch.
|
| 13 |
+
|
| 14 |
+
Args:
|
| 15 |
+
n_classes: Number of output classes.
|
| 16 |
+
backbone: Any timm model name that supports ``num_classes=0``. The
|
| 17 |
+
default uses InceptionV3.
|
| 18 |
+
pretrained: Load ImageNet weights for the backbone.
|
| 19 |
+
dropout: Dropout probability used by the classifier head.
|
| 20 |
+
freeze_backbone: If true, keep the backbone frozen and train only the
|
| 21 |
+
classifier head.
|
| 22 |
+
"""
|
| 23 |
+
|
| 24 |
+
def __init__(
|
| 25 |
+
self,
|
| 26 |
+
n_classes: int = 2,
|
| 27 |
+
backbone: str = "inception_v3",
|
| 28 |
+
pretrained: bool = True,
|
| 29 |
+
dropout: float = 0.5,
|
| 30 |
+
freeze_backbone: bool = False,
|
| 31 |
+
) -> None:
|
| 32 |
+
super().__init__()
|
| 33 |
+
if n_classes < 1:
|
| 34 |
+
raise ValueError("n_classes must be positive")
|
| 35 |
+
if timm is None:
|
| 36 |
+
raise ImportError("timm is required to build DeepSeeNet")
|
| 37 |
+
|
| 38 |
+
self.backbone_name = backbone
|
| 39 |
+
self.backbone = timm.create_model(
|
| 40 |
+
backbone,
|
| 41 |
+
pretrained=pretrained,
|
| 42 |
+
num_classes=0,
|
| 43 |
+
global_pool="avg",
|
| 44 |
+
)
|
| 45 |
+
in_features = self.backbone.num_features
|
| 46 |
+
self.classifier = nn.Sequential(
|
| 47 |
+
nn.Linear(in_features, 256),
|
| 48 |
+
nn.ReLU(inplace=True),
|
| 49 |
+
nn.Dropout(dropout),
|
| 50 |
+
nn.Linear(256, 128),
|
| 51 |
+
nn.ReLU(inplace=True),
|
| 52 |
+
nn.Dropout(dropout),
|
| 53 |
+
nn.Linear(128, n_classes),
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
if freeze_backbone:
|
| 57 |
+
self.backbone.requires_grad_(False)
|
| 58 |
+
|
| 59 |
+
def forward(self, x: Tensor) -> Tensor:
|
| 60 |
+
features = self.backbone(x)
|
| 61 |
+
return self.classifier(features)
|
requirements.txt
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
albumentations
|
| 2 |
+
gradio
|
| 3 |
+
huggingface_hub
|
| 4 |
+
numpy
|
| 5 |
+
opencv-python
|
| 6 |
+
pandas
|
| 7 |
+
pillow
|
| 8 |
+
pydantic
|
| 9 |
+
timm
|
| 10 |
+
torch
|
| 11 |
+
torchvision
|
| 12 |
+
torchaudio
|
| 13 |
+
tqdm
|
runs/eyepacs_dr/inception_v3_fold0/best_model_only.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:dce962b4cc7a2c70bff55de17f3df89c1ff8c03fb881a681591377794d0c19de
|
| 3 |
+
size 89735243
|
runs/eyepacs_dr/inception_v3_fold0/history.json
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"epoch": 1,
|
| 4 |
+
"lr": 0.0001,
|
| 5 |
+
"train_loss": 1.2191880825112196,
|
| 6 |
+
"train_acc": 0.5508288227334236,
|
| 7 |
+
"val_loss": 0.8676833006413706,
|
| 8 |
+
"val_acc": 0.7436865839909809,
|
| 9 |
+
"val_referable_acc": 0.9082863585118377,
|
| 10 |
+
"val_any_dr_acc": 0.8395152198421646,
|
| 11 |
+
"val_severe_or_pdr_acc": 0.9364712514092447,
|
| 12 |
+
"val_qwk": 0.7140886061578311,
|
| 13 |
+
"val_referable_auc": 0.924552902315247,
|
| 14 |
+
"val_any_dr_auc": 0.879340733543783,
|
| 15 |
+
"val_severe_or_pdr_auc": 0.9729235633730084
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"epoch": 2,
|
| 19 |
+
"lr": 9.972883382072954e-05,
|
| 20 |
+
"train_loss": 1.0452303189547363,
|
| 21 |
+
"train_acc": 0.6802125620207488,
|
| 22 |
+
"val_loss": 0.7482551874544602,
|
| 23 |
+
"val_acc": 0.7671927846674182,
|
| 24 |
+
"val_referable_acc": 0.9131341600901917,
|
| 25 |
+
"val_any_dr_acc": 0.8613866967305525,
|
| 26 |
+
"val_severe_or_pdr_acc": 0.9496054114994363,
|
| 27 |
+
"val_qwk": 0.7584975852550456,
|
| 28 |
+
"val_referable_auc": 0.9301897769832052,
|
| 29 |
+
"val_any_dr_auc": 0.9032338758891758,
|
| 30 |
+
"val_severe_or_pdr_auc": 0.9757942542713257
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"epoch": 3,
|
| 34 |
+
"lr": 9.891830623632339e-05,
|
| 35 |
+
"train_loss": 0.9849801756774298,
|
| 36 |
+
"train_acc": 0.719539354984213,
|
| 37 |
+
"val_loss": 0.8034545580053276,
|
| 38 |
+
"val_acc": 0.7496617812852311,
|
| 39 |
+
"val_referable_acc": 0.9096392333709132,
|
| 40 |
+
"val_any_dr_acc": 0.8586245772266066,
|
| 41 |
+
"val_severe_or_pdr_acc": 0.9195603156708004,
|
| 42 |
+
"val_qwk": 0.7155813958918468,
|
| 43 |
+
"val_referable_auc": 0.9341313162498839,
|
| 44 |
+
"val_any_dr_auc": 0.9124605325061405,
|
| 45 |
+
"val_severe_or_pdr_auc": 0.9746139125395339
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"epoch": 4,
|
| 49 |
+
"lr": 9.757729755661011e-05,
|
| 50 |
+
"train_loss": 0.9430840012588424,
|
| 51 |
+
"train_acc": 0.740978800180424,
|
| 52 |
+
"val_loss": 0.7264118472107906,
|
| 53 |
+
"val_acc": 0.7847801578354002,
|
| 54 |
+
"val_referable_acc": 0.9155016910935738,
|
| 55 |
+
"val_any_dr_acc": 0.8696166854565953,
|
| 56 |
+
"val_severe_or_pdr_acc": 0.9439684329199549,
|
| 57 |
+
"val_qwk": 0.7404066770264675,
|
| 58 |
+
"val_referable_auc": 0.9430007323088389,
|
| 59 |
+
"val_any_dr_auc": 0.918949293829938,
|
| 60 |
+
"val_severe_or_pdr_auc": 0.9757122141043169
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"epoch": 5,
|
| 64 |
+
"lr": 9.572050015330873e-05,
|
| 65 |
+
"train_loss": 0.9146992052977936,
|
| 66 |
+
"train_acc": 0.756441700496166,
|
| 67 |
+
"val_loss": 0.6687679942323498,
|
| 68 |
+
"val_acc": 0.8094701240135288,
|
| 69 |
+
"val_referable_acc": 0.913641488162345,
|
| 70 |
+
"val_any_dr_acc": 0.8978015783540022,
|
| 71 |
+
"val_severe_or_pdr_acc": 0.9494363021420519,
|
| 72 |
+
"val_qwk": 0.7657158782341715,
|
| 73 |
+
"val_referable_auc": 0.9439605662828892,
|
| 74 |
+
"val_any_dr_auc": 0.9205573987730261,
|
| 75 |
+
"val_severe_or_pdr_auc": 0.9773371098739827
|
| 76 |
+
},
|
| 77 |
+
{
|
| 78 |
+
"epoch": 6,
|
| 79 |
+
"lr": 9.336825748732972e-05,
|
| 80 |
+
"train_loss": 0.882006509337922,
|
| 81 |
+
"train_acc": 0.7686485115020297,
|
| 82 |
+
"val_loss": 0.7364799950544837,
|
| 83 |
+
"val_acc": 0.7890642615558061,
|
| 84 |
+
"val_referable_acc": 0.913923337091319,
|
| 85 |
+
"val_any_dr_acc": 0.8679819616685457,
|
| 86 |
+
"val_severe_or_pdr_acc": 0.9467305524239008,
|
| 87 |
+
"val_qwk": 0.7378029189144739,
|
| 88 |
+
"val_referable_auc": 0.9429656239713404,
|
| 89 |
+
"val_any_dr_auc": 0.9224749898528801,
|
| 90 |
+
"val_severe_or_pdr_auc": 0.9758237458346295
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"epoch": 7,
|
| 94 |
+
"lr": 9.05463412215599e-05,
|
| 95 |
+
"train_loss": 0.8602466160817139,
|
| 96 |
+
"train_acc": 0.7752311682453766,
|
| 97 |
+
"val_loss": 0.6406958381245343,
|
| 98 |
+
"val_acc": 0.8077226606538895,
|
| 99 |
+
"val_referable_acc": 0.9151071025930101,
|
| 100 |
+
"val_any_dr_acc": 0.8822998872604284,
|
| 101 |
+
"val_severe_or_pdr_acc": 0.9576099210822999,
|
| 102 |
+
"val_qwk": 0.7721192161837538,
|
| 103 |
+
"val_referable_auc": 0.9449475727317759,
|
| 104 |
+
"val_any_dr_auc": 0.9233336916673446,
|
| 105 |
+
"val_severe_or_pdr_auc": 0.9767672256289048
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"epoch": 8,
|
| 109 |
+
"lr": 8.728566886113101e-05,
|
| 110 |
+
"train_loss": 0.8290294695126349,
|
| 111 |
+
"train_acc": 0.779967298150654,
|
| 112 |
+
"val_loss": 0.6343717073507212,
|
| 113 |
+
"val_acc": 0.8144870349492672,
|
| 114 |
+
"val_referable_acc": 0.9237880496054115,
|
| 115 |
+
"val_any_dr_acc": 0.8870349492671927,
|
| 116 |
+
"val_severe_or_pdr_acc": 0.9634160090191657,
|
| 117 |
+
"val_qwk": 0.8033455171949371,
|
| 118 |
+
"val_referable_auc": 0.9489161527156735,
|
| 119 |
+
"val_any_dr_auc": 0.9277659781884949,
|
| 120 |
+
"val_severe_or_pdr_auc": 0.9800201271876396
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"epoch": 9,
|
| 124 |
+
"lr": 8.362196501476347e-05,
|
| 125 |
+
"train_loss": 0.8049967132162607,
|
| 126 |
+
"train_acc": 0.7827582318448354,
|
| 127 |
+
"val_loss": 0.6686938404633738,
|
| 128 |
+
"val_acc": 0.7877677564825254,
|
| 129 |
+
"val_referable_acc": 0.9228297632468997,
|
| 130 |
+
"val_any_dr_acc": 0.8662908680947012,
|
| 131 |
+
"val_severe_or_pdr_acc": 0.9598647125140924,
|
| 132 |
+
"val_qwk": 0.7868667085078025,
|
| 133 |
+
"val_referable_auc": 0.948626316362486,
|
| 134 |
+
"val_any_dr_auc": 0.9289171459554377,
|
| 135 |
+
"val_severe_or_pdr_auc": 0.9788885805878594
|
| 136 |
+
},
|
| 137 |
+
{
|
| 138 |
+
"epoch": 10,
|
| 139 |
+
"lr": 7.959536998847741e-05,
|
| 140 |
+
"train_loss": 0.7784485263522273,
|
| 141 |
+
"train_acc": 0.7822789806044204,
|
| 142 |
+
"val_loss": 0.6502069805493618,
|
| 143 |
+
"val_acc": 0.7921082299887261,
|
| 144 |
+
"val_referable_acc": 0.9254227733934611,
|
| 145 |
+
"val_any_dr_acc": 0.8756482525366404,
|
| 146 |
+
"val_severe_or_pdr_acc": 0.9478579481397971,
|
| 147 |
+
"val_qwk": 0.7910244571190812,
|
| 148 |
+
"val_referable_auc": 0.9516418326868392,
|
| 149 |
+
"val_any_dr_auc": 0.9282227682160731,
|
| 150 |
+
"val_severe_or_pdr_auc": 0.9795037924720514
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"epoch": 11,
|
| 154 |
+
"lr": 7.524999999999999e-05,
|
| 155 |
+
"train_loss": 0.7509459461924403,
|
| 156 |
+
"train_acc": 0.7843510374379793,
|
| 157 |
+
"val_loss": 0.6940719285839171,
|
| 158 |
+
"val_acc": 0.7910372040586245,
|
| 159 |
+
"val_referable_acc": 0.9186020293122886,
|
| 160 |
+
"val_any_dr_acc": 0.8686583990980834,
|
| 161 |
+
"val_severe_or_pdr_acc": 0.9589627959413755,
|
| 162 |
+
"val_qwk": 0.7803465132729354,
|
| 163 |
+
"val_referable_auc": 0.9472788109365553,
|
| 164 |
+
"val_any_dr_auc": 0.9282660544196276,
|
| 165 |
+
"val_severe_or_pdr_auc": 0.9756903724737973
|
| 166 |
+
},
|
| 167 |
+
{
|
| 168 |
+
"epoch": 12,
|
| 169 |
+
"lr": 7.06334638322521e-05,
|
| 170 |
+
"train_loss": 0.7224059543149344,
|
| 171 |
+
"train_acc": 0.790581303563374,
|
| 172 |
+
"val_loss": 0.6284573407157029,
|
| 173 |
+
"val_acc": 0.8084554678692221,
|
| 174 |
+
"val_referable_acc": 0.9204622322435174,
|
| 175 |
+
"val_any_dr_acc": 0.8856820744081173,
|
| 176 |
+
"val_severe_or_pdr_acc": 0.9538331454340474,
|
| 177 |
+
"val_qwk": 0.7859381302661944,
|
| 178 |
+
"val_referable_auc": 0.949624795859308,
|
| 179 |
+
"val_any_dr_auc": 0.9286386672917757,
|
| 180 |
+
"val_severe_or_pdr_auc": 0.9782240016140643
|
| 181 |
+
},
|
| 182 |
+
{
|
| 183 |
+
"epoch": 13,
|
| 184 |
+
"lr": 6.579634122155988e-05,
|
| 185 |
+
"train_loss": 0.678931502343891,
|
| 186 |
+
"train_acc": 0.8054239963915201,
|
| 187 |
+
"val_loss": 0.6790591289521339,
|
| 188 |
+
"val_acc": 0.7918827508455468,
|
| 189 |
+
"val_referable_acc": 0.9203494926719279,
|
| 190 |
+
"val_any_dr_acc": 0.8708004509582864,
|
| 191 |
+
"val_severe_or_pdr_acc": 0.9526493799323562,
|
| 192 |
+
"val_qwk": 0.7776873128462451,
|
| 193 |
+
"val_referable_auc": 0.9484067777659061,
|
| 194 |
+
"val_any_dr_auc": 0.9263266363022873,
|
| 195 |
+
"val_severe_or_pdr_auc": 0.9759889700838298
|
| 196 |
+
},
|
| 197 |
+
{
|
| 198 |
+
"epoch": 14,
|
| 199 |
+
"lr": 6.079162869547907e-05,
|
| 200 |
+
"train_loss": 0.65180876729426,
|
| 201 |
+
"train_acc": 0.8017450383400992,
|
| 202 |
+
"val_loss": 0.635306676372197,
|
| 203 |
+
"val_acc": 0.8014656144306652,
|
| 204 |
+
"val_referable_acc": 0.9195039458850056,
|
| 205 |
+
"val_any_dr_acc": 0.8771138669673055,
|
| 206 |
+
"val_severe_or_pdr_acc": 0.957271702367531,
|
| 207 |
+
"val_qwk": 0.7925515495846708,
|
| 208 |
+
"val_referable_auc": 0.9500388593755204,
|
| 209 |
+
"val_any_dr_auc": 0.9308198505052305,
|
| 210 |
+
"val_severe_or_pdr_auc": 0.976161594034368
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"epoch": 15,
|
| 214 |
+
"lr": 5.567415893174884e-05,
|
| 215 |
+
"train_loss": 0.61246272180873,
|
| 216 |
+
"train_acc": 0.8109212900315742,
|
| 217 |
+
"val_loss": 0.6278831657186033,
|
| 218 |
+
"val_acc": 0.7925028184892897,
|
| 219 |
+
"val_referable_acc": 0.9235625704622322,
|
| 220 |
+
"val_any_dr_acc": 0.8679255918827509,
|
| 221 |
+
"val_severe_or_pdr_acc": 0.9588500563697858,
|
| 222 |
+
"val_qwk": 0.8006316582640922,
|
| 223 |
+
"val_referable_auc": 0.9499428891538771,
|
| 224 |
+
"val_any_dr_auc": 0.9269722669912654,
|
| 225 |
+
"val_severe_or_pdr_auc": 0.9790055816626393
|
| 226 |
+
},
|
| 227 |
+
{
|
| 228 |
+
"epoch": 16,
|
| 229 |
+
"lr": 5.05e-05,
|
| 230 |
+
"train_loss": 0.5845572758309735,
|
| 231 |
+
"train_acc": 0.8146425349571493,
|
| 232 |
+
"val_loss": 0.6543550435289858,
|
| 233 |
+
"val_acc": 0.7959977452085683,
|
| 234 |
+
"val_referable_acc": 0.9232807215332581,
|
| 235 |
+
"val_any_dr_acc": 0.8736753100338218,
|
| 236 |
+
"val_severe_or_pdr_acc": 0.9649379932356257,
|
| 237 |
+
"val_qwk": 0.8075519604379204,
|
| 238 |
+
"val_referable_auc": 0.9482329286570407,
|
| 239 |
+
"val_any_dr_auc": 0.9286975430685462,
|
| 240 |
+
"val_severe_or_pdr_auc": 0.9758107695467758
|
| 241 |
+
},
|
| 242 |
+
{
|
| 243 |
+
"epoch": 17,
|
| 244 |
+
"lr": 4.532584106825115e-05,
|
| 245 |
+
"train_loss": 0.5447519773001546,
|
| 246 |
+
"train_acc": 0.821521199819576,
|
| 247 |
+
"val_loss": 0.6652101601796327,
|
| 248 |
+
"val_acc": 0.7871476888387824,
|
| 249 |
+
"val_referable_acc": 0.923055242390079,
|
| 250 |
+
"val_any_dr_acc": 0.8653325817361894,
|
| 251 |
+
"val_severe_or_pdr_acc": 0.961837655016911,
|
| 252 |
+
"val_qwk": 0.791314256809605,
|
| 253 |
+
"val_referable_auc": 0.9438051936460965,
|
| 254 |
+
"val_any_dr_auc": 0.9265324644482931,
|
| 255 |
+
"val_severe_or_pdr_auc": 0.9767693704698723
|
| 256 |
+
},
|
| 257 |
+
{
|
| 258 |
+
"epoch": 18,
|
| 259 |
+
"lr": 4.0208371304520894e-05,
|
| 260 |
+
"train_loss": 0.5182197611740327,
|
| 261 |
+
"train_acc": 0.8213379566982408,
|
| 262 |
+
"val_loss": 0.6194416342485851,
|
| 263 |
+
"val_acc": 0.7971815107102593,
|
| 264 |
+
"val_referable_acc": 0.9248590755355129,
|
| 265 |
+
"val_any_dr_acc": 0.8734498308906427,
|
| 266 |
+
"val_severe_or_pdr_acc": 0.9632468996617812,
|
| 267 |
+
"val_qwk": 0.8099503330099491,
|
| 268 |
+
"val_referable_auc": 0.9476082860622475,
|
| 269 |
+
"val_any_dr_auc": 0.9269798287926418,
|
| 270 |
+
"val_severe_or_pdr_auc": 0.9785031884133404
|
| 271 |
+
},
|
| 272 |
+
{
|
| 273 |
+
"epoch": 19,
|
| 274 |
+
"lr": 3.520365877844009e-05,
|
| 275 |
+
"train_loss": 0.4779584521766337,
|
| 276 |
+
"train_acc": 0.8299503834009924,
|
| 277 |
+
"val_loss": 0.6388505003094808,
|
| 278 |
+
"val_acc": 0.8011837655016911,
|
| 279 |
+
"val_referable_acc": 0.9214768883878242,
|
| 280 |
+
"val_any_dr_acc": 0.8696166854565953,
|
| 281 |
+
"val_severe_or_pdr_acc": 0.9637542277339346,
|
| 282 |
+
"val_qwk": 0.7931194428109762,
|
| 283 |
+
"val_referable_auc": 0.9505122746308755,
|
| 284 |
+
"val_any_dr_auc": 0.9300419577789887,
|
| 285 |
+
"val_severe_or_pdr_auc": 0.9751037227218233
|
| 286 |
+
}
|
| 287 |
+
]
|
runs/eyepacs_dr/inception_v3_fold1/best_model_only.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:065898a2a70eb2c96da5c2c78efacc5f29dc66a6394af397bb0f761cf7527cb1
|
| 3 |
+
size 89735243
|
runs/eyepacs_dr/inception_v3_fold1/history.json
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"epoch": 1,
|
| 4 |
+
"lr": 0.0001,
|
| 5 |
+
"train_loss": 1.2026121128933571,
|
| 6 |
+
"train_acc": 0.553168696436626,
|
| 7 |
+
"val_loss": 0.8374152492743148,
|
| 8 |
+
"val_acc": 0.7521136286777139,
|
| 9 |
+
"val_referable_acc": 0.8970803742531845,
|
| 10 |
+
"val_any_dr_acc": 0.8385751324540638,
|
| 11 |
+
"val_severe_or_pdr_acc": 0.9418329387893135,
|
| 12 |
+
"val_qwk": 0.6836796861912281,
|
| 13 |
+
"val_referable_auc": 0.9156936050415827,
|
| 14 |
+
"val_any_dr_auc": 0.8720412184915984,
|
| 15 |
+
"val_severe_or_pdr_auc": 0.9578836845029959
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"epoch": 2,
|
| 19 |
+
"lr": 9.972883382072954e-05,
|
| 20 |
+
"train_loss": 1.0318292616238507,
|
| 21 |
+
"train_acc": 0.6790426251691475,
|
| 22 |
+
"val_loss": 0.7552449644290532,
|
| 23 |
+
"val_acc": 0.7826626084996054,
|
| 24 |
+
"val_referable_acc": 0.9076766993574569,
|
| 25 |
+
"val_any_dr_acc": 0.871491376394995,
|
| 26 |
+
"val_severe_or_pdr_acc": 0.9453838349678728,
|
| 27 |
+
"val_qwk": 0.7235517054346978,
|
| 28 |
+
"val_referable_auc": 0.9167888976621349,
|
| 29 |
+
"val_any_dr_auc": 0.8932112253636199,
|
| 30 |
+
"val_severe_or_pdr_auc": 0.9604115897123635
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"epoch": 3,
|
| 34 |
+
"lr": 9.891830623632339e-05,
|
| 35 |
+
"train_loss": 0.9734103289551707,
|
| 36 |
+
"train_acc": 0.726009246729815,
|
| 37 |
+
"val_loss": 0.7190881273400056,
|
| 38 |
+
"val_acc": 0.8057152519445384,
|
| 39 |
+
"val_referable_acc": 0.9196821102468719,
|
| 40 |
+
"val_any_dr_acc": 0.8854695073836095,
|
| 41 |
+
"val_severe_or_pdr_acc": 0.9467365573216098,
|
| 42 |
+
"val_qwk": 0.7489601682632545,
|
| 43 |
+
"val_referable_auc": 0.937417607330826,
|
| 44 |
+
"val_any_dr_auc": 0.907371009956367,
|
| 45 |
+
"val_severe_or_pdr_auc": 0.963622201448665
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"epoch": 4,
|
| 49 |
+
"lr": 9.757729755661011e-05,
|
| 50 |
+
"train_loss": 0.9321129762029454,
|
| 51 |
+
"train_acc": 0.7482380469102391,
|
| 52 |
+
"val_loss": 0.7095937849757449,
|
| 53 |
+
"val_acc": 0.7950061999774546,
|
| 54 |
+
"val_referable_acc": 0.921373013189043,
|
| 55 |
+
"val_any_dr_acc": 0.8789313493405478,
|
| 56 |
+
"val_severe_or_pdr_acc": 0.9477510990869125,
|
| 57 |
+
"val_qwk": 0.762886911264498,
|
| 58 |
+
"val_referable_auc": 0.9420763854554339,
|
| 59 |
+
"val_any_dr_auc": 0.9133179603379078,
|
| 60 |
+
"val_severe_or_pdr_auc": 0.9666140768371154
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"epoch": 5,
|
| 64 |
+
"lr": 9.572050015330873e-05,
|
| 65 |
+
"train_loss": 0.9010974023193726,
|
| 66 |
+
"train_acc": 0.7627565403698692,
|
| 67 |
+
"val_loss": 0.7568363213052665,
|
| 68 |
+
"val_acc": 0.7908353060534326,
|
| 69 |
+
"val_referable_acc": 0.9201330176981175,
|
| 70 |
+
"val_any_dr_acc": 0.8696877465900124,
|
| 71 |
+
"val_severe_or_pdr_acc": 0.9524856273249915,
|
| 72 |
+
"val_qwk": 0.7572223845133317,
|
| 73 |
+
"val_referable_auc": 0.9399529114467903,
|
| 74 |
+
"val_any_dr_auc": 0.913509437130183,
|
| 75 |
+
"val_severe_or_pdr_auc": 0.9651894407755202
|
| 76 |
+
},
|
| 77 |
+
{
|
| 78 |
+
"epoch": 6,
|
| 79 |
+
"lr": 9.336825748732972e-05,
|
| 80 |
+
"train_loss": 0.8704525511249745,
|
| 81 |
+
"train_acc": 0.7721865133062698,
|
| 82 |
+
"val_loss": 0.8010236610219734,
|
| 83 |
+
"val_acc": 0.7685153872167737,
|
| 84 |
+
"val_referable_acc": 0.8974185548416188,
|
| 85 |
+
"val_any_dr_acc": 0.8616841393304024,
|
| 86 |
+
"val_severe_or_pdr_acc": 0.9301093450569271,
|
| 87 |
+
"val_qwk": 0.7133115474233512,
|
| 88 |
+
"val_referable_auc": 0.9472766142977672,
|
| 89 |
+
"val_any_dr_auc": 0.9200055280370211,
|
| 90 |
+
"val_severe_or_pdr_auc": 0.9665115217625493
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"epoch": 7,
|
| 94 |
+
"lr": 9.05463412215599e-05,
|
| 95 |
+
"train_loss": 0.8321962211924627,
|
| 96 |
+
"train_acc": 0.775625845737483,
|
| 97 |
+
"val_loss": 0.7558084888464165,
|
| 98 |
+
"val_acc": 0.7736444594746928,
|
| 99 |
+
"val_referable_acc": 0.9060985232780971,
|
| 100 |
+
"val_any_dr_acc": 0.8678841167850299,
|
| 101 |
+
"val_severe_or_pdr_acc": 0.9163566677939353,
|
| 102 |
+
"val_qwk": 0.6786061720857763,
|
| 103 |
+
"val_referable_auc": 0.9403188664966133,
|
| 104 |
+
"val_any_dr_auc": 0.9191492215314945,
|
| 105 |
+
"val_severe_or_pdr_auc": 0.9615996734543758
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"epoch": 8,
|
| 109 |
+
"lr": 8.728566886113101e-05,
|
| 110 |
+
"train_loss": 0.8177962298792765,
|
| 111 |
+
"train_acc": 0.7858451736580965,
|
| 112 |
+
"val_loss": 0.6457110616779425,
|
| 113 |
+
"val_acc": 0.8106188704768347,
|
| 114 |
+
"val_referable_acc": 0.9237402773080825,
|
| 115 |
+
"val_any_dr_acc": 0.8930222071919739,
|
| 116 |
+
"val_severe_or_pdr_acc": 0.9468492841844212,
|
| 117 |
+
"val_qwk": 0.7714119068915228,
|
| 118 |
+
"val_referable_auc": 0.9457900718012293,
|
| 119 |
+
"val_any_dr_auc": 0.9203518908286116,
|
| 120 |
+
"val_severe_or_pdr_auc": 0.9663216986230594
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"epoch": 9,
|
| 124 |
+
"lr": 8.362196501476347e-05,
|
| 125 |
+
"train_loss": 0.7908911250588805,
|
| 126 |
+
"train_acc": 0.7856619305367614,
|
| 127 |
+
"val_loss": 0.6637757030902459,
|
| 128 |
+
"val_acc": 0.8100552361627776,
|
| 129 |
+
"val_referable_acc": 0.9274039003494533,
|
| 130 |
+
"val_any_dr_acc": 0.8876113177770263,
|
| 131 |
+
"val_severe_or_pdr_acc": 0.956205613797768,
|
| 132 |
+
"val_qwk": 0.8006692611738406,
|
| 133 |
+
"val_referable_auc": 0.9488354745793148,
|
| 134 |
+
"val_any_dr_auc": 0.9206744634585085,
|
| 135 |
+
"val_severe_or_pdr_auc": 0.9689028630191081
|
| 136 |
+
},
|
| 137 |
+
{
|
| 138 |
+
"epoch": 10,
|
| 139 |
+
"lr": 7.959536998847741e-05,
|
| 140 |
+
"train_loss": 0.7643525296428153,
|
| 141 |
+
"train_acc": 0.7932876635092467,
|
| 142 |
+
"val_loss": 0.6757383593818459,
|
| 143 |
+
"val_acc": 0.7982752789989854,
|
| 144 |
+
"val_referable_acc": 0.9256566339758765,
|
| 145 |
+
"val_any_dr_acc": 0.8783677150264908,
|
| 146 |
+
"val_severe_or_pdr_acc": 0.948596550557998,
|
| 147 |
+
"val_qwk": 0.7795822369761995,
|
| 148 |
+
"val_referable_auc": 0.952180940819946,
|
| 149 |
+
"val_any_dr_auc": 0.9246441342557743,
|
| 150 |
+
"val_severe_or_pdr_auc": 0.9664718510288837
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"epoch": 11,
|
| 154 |
+
"lr": 7.524999999999999e-05,
|
| 155 |
+
"train_loss": 0.7334291298928753,
|
| 156 |
+
"train_acc": 0.7942320703653586,
|
| 157 |
+
"val_loss": 0.6057324167330496,
|
| 158 |
+
"val_acc": 0.8163115770488107,
|
| 159 |
+
"val_referable_acc": 0.9269529928982077,
|
| 160 |
+
"val_any_dr_acc": 0.891274940818397,
|
| 161 |
+
"val_severe_or_pdr_acc": 0.9563747040919851,
|
| 162 |
+
"val_qwk": 0.7900845705555817,
|
| 163 |
+
"val_referable_auc": 0.9473444224703329,
|
| 164 |
+
"val_any_dr_auc": 0.9199220043277607,
|
| 165 |
+
"val_severe_or_pdr_auc": 0.9659417503784572
|
| 166 |
+
},
|
| 167 |
+
{
|
| 168 |
+
"epoch": 12,
|
| 169 |
+
"lr": 7.06334638322521e-05,
|
| 170 |
+
"train_loss": 0.6972404156026402,
|
| 171 |
+
"train_acc": 0.7989118177717637,
|
| 172 |
+
"val_loss": 0.7115337061594444,
|
| 173 |
+
"val_acc": 0.778942622026829,
|
| 174 |
+
"val_referable_acc": 0.914891218577387,
|
| 175 |
+
"val_any_dr_acc": 0.857569608837786,
|
| 176 |
+
"val_severe_or_pdr_acc": 0.9541765302671626,
|
| 177 |
+
"val_qwk": 0.773439823813228,
|
| 178 |
+
"val_referable_auc": 0.9498813971927252,
|
| 179 |
+
"val_any_dr_auc": 0.9262803122554194,
|
| 180 |
+
"val_severe_or_pdr_auc": 0.9691176738138658
|
| 181 |
+
},
|
| 182 |
+
{
|
| 183 |
+
"epoch": 13,
|
| 184 |
+
"lr": 6.579634122155988e-05,
|
| 185 |
+
"train_loss": 0.6745618633862063,
|
| 186 |
+
"train_acc": 0.8047615020297699,
|
| 187 |
+
"val_loss": 0.6478154543972434,
|
| 188 |
+
"val_acc": 0.803686168413933,
|
| 189 |
+
"val_referable_acc": 0.9209221057377973,
|
| 190 |
+
"val_any_dr_acc": 0.8797768008116335,
|
| 191 |
+
"val_severe_or_pdr_acc": 0.9530492616390486,
|
| 192 |
+
"val_qwk": 0.7809586848122757,
|
| 193 |
+
"val_referable_auc": 0.9476525109932052,
|
| 194 |
+
"val_any_dr_auc": 0.9234389081104144,
|
| 195 |
+
"val_severe_or_pdr_auc": 0.9665842954775892
|
| 196 |
+
},
|
| 197 |
+
{
|
| 198 |
+
"epoch": 14,
|
| 199 |
+
"lr": 6.079162869547907e-05,
|
| 200 |
+
"train_loss": 0.6390304281857296,
|
| 201 |
+
"train_acc": 0.8057481957600361,
|
| 202 |
+
"val_loss": 0.6064365419026172,
|
| 203 |
+
"val_acc": 0.8143388569496111,
|
| 204 |
+
"val_referable_acc": 0.9259948145643107,
|
| 205 |
+
"val_any_dr_acc": 0.8916131214068312,
|
| 206 |
+
"val_severe_or_pdr_acc": 0.9585165144854019,
|
| 207 |
+
"val_qwk": 0.8013380815188119,
|
| 208 |
+
"val_referable_auc": 0.9495913061231518,
|
| 209 |
+
"val_any_dr_auc": 0.9251410560727309,
|
| 210 |
+
"val_severe_or_pdr_auc": 0.9679007523548978
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"epoch": 15,
|
| 214 |
+
"lr": 5.567415893174884e-05,
|
| 215 |
+
"train_loss": 0.6031589889693055,
|
| 216 |
+
"train_acc": 0.8134444068561119,
|
| 217 |
+
"val_loss": 0.6843524756311712,
|
| 218 |
+
"val_acc": 0.7870589561492504,
|
| 219 |
+
"val_referable_acc": 0.9243602750535452,
|
| 220 |
+
"val_any_dr_acc": 0.8676586630594071,
|
| 221 |
+
"val_severe_or_pdr_acc": 0.9522038101679631,
|
| 222 |
+
"val_qwk": 0.7926764678375114,
|
| 223 |
+
"val_referable_auc": 0.9519691120245126,
|
| 224 |
+
"val_any_dr_auc": 0.9264247004258922,
|
| 225 |
+
"val_severe_or_pdr_auc": 0.9699912226142658
|
| 226 |
+
},
|
| 227 |
+
{
|
| 228 |
+
"epoch": 16,
|
| 229 |
+
"lr": 5.05e-05,
|
| 230 |
+
"train_loss": 0.5689867827125535,
|
| 231 |
+
"train_acc": 0.8199988723500226,
|
| 232 |
+
"val_loss": 0.6491324536064783,
|
| 233 |
+
"val_acc": 0.8049825273362642,
|
| 234 |
+
"val_referable_acc": 0.9251493630932252,
|
| 235 |
+
"val_any_dr_acc": 0.8824258820877015,
|
| 236 |
+
"val_severe_or_pdr_acc": 0.9555856160523053,
|
| 237 |
+
"val_qwk": 0.7875070071285253,
|
| 238 |
+
"val_referable_auc": 0.945414267347864,
|
| 239 |
+
"val_any_dr_auc": 0.9243323626706975,
|
| 240 |
+
"val_severe_or_pdr_auc": 0.9674251942450486
|
| 241 |
+
},
|
| 242 |
+
{
|
| 243 |
+
"epoch": 17,
|
| 244 |
+
"lr": 4.532584106825115e-05,
|
| 245 |
+
"train_loss": 0.5425662958560142,
|
| 246 |
+
"train_acc": 0.820872801082544,
|
| 247 |
+
"val_loss": 0.6018754473910796,
|
| 248 |
+
"val_acc": 0.8186224777364446,
|
| 249 |
+
"val_referable_acc": 0.9275166272122647,
|
| 250 |
+
"val_any_dr_acc": 0.8925712997407282,
|
| 251 |
+
"val_severe_or_pdr_acc": 0.9621801375267727,
|
| 252 |
+
"val_qwk": 0.8065342569653287,
|
| 253 |
+
"val_referable_auc": 0.9471525794573215,
|
| 254 |
+
"val_any_dr_auc": 0.9243262164008834,
|
| 255 |
+
"val_severe_or_pdr_auc": 0.9677116841294643
|
| 256 |
+
},
|
| 257 |
+
{
|
| 258 |
+
"epoch": 18,
|
| 259 |
+
"lr": 4.0208371304520894e-05,
|
| 260 |
+
"train_loss": 0.5011885827445048,
|
| 261 |
+
"train_acc": 0.83247350022553,
|
| 262 |
+
"val_loss": 0.6446213349053266,
|
| 263 |
+
"val_acc": 0.809040694397475,
|
| 264 |
+
"val_referable_acc": 0.9258820877014993,
|
| 265 |
+
"val_any_dr_acc": 0.8854695073836095,
|
| 266 |
+
"val_severe_or_pdr_acc": 0.962123774095367,
|
| 267 |
+
"val_qwk": 0.8019418515785007,
|
| 268 |
+
"val_referable_auc": 0.9391693765337806,
|
| 269 |
+
"val_any_dr_auc": 0.9214470823542462,
|
| 270 |
+
"val_severe_or_pdr_auc": 0.9675130662412171
|
| 271 |
+
},
|
| 272 |
+
{
|
| 273 |
+
"epoch": 19,
|
| 274 |
+
"lr": 3.520365877844009e-05,
|
| 275 |
+
"train_loss": 0.47397731046285185,
|
| 276 |
+
"train_acc": 0.8359974064050518,
|
| 277 |
+
"val_loss": 0.6219859553383217,
|
| 278 |
+
"val_acc": 0.8104497801826175,
|
| 279 |
+
"val_referable_acc": 0.9272911734866419,
|
| 280 |
+
"val_any_dr_acc": 0.8833840604215984,
|
| 281 |
+
"val_severe_or_pdr_acc": 0.9569383384060421,
|
| 282 |
+
"val_qwk": 0.7980956613043054,
|
| 283 |
+
"val_referable_auc": 0.9491089108302032,
|
| 284 |
+
"val_any_dr_auc": 0.9246982460152176,
|
| 285 |
+
"val_severe_or_pdr_auc": 0.9674015654350823
|
| 286 |
+
}
|
| 287 |
+
]
|
runs/eyepacs_dr/inception_v3_fold2/best_model_only.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7e11288258bff638027be0a4956da8992931c25ccdac7b635fb542be6eb0c05f
|
| 3 |
+
size 89735243
|
runs/eyepacs_dr/inception_v3_fold2/history.json
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"epoch": 1,
|
| 4 |
+
"lr": 0.0001,
|
| 5 |
+
"train_loss": 1.2143506749987225,
|
| 6 |
+
"train_acc": 0.5614710193955796,
|
| 7 |
+
"val_loss": 0.6948825628539755,
|
| 8 |
+
"val_acc": 0.7953776775648252,
|
| 9 |
+
"val_referable_acc": 0.9081172491544532,
|
| 10 |
+
"val_any_dr_acc": 0.8778466741826381,
|
| 11 |
+
"val_severe_or_pdr_acc": 0.9413190529875987,
|
| 12 |
+
"val_qwk": 0.7155456574787837,
|
| 13 |
+
"val_referable_auc": 0.9247314923272769,
|
| 14 |
+
"val_any_dr_auc": 0.8790872092642767,
|
| 15 |
+
"val_severe_or_pdr_auc": 0.9670086693426698
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"epoch": 2,
|
| 19 |
+
"lr": 9.972883382072954e-05,
|
| 20 |
+
"train_loss": 1.0420125438304544,
|
| 21 |
+
"train_acc": 0.6888390843482183,
|
| 22 |
+
"val_loss": 0.8327976735630057,
|
| 23 |
+
"val_acc": 0.6973506200676437,
|
| 24 |
+
"val_referable_acc": 0.9091319052987599,
|
| 25 |
+
"val_any_dr_acc": 0.7968996617812852,
|
| 26 |
+
"val_severe_or_pdr_acc": 0.9479143179255919,
|
| 27 |
+
"val_qwk": 0.7231192710199451,
|
| 28 |
+
"val_referable_auc": 0.9336409757639126,
|
| 29 |
+
"val_any_dr_auc": 0.8999365600581144,
|
| 30 |
+
"val_severe_or_pdr_auc": 0.9717771882818815
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"epoch": 3,
|
| 34 |
+
"lr": 9.891830623632339e-05,
|
| 35 |
+
"train_loss": 0.985259113020869,
|
| 36 |
+
"train_acc": 0.7269959404600812,
|
| 37 |
+
"val_loss": 0.7072824161512339,
|
| 38 |
+
"val_acc": 0.7739571589627959,
|
| 39 |
+
"val_referable_acc": 0.9163472378804961,
|
| 40 |
+
"val_any_dr_acc": 0.86967305524239,
|
| 41 |
+
"val_severe_or_pdr_acc": 0.9385569334836528,
|
| 42 |
+
"val_qwk": 0.7451868136032376,
|
| 43 |
+
"val_referable_auc": 0.9428887353837985,
|
| 44 |
+
"val_any_dr_auc": 0.9123166499784034,
|
| 45 |
+
"val_severe_or_pdr_auc": 0.9740952162696138
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"epoch": 4,
|
| 49 |
+
"lr": 9.757729755661011e-05,
|
| 50 |
+
"train_loss": 0.9373754202970042,
|
| 51 |
+
"train_acc": 0.7481111862877763,
|
| 52 |
+
"val_loss": 0.7193142563944604,
|
| 53 |
+
"val_acc": 0.7816234498308906,
|
| 54 |
+
"val_referable_acc": 0.918489289740699,
|
| 55 |
+
"val_any_dr_acc": 0.8700112739571589,
|
| 56 |
+
"val_severe_or_pdr_acc": 0.9522547914317926,
|
| 57 |
+
"val_qwk": 0.7620895041226018,
|
| 58 |
+
"val_referable_auc": 0.9451858199028286,
|
| 59 |
+
"val_any_dr_auc": 0.9131514312639888,
|
| 60 |
+
"val_severe_or_pdr_auc": 0.9744336137071168
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"epoch": 5,
|
| 64 |
+
"lr": 9.572050015330873e-05,
|
| 65 |
+
"train_loss": 0.9043582667893636,
|
| 66 |
+
"train_acc": 0.7615584122688318,
|
| 67 |
+
"val_loss": 0.6663910818341888,
|
| 68 |
+
"val_acc": 0.8056369785794814,
|
| 69 |
+
"val_referable_acc": 0.9179255918827508,
|
| 70 |
+
"val_any_dr_acc": 0.8842164599774521,
|
| 71 |
+
"val_severe_or_pdr_acc": 0.9594137542277339,
|
| 72 |
+
"val_qwk": 0.7709031226321263,
|
| 73 |
+
"val_referable_auc": 0.9445627977133615,
|
| 74 |
+
"val_any_dr_auc": 0.9151006204107276,
|
| 75 |
+
"val_severe_or_pdr_auc": 0.9724197038400002
|
| 76 |
+
},
|
| 77 |
+
{
|
| 78 |
+
"epoch": 6,
|
| 79 |
+
"lr": 9.336825748732972e-05,
|
| 80 |
+
"train_loss": 0.8722681901478585,
|
| 81 |
+
"train_acc": 0.7702554127198917,
|
| 82 |
+
"val_loss": 0.7913296779489571,
|
| 83 |
+
"val_acc": 0.7606538895152198,
|
| 84 |
+
"val_referable_acc": 0.9029312288613304,
|
| 85 |
+
"val_any_dr_acc": 0.8507891770011274,
|
| 86 |
+
"val_severe_or_pdr_acc": 0.9457158962795942,
|
| 87 |
+
"val_qwk": 0.7080191690735049,
|
| 88 |
+
"val_referable_auc": 0.9269965806304334,
|
| 89 |
+
"val_any_dr_auc": 0.9172570957840867,
|
| 90 |
+
"val_severe_or_pdr_auc": 0.9683691666705453
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"epoch": 7,
|
| 94 |
+
"lr": 9.05463412215599e-05,
|
| 95 |
+
"train_loss": 0.8582366131410762,
|
| 96 |
+
"train_acc": 0.7776133288227334,
|
| 97 |
+
"val_loss": 0.6967431294608949,
|
| 98 |
+
"val_acc": 0.7959413754227734,
|
| 99 |
+
"val_referable_acc": 0.9282412626832018,
|
| 100 |
+
"val_any_dr_acc": 0.8834836527621195,
|
| 101 |
+
"val_severe_or_pdr_acc": 0.9430665163472379,
|
| 102 |
+
"val_qwk": 0.7790565442854828,
|
| 103 |
+
"val_referable_auc": 0.9510393498401439,
|
| 104 |
+
"val_any_dr_auc": 0.91728786272431,
|
| 105 |
+
"val_severe_or_pdr_auc": 0.9742298955685044
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"epoch": 8,
|
| 109 |
+
"lr": 8.728566886113101e-05,
|
| 110 |
+
"train_loss": 0.8172618988388877,
|
| 111 |
+
"train_acc": 0.7812077131258457,
|
| 112 |
+
"val_loss": 0.7357572990044398,
|
| 113 |
+
"val_acc": 0.7737880496054115,
|
| 114 |
+
"val_referable_acc": 0.922435174746336,
|
| 115 |
+
"val_any_dr_acc": 0.8633596392333709,
|
| 116 |
+
"val_severe_or_pdr_acc": 0.9395152198421646,
|
| 117 |
+
"val_qwk": 0.7589173021521816,
|
| 118 |
+
"val_referable_auc": 0.9514882719851434,
|
| 119 |
+
"val_any_dr_auc": 0.9188145524927684,
|
| 120 |
+
"val_severe_or_pdr_auc": 0.9749677874156344
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"epoch": 9,
|
| 124 |
+
"lr": 8.362196501476347e-05,
|
| 125 |
+
"train_loss": 0.7983663257616406,
|
| 126 |
+
"train_acc": 0.785281348669373,
|
| 127 |
+
"val_loss": 0.6312644582321572,
|
| 128 |
+
"val_acc": 0.8122886133032694,
|
| 129 |
+
"val_referable_acc": 0.9180947012401353,
|
| 130 |
+
"val_any_dr_acc": 0.8882750845546787,
|
| 131 |
+
"val_severe_or_pdr_acc": 0.9629650507328072,
|
| 132 |
+
"val_qwk": 0.7852212513783992,
|
| 133 |
+
"val_referable_auc": 0.9459528860088998,
|
| 134 |
+
"val_any_dr_auc": 0.9226028127904086,
|
| 135 |
+
"val_severe_or_pdr_auc": 0.9741718275877431
|
| 136 |
+
},
|
| 137 |
+
{
|
| 138 |
+
"epoch": 10,
|
| 139 |
+
"lr": 7.959536998847741e-05,
|
| 140 |
+
"train_loss": 0.7734421917216757,
|
| 141 |
+
"train_acc": 0.7890025935949482,
|
| 142 |
+
"val_loss": 0.652807928448734,
|
| 143 |
+
"val_acc": 0.7968996617812852,
|
| 144 |
+
"val_referable_acc": 0.9205186020293122,
|
| 145 |
+
"val_any_dr_acc": 0.8818489289740699,
|
| 146 |
+
"val_severe_or_pdr_acc": 0.9560315670800451,
|
| 147 |
+
"val_qwk": 0.7862390587287141,
|
| 148 |
+
"val_referable_auc": 0.9485443458714957,
|
| 149 |
+
"val_any_dr_auc": 0.9240858103951519,
|
| 150 |
+
"val_severe_or_pdr_auc": 0.9748014514631099
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"epoch": 11,
|
| 154 |
+
"lr": 7.524999999999999e-05,
|
| 155 |
+
"train_loss": 0.7356365497552118,
|
| 156 |
+
"train_acc": 0.7935413847541724,
|
| 157 |
+
"val_loss": 0.6950417665376201,
|
| 158 |
+
"val_acc": 0.8027057497181511,
|
| 159 |
+
"val_referable_acc": 0.9224915445321308,
|
| 160 |
+
"val_any_dr_acc": 0.8719278466741827,
|
| 161 |
+
"val_severe_or_pdr_acc": 0.9626268320180383,
|
| 162 |
+
"val_qwk": 0.7840566914760235,
|
| 163 |
+
"val_referable_auc": 0.9528219758380423,
|
| 164 |
+
"val_any_dr_auc": 0.9236595806992055,
|
| 165 |
+
"val_severe_or_pdr_auc": 0.9734454237444407
|
| 166 |
+
},
|
| 167 |
+
{
|
| 168 |
+
"epoch": 12,
|
| 169 |
+
"lr": 7.06334638322521e-05,
|
| 170 |
+
"train_loss": 0.703734042397694,
|
| 171 |
+
"train_acc": 0.7984607577807848,
|
| 172 |
+
"val_loss": 0.7197710200657033,
|
| 173 |
+
"val_acc": 0.7735625704622322,
|
| 174 |
+
"val_referable_acc": 0.921815107102593,
|
| 175 |
+
"val_any_dr_acc": 0.8545095828635851,
|
| 176 |
+
"val_severe_or_pdr_acc": 0.9510710259301015,
|
| 177 |
+
"val_qwk": 0.7837397715419365,
|
| 178 |
+
"val_referable_auc": 0.9540776393967962,
|
| 179 |
+
"val_any_dr_auc": 0.9251081219486657,
|
| 180 |
+
"val_severe_or_pdr_auc": 0.9740435387218498
|
| 181 |
+
},
|
| 182 |
+
{
|
| 183 |
+
"epoch": 13,
|
| 184 |
+
"lr": 6.579634122155988e-05,
|
| 185 |
+
"train_loss": 0.6775929662401095,
|
| 186 |
+
"train_acc": 0.7984607577807848,
|
| 187 |
+
"val_loss": 0.7374675619427489,
|
| 188 |
+
"val_acc": 0.7498872604284104,
|
| 189 |
+
"val_referable_acc": 0.9068771138669673,
|
| 190 |
+
"val_any_dr_acc": 0.8481397970687712,
|
| 191 |
+
"val_severe_or_pdr_acc": 0.9284667418263811,
|
| 192 |
+
"val_qwk": 0.7465711006115658,
|
| 193 |
+
"val_referable_auc": 0.9518734454790881,
|
| 194 |
+
"val_any_dr_auc": 0.9208624478082748,
|
| 195 |
+
"val_severe_or_pdr_auc": 0.9757295048655574
|
| 196 |
+
},
|
| 197 |
+
{
|
| 198 |
+
"epoch": 14,
|
| 199 |
+
"lr": 6.079162869547907e-05,
|
| 200 |
+
"train_loss": 0.63867224941772,
|
| 201 |
+
"train_acc": 0.8038875732972486,
|
| 202 |
+
"val_loss": 0.638574194605751,
|
| 203 |
+
"val_acc": 0.7966178128523111,
|
| 204 |
+
"val_referable_acc": 0.9206877113866967,
|
| 205 |
+
"val_any_dr_acc": 0.8729988726042841,
|
| 206 |
+
"val_severe_or_pdr_acc": 0.9561443066516347,
|
| 207 |
+
"val_qwk": 0.7783495078517592,
|
| 208 |
+
"val_referable_auc": 0.9506779043335899,
|
| 209 |
+
"val_any_dr_auc": 0.9251737460897108,
|
| 210 |
+
"val_severe_or_pdr_auc": 0.9743007813541793
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"epoch": 15,
|
| 214 |
+
"lr": 5.567415893174884e-05,
|
| 215 |
+
"train_loss": 0.6125179093547861,
|
| 216 |
+
"train_acc": 0.8125563824988723,
|
| 217 |
+
"val_loss": 0.6638782870137839,
|
| 218 |
+
"val_acc": 0.7777339346110484,
|
| 219 |
+
"val_referable_acc": 0.9192784667418263,
|
| 220 |
+
"val_any_dr_acc": 0.8587373167981962,
|
| 221 |
+
"val_severe_or_pdr_acc": 0.951803833145434,
|
| 222 |
+
"val_qwk": 0.7777181287118557,
|
| 223 |
+
"val_referable_auc": 0.9527175361264195,
|
| 224 |
+
"val_any_dr_auc": 0.9251897062865668,
|
| 225 |
+
"val_severe_or_pdr_auc": 0.9756308410127499
|
| 226 |
+
},
|
| 227 |
+
{
|
| 228 |
+
"epoch": 16,
|
| 229 |
+
"lr": 5.05e-05,
|
| 230 |
+
"train_loss": 0.5682916087197138,
|
| 231 |
+
"train_acc": 0.8178845286423094,
|
| 232 |
+
"val_loss": 0.6209135725103075,
|
| 233 |
+
"val_acc": 0.8029312288613303,
|
| 234 |
+
"val_referable_acc": 0.9244644870349493,
|
| 235 |
+
"val_any_dr_acc": 0.8774520856820744,
|
| 236 |
+
"val_severe_or_pdr_acc": 0.9574971815107103,
|
| 237 |
+
"val_qwk": 0.7954055446182169,
|
| 238 |
+
"val_referable_auc": 0.9493490659370094,
|
| 239 |
+
"val_any_dr_auc": 0.9210591320794231,
|
| 240 |
+
"val_severe_or_pdr_auc": 0.9754178512054537
|
| 241 |
+
},
|
| 242 |
+
{
|
| 243 |
+
"epoch": 17,
|
| 244 |
+
"lr": 4.532584106825115e-05,
|
| 245 |
+
"train_loss": 0.5481052464214488,
|
| 246 |
+
"train_acc": 0.8168978349120433,
|
| 247 |
+
"val_loss": 0.635486727247378,
|
| 248 |
+
"val_acc": 0.7961668545659526,
|
| 249 |
+
"val_referable_acc": 0.9253664036076663,
|
| 250 |
+
"val_any_dr_acc": 0.867869222096956,
|
| 251 |
+
"val_severe_or_pdr_acc": 0.9629650507328072,
|
| 252 |
+
"val_qwk": 0.7962354701827697,
|
| 253 |
+
"val_referable_auc": 0.9528051854428554,
|
| 254 |
+
"val_any_dr_auc": 0.9221625944032146,
|
| 255 |
+
"val_severe_or_pdr_auc": 0.9746945132924331
|
| 256 |
+
}
|
| 257 |
+
]
|
runs/eyepacs_dr/inception_v3_fold3/best_model_only.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:859c08cfee33d0876f0715e6243007351c59318e48cf1ee05e03073b1b8dd28b
|
| 3 |
+
size 89735243
|
runs/eyepacs_dr/inception_v3_fold3/history.json
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"epoch": 1,
|
| 4 |
+
"lr": 0.0001,
|
| 5 |
+
"train_loss": 1.2025198198192872,
|
| 6 |
+
"train_acc": 0.5520410464591791,
|
| 7 |
+
"val_loss": 0.8228783474162036,
|
| 8 |
+
"val_acc": 0.7453776775648252,
|
| 9 |
+
"val_referable_acc": 0.8989289740698986,
|
| 10 |
+
"val_any_dr_acc": 0.8471251409244644,
|
| 11 |
+
"val_severe_or_pdr_acc": 0.9259301014656144,
|
| 12 |
+
"val_qwk": 0.6898827561312655,
|
| 13 |
+
"val_referable_auc": 0.9175911681283208,
|
| 14 |
+
"val_any_dr_auc": 0.8747995817301016,
|
| 15 |
+
"val_severe_or_pdr_auc": 0.9673576416115902
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"epoch": 2,
|
| 19 |
+
"lr": 9.972883382072954e-05,
|
| 20 |
+
"train_loss": 1.0339324369347735,
|
| 21 |
+
"train_acc": 0.6820308976093821,
|
| 22 |
+
"val_loss": 0.8109341154641471,
|
| 23 |
+
"val_acc": 0.7558624577226607,
|
| 24 |
+
"val_referable_acc": 0.9067080045095829,
|
| 25 |
+
"val_any_dr_acc": 0.8419954904171364,
|
| 26 |
+
"val_severe_or_pdr_acc": 0.9482525366403608,
|
| 27 |
+
"val_qwk": 0.7271704083716478,
|
| 28 |
+
"val_referable_auc": 0.9356385507586122,
|
| 29 |
+
"val_any_dr_auc": 0.9036777524528425,
|
| 30 |
+
"val_severe_or_pdr_auc": 0.9724214181695979
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"epoch": 3,
|
| 34 |
+
"lr": 9.891830623632339e-05,
|
| 35 |
+
"train_loss": 0.9782092773704633,
|
| 36 |
+
"train_acc": 0.7262629679747407,
|
| 37 |
+
"val_loss": 0.7510695437567881,
|
| 38 |
+
"val_acc": 0.7797632468996618,
|
| 39 |
+
"val_referable_acc": 0.9089627959413754,
|
| 40 |
+
"val_any_dr_acc": 0.8714205186020293,
|
| 41 |
+
"val_severe_or_pdr_acc": 0.947576099210823,
|
| 42 |
+
"val_qwk": 0.7372795022381535,
|
| 43 |
+
"val_referable_auc": 0.9319354956337893,
|
| 44 |
+
"val_any_dr_auc": 0.9054813371565816,
|
| 45 |
+
"val_severe_or_pdr_auc": 0.9716824987864531
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"epoch": 4,
|
| 49 |
+
"lr": 9.757729755661011e-05,
|
| 50 |
+
"train_loss": 0.9379007722753956,
|
| 51 |
+
"train_acc": 0.7525090211998195,
|
| 52 |
+
"val_loss": 0.6549568566085252,
|
| 53 |
+
"val_acc": 0.8064825253664036,
|
| 54 |
+
"val_referable_acc": 0.9164599774520856,
|
| 55 |
+
"val_any_dr_acc": 0.8899661781285231,
|
| 56 |
+
"val_severe_or_pdr_acc": 0.9606538895152198,
|
| 57 |
+
"val_qwk": 0.7948299036997162,
|
| 58 |
+
"val_referable_auc": 0.9453975533926049,
|
| 59 |
+
"val_any_dr_auc": 0.9143007050135201,
|
| 60 |
+
"val_severe_or_pdr_auc": 0.9740853216832828
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"epoch": 5,
|
| 64 |
+
"lr": 9.572050015330873e-05,
|
| 65 |
+
"train_loss": 0.8938556916954606,
|
| 66 |
+
"train_acc": 0.7624464366260713,
|
| 67 |
+
"val_loss": 0.7379223013004832,
|
| 68 |
+
"val_acc": 0.7736753100338218,
|
| 69 |
+
"val_referable_acc": 0.9153325817361894,
|
| 70 |
+
"val_any_dr_acc": 0.8563697857948139,
|
| 71 |
+
"val_severe_or_pdr_acc": 0.9559188275084555,
|
| 72 |
+
"val_qwk": 0.7567080724224234,
|
| 73 |
+
"val_referable_auc": 0.936530104661968,
|
| 74 |
+
"val_any_dr_auc": 0.9078175951114706,
|
| 75 |
+
"val_severe_or_pdr_auc": 0.9719054927000486
|
| 76 |
+
},
|
| 77 |
+
{
|
| 78 |
+
"epoch": 6,
|
| 79 |
+
"lr": 9.336825748732972e-05,
|
| 80 |
+
"train_loss": 0.871171380775062,
|
| 81 |
+
"train_acc": 0.7707064727108706,
|
| 82 |
+
"val_loss": 0.7070721405737833,
|
| 83 |
+
"val_acc": 0.7897406989853438,
|
| 84 |
+
"val_referable_acc": 0.9234498308906426,
|
| 85 |
+
"val_any_dr_acc": 0.8689966178128523,
|
| 86 |
+
"val_severe_or_pdr_acc": 0.9564261555806088,
|
| 87 |
+
"val_qwk": 0.7851643398048448,
|
| 88 |
+
"val_referable_auc": 0.947155445348272,
|
| 89 |
+
"val_any_dr_auc": 0.9142982950600038,
|
| 90 |
+
"val_severe_or_pdr_auc": 0.9759564243306822
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"epoch": 7,
|
| 94 |
+
"lr": 9.05463412215599e-05,
|
| 95 |
+
"train_loss": 0.8448774115319826,
|
| 96 |
+
"train_acc": 0.7775851375732973,
|
| 97 |
+
"val_loss": 0.679549956227639,
|
| 98 |
+
"val_acc": 0.8164036076662908,
|
| 99 |
+
"val_referable_acc": 0.924520856820744,
|
| 100 |
+
"val_any_dr_acc": 0.8813416009019166,
|
| 101 |
+
"val_severe_or_pdr_acc": 0.9644870349492672,
|
| 102 |
+
"val_qwk": 0.7821747923185505,
|
| 103 |
+
"val_referable_auc": 0.9481949654990761,
|
| 104 |
+
"val_any_dr_auc": 0.9170575366190394,
|
| 105 |
+
"val_severe_or_pdr_auc": 0.9746656584892275
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"epoch": 8,
|
| 109 |
+
"lr": 8.728566886113101e-05,
|
| 110 |
+
"train_loss": 0.8195717033094579,
|
| 111 |
+
"train_acc": 0.7809680875056383,
|
| 112 |
+
"val_loss": 0.6137274920604409,
|
| 113 |
+
"val_acc": 0.809413754227734,
|
| 114 |
+
"val_referable_acc": 0.9208004509582863,
|
| 115 |
+
"val_any_dr_acc": 0.8852311161217588,
|
| 116 |
+
"val_severe_or_pdr_acc": 0.9581172491544532,
|
| 117 |
+
"val_qwk": 0.7956730170227315,
|
| 118 |
+
"val_referable_auc": 0.9454241231831684,
|
| 119 |
+
"val_any_dr_auc": 0.9121724219624374,
|
| 120 |
+
"val_severe_or_pdr_auc": 0.9762521190396176
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"epoch": 9,
|
| 124 |
+
"lr": 8.362196501476347e-05,
|
| 125 |
+
"train_loss": 0.7902204092351713,
|
| 126 |
+
"train_acc": 0.783026048714479,
|
| 127 |
+
"val_loss": 0.734050494479488,
|
| 128 |
+
"val_acc": 0.7920518602029313,
|
| 129 |
+
"val_referable_acc": 0.9162908680947013,
|
| 130 |
+
"val_any_dr_acc": 0.8687147688838782,
|
| 131 |
+
"val_severe_or_pdr_acc": 0.9494926719278467,
|
| 132 |
+
"val_qwk": 0.7573945822492804,
|
| 133 |
+
"val_referable_auc": 0.9479569164636216,
|
| 134 |
+
"val_any_dr_auc": 0.9187071783937456,
|
| 135 |
+
"val_severe_or_pdr_auc": 0.9708768529927934
|
| 136 |
+
},
|
| 137 |
+
{
|
| 138 |
+
"epoch": 10,
|
| 139 |
+
"lr": 7.959536998847741e-05,
|
| 140 |
+
"train_loss": 0.7650700230210227,
|
| 141 |
+
"train_acc": 0.7899188092016238,
|
| 142 |
+
"val_loss": 0.6066389189766386,
|
| 143 |
+
"val_acc": 0.8162908680947012,
|
| 144 |
+
"val_referable_acc": 0.9243517474633597,
|
| 145 |
+
"val_any_dr_acc": 0.8935174746335964,
|
| 146 |
+
"val_severe_or_pdr_acc": 0.9520293122886133,
|
| 147 |
+
"val_qwk": 0.7954633767456802,
|
| 148 |
+
"val_referable_auc": 0.9486835951455344,
|
| 149 |
+
"val_any_dr_auc": 0.9155345767059612,
|
| 150 |
+
"val_severe_or_pdr_auc": 0.9757451178074008
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"epoch": 11,
|
| 154 |
+
"lr": 7.524999999999999e-05,
|
| 155 |
+
"train_loss": 0.7395555126368596,
|
| 156 |
+
"train_acc": 0.7941756878664863,
|
| 157 |
+
"val_loss": 0.6811727064572435,
|
| 158 |
+
"val_acc": 0.7918827508455468,
|
| 159 |
+
"val_referable_acc": 0.9159526493799324,
|
| 160 |
+
"val_any_dr_acc": 0.8719278466741827,
|
| 161 |
+
"val_severe_or_pdr_acc": 0.9613866967305524,
|
| 162 |
+
"val_qwk": 0.7880716708685575,
|
| 163 |
+
"val_referable_auc": 0.9474283812313362,
|
| 164 |
+
"val_any_dr_auc": 0.9180301775196268,
|
| 165 |
+
"val_severe_or_pdr_auc": 0.9750599305477764
|
| 166 |
+
},
|
| 167 |
+
{
|
| 168 |
+
"epoch": 12,
|
| 169 |
+
"lr": 7.06334638322521e-05,
|
| 170 |
+
"train_loss": 0.7014671185355924,
|
| 171 |
+
"train_acc": 0.8014208389715832,
|
| 172 |
+
"val_loss": 0.6409604030639235,
|
| 173 |
+
"val_acc": 0.8064261555806088,
|
| 174 |
+
"val_referable_acc": 0.9247463359639233,
|
| 175 |
+
"val_any_dr_acc": 0.8740698985343855,
|
| 176 |
+
"val_severe_or_pdr_acc": 0.9613303269447576,
|
| 177 |
+
"val_qwk": 0.7936155738468372,
|
| 178 |
+
"val_referable_auc": 0.9497614124427368,
|
| 179 |
+
"val_any_dr_auc": 0.9194105335392007,
|
| 180 |
+
"val_severe_or_pdr_auc": 0.9763317650573168
|
| 181 |
+
},
|
| 182 |
+
{
|
| 183 |
+
"epoch": 13,
|
| 184 |
+
"lr": 6.579634122155988e-05,
|
| 185 |
+
"train_loss": 0.6744532153702664,
|
| 186 |
+
"train_acc": 0.801547699594046,
|
| 187 |
+
"val_loss": 0.6877641824616924,
|
| 188 |
+
"val_acc": 0.788782412626832,
|
| 189 |
+
"val_referable_acc": 0.9089064261555806,
|
| 190 |
+
"val_any_dr_acc": 0.8720405862457723,
|
| 191 |
+
"val_severe_or_pdr_acc": 0.9422209695603156,
|
| 192 |
+
"val_qwk": 0.739571072166862,
|
| 193 |
+
"val_referable_auc": 0.9406614118746931,
|
| 194 |
+
"val_any_dr_auc": 0.9148891339689075,
|
| 195 |
+
"val_severe_or_pdr_auc": 0.9710664650311789
|
| 196 |
+
},
|
| 197 |
+
{
|
| 198 |
+
"epoch": 14,
|
| 199 |
+
"lr": 6.079162869547907e-05,
|
| 200 |
+
"train_loss": 0.6426656583326595,
|
| 201 |
+
"train_acc": 0.8055226657645467,
|
| 202 |
+
"val_loss": 0.6913967782104432,
|
| 203 |
+
"val_acc": 0.7749718151071026,
|
| 204 |
+
"val_referable_acc": 0.9171364148816235,
|
| 205 |
+
"val_any_dr_acc": 0.8547350620067644,
|
| 206 |
+
"val_severe_or_pdr_acc": 0.9571025930101466,
|
| 207 |
+
"val_qwk": 0.7778506643992253,
|
| 208 |
+
"val_referable_auc": 0.943374991710938,
|
| 209 |
+
"val_any_dr_auc": 0.9158870344500813,
|
| 210 |
+
"val_severe_or_pdr_auc": 0.9749824502445763
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"epoch": 15,
|
| 214 |
+
"lr": 5.567415893174884e-05,
|
| 215 |
+
"train_loss": 0.6071117940986,
|
| 216 |
+
"train_acc": 0.8086659900766802,
|
| 217 |
+
"val_loss": 0.682904385593053,
|
| 218 |
+
"val_acc": 0.7785794813979707,
|
| 219 |
+
"val_referable_acc": 0.9217587373167982,
|
| 220 |
+
"val_any_dr_acc": 0.8600901916572717,
|
| 221 |
+
"val_severe_or_pdr_acc": 0.9599774520856821,
|
| 222 |
+
"val_qwk": 0.7914131533126754,
|
| 223 |
+
"val_referable_auc": 0.9482813427683984,
|
| 224 |
+
"val_any_dr_auc": 0.9183545981096161,
|
| 225 |
+
"val_severe_or_pdr_auc": 0.9763147380605655
|
| 226 |
+
},
|
| 227 |
+
{
|
| 228 |
+
"epoch": 16,
|
| 229 |
+
"lr": 5.05e-05,
|
| 230 |
+
"train_loss": 0.5828789531055419,
|
| 231 |
+
"train_acc": 0.8125140956247181,
|
| 232 |
+
"val_loss": 0.674042572795068,
|
| 233 |
+
"val_acc": 0.7829199549041713,
|
| 234 |
+
"val_referable_acc": 0.922435174746336,
|
| 235 |
+
"val_any_dr_acc": 0.8550732807215332,
|
| 236 |
+
"val_severe_or_pdr_acc": 0.9631905298759865,
|
| 237 |
+
"val_qwk": 0.7885094124571328,
|
| 238 |
+
"val_referable_auc": 0.9481833297632086,
|
| 239 |
+
"val_any_dr_auc": 0.9190702399333383,
|
| 240 |
+
"val_severe_or_pdr_auc": 0.9758976139800606
|
| 241 |
+
},
|
| 242 |
+
{
|
| 243 |
+
"epoch": 17,
|
| 244 |
+
"lr": 4.532584106825115e-05,
|
| 245 |
+
"train_loss": 0.543698809546934,
|
| 246 |
+
"train_acc": 0.8226347541723049,
|
| 247 |
+
"val_loss": 0.5916262666832366,
|
| 248 |
+
"val_acc": 0.8156708004509583,
|
| 249 |
+
"val_referable_acc": 0.9244644870349493,
|
| 250 |
+
"val_any_dr_acc": 0.8904735062006764,
|
| 251 |
+
"val_severe_or_pdr_acc": 0.9613303269447576,
|
| 252 |
+
"val_qwk": 0.8081824267323067,
|
| 253 |
+
"val_referable_auc": 0.9482310637662554,
|
| 254 |
+
"val_any_dr_auc": 0.9186220702726107,
|
| 255 |
+
"val_severe_or_pdr_auc": 0.9764491990590344
|
| 256 |
+
}
|
| 257 |
+
]
|
runs/eyepacs_dr/inception_v3_fold4/best_model_only.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:98ff44110cf6b82ea97f53048fdb966eab3a733f5ddf8131f388236900d311ac
|
| 3 |
+
size 89735243
|
runs/eyepacs_dr/inception_v3_fold4/history.json
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"epoch": 1,
|
| 4 |
+
"lr": 0.0001,
|
| 5 |
+
"train_loss": 1.2001196421585376,
|
| 6 |
+
"train_acc": 0.5799503834009924,
|
| 7 |
+
"val_loss": 0.7569317756537789,
|
| 8 |
+
"val_acc": 0.788782412626832,
|
| 9 |
+
"val_referable_acc": 0.9088500563697858,
|
| 10 |
+
"val_any_dr_acc": 0.8717587373167982,
|
| 11 |
+
"val_severe_or_pdr_acc": 0.9549605411499437,
|
| 12 |
+
"val_qwk": 0.7429282333731377,
|
| 13 |
+
"val_referable_auc": 0.9194775303027065,
|
| 14 |
+
"val_any_dr_auc": 0.8871391804338257,
|
| 15 |
+
"val_severe_or_pdr_auc": 0.9680421111259949
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"epoch": 2,
|
| 19 |
+
"lr": 9.972883382072954e-05,
|
| 20 |
+
"train_loss": 1.0279213763810409,
|
| 21 |
+
"train_acc": 0.6919119305367614,
|
| 22 |
+
"val_loss": 0.8218129052519126,
|
| 23 |
+
"val_acc": 0.7131905298759865,
|
| 24 |
+
"val_referable_acc": 0.9132468996617813,
|
| 25 |
+
"val_any_dr_acc": 0.8071589627959413,
|
| 26 |
+
"val_severe_or_pdr_acc": 0.9501691093573844,
|
| 27 |
+
"val_qwk": 0.7225971569447935,
|
| 28 |
+
"val_referable_auc": 0.9308688716088045,
|
| 29 |
+
"val_any_dr_auc": 0.9059231844560037,
|
| 30 |
+
"val_severe_or_pdr_auc": 0.973083919091364
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"epoch": 3,
|
| 34 |
+
"lr": 9.891830623632339e-05,
|
| 35 |
+
"train_loss": 0.9740518329914594,
|
| 36 |
+
"train_acc": 0.7313937753721245,
|
| 37 |
+
"val_loss": 0.6883974176920791,
|
| 38 |
+
"val_acc": 0.797294250281849,
|
| 39 |
+
"val_referable_acc": 0.9175310033821872,
|
| 40 |
+
"val_any_dr_acc": 0.8841037204058625,
|
| 41 |
+
"val_severe_or_pdr_acc": 0.943630214205186,
|
| 42 |
+
"val_qwk": 0.756051220656397,
|
| 43 |
+
"val_referable_auc": 0.9364977917175292,
|
| 44 |
+
"val_any_dr_auc": 0.914930932335793,
|
| 45 |
+
"val_severe_or_pdr_auc": 0.9724510492530263
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"epoch": 4,
|
| 49 |
+
"lr": 9.757729755661011e-05,
|
| 50 |
+
"train_loss": 0.9428328731385878,
|
| 51 |
+
"train_acc": 0.749351601262968,
|
| 52 |
+
"val_loss": 0.7232750525065984,
|
| 53 |
+
"val_acc": 0.8005073280721533,
|
| 54 |
+
"val_referable_acc": 0.917869222096956,
|
| 55 |
+
"val_any_dr_acc": 0.8906989853438557,
|
| 56 |
+
"val_severe_or_pdr_acc": 0.9491544532130778,
|
| 57 |
+
"val_qwk": 0.783084663770558,
|
| 58 |
+
"val_referable_auc": 0.9426302409992056,
|
| 59 |
+
"val_any_dr_auc": 0.9197314348315854,
|
| 60 |
+
"val_severe_or_pdr_auc": 0.9738521022661843
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"epoch": 5,
|
| 64 |
+
"lr": 9.572050015330873e-05,
|
| 65 |
+
"train_loss": 0.9063401475219399,
|
| 66 |
+
"train_acc": 0.7640533378439333,
|
| 67 |
+
"val_loss": 0.6571064746366413,
|
| 68 |
+
"val_acc": 0.8170800450958287,
|
| 69 |
+
"val_referable_acc": 0.9222660653889515,
|
| 70 |
+
"val_any_dr_acc": 0.8917136414881623,
|
| 71 |
+
"val_severe_or_pdr_acc": 0.9569898534385569,
|
| 72 |
+
"val_qwk": 0.788183818867606,
|
| 73 |
+
"val_referable_auc": 0.9435813278531469,
|
| 74 |
+
"val_any_dr_auc": 0.9210081541524229,
|
| 75 |
+
"val_severe_or_pdr_auc": 0.9748177290801543
|
| 76 |
+
},
|
| 77 |
+
{
|
| 78 |
+
"epoch": 6,
|
| 79 |
+
"lr": 9.336825748732972e-05,
|
| 80 |
+
"train_loss": 0.8696432277647611,
|
| 81 |
+
"train_acc": 0.773849797023004,
|
| 82 |
+
"val_loss": 0.7369026844235391,
|
| 83 |
+
"val_acc": 0.7794250281848929,
|
| 84 |
+
"val_referable_acc": 0.9114430665163472,
|
| 85 |
+
"val_any_dr_acc": 0.8700112739571589,
|
| 86 |
+
"val_severe_or_pdr_acc": 0.938162344983089,
|
| 87 |
+
"val_qwk": 0.7573919491497015,
|
| 88 |
+
"val_referable_auc": 0.9446331246227204,
|
| 89 |
+
"val_any_dr_auc": 0.9217323785663145,
|
| 90 |
+
"val_severe_or_pdr_auc": 0.9769722038132437
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"epoch": 7,
|
| 94 |
+
"lr": 9.05463412215599e-05,
|
| 95 |
+
"train_loss": 0.8532237627106203,
|
| 96 |
+
"train_acc": 0.7721019395579612,
|
| 97 |
+
"val_loss": 0.714924802317829,
|
| 98 |
+
"val_acc": 0.7762119503945885,
|
| 99 |
+
"val_referable_acc": 0.9133596392333709,
|
| 100 |
+
"val_any_dr_acc": 0.8534949267192785,
|
| 101 |
+
"val_severe_or_pdr_acc": 0.9580045095828635,
|
| 102 |
+
"val_qwk": 0.770881114926211,
|
| 103 |
+
"val_referable_auc": 0.9455423195798338,
|
| 104 |
+
"val_any_dr_auc": 0.9243729038402309,
|
| 105 |
+
"val_severe_or_pdr_auc": 0.9756124975617895
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"epoch": 8,
|
| 109 |
+
"lr": 8.728566886113101e-05,
|
| 110 |
+
"train_loss": 0.8223982596510317,
|
| 111 |
+
"train_acc": 0.7796712900315742,
|
| 112 |
+
"val_loss": 0.6834435512275008,
|
| 113 |
+
"val_acc": 0.8021984216459978,
|
| 114 |
+
"val_referable_acc": 0.9120631341600902,
|
| 115 |
+
"val_any_dr_acc": 0.8750281848928974,
|
| 116 |
+
"val_severe_or_pdr_acc": 0.9632468996617812,
|
| 117 |
+
"val_qwk": 0.7856095873155075,
|
| 118 |
+
"val_referable_auc": 0.9450883852706131,
|
| 119 |
+
"val_any_dr_auc": 0.9239819931437874,
|
| 120 |
+
"val_severe_or_pdr_auc": 0.9751521751774899
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"epoch": 9,
|
| 124 |
+
"lr": 8.362196501476347e-05,
|
| 125 |
+
"train_loss": 0.7951097573831267,
|
| 126 |
+
"train_acc": 0.7813627649977447,
|
| 127 |
+
"val_loss": 0.6987135975444196,
|
| 128 |
+
"val_acc": 0.7952649379932356,
|
| 129 |
+
"val_referable_acc": 0.9191657271702367,
|
| 130 |
+
"val_any_dr_acc": 0.8735062006764375,
|
| 131 |
+
"val_severe_or_pdr_acc": 0.9528184892897407,
|
| 132 |
+
"val_qwk": 0.780215455176247,
|
| 133 |
+
"val_referable_auc": 0.9475252265024259,
|
| 134 |
+
"val_any_dr_auc": 0.9271016594578287,
|
| 135 |
+
"val_severe_or_pdr_auc": 0.9774892586547659
|
| 136 |
+
},
|
| 137 |
+
{
|
| 138 |
+
"epoch": 10,
|
| 139 |
+
"lr": 7.959536998847741e-05,
|
| 140 |
+
"train_loss": 0.76612451310275,
|
| 141 |
+
"train_acc": 0.7922727785295445,
|
| 142 |
+
"val_loss": 0.6806002331693922,
|
| 143 |
+
"val_acc": 0.7983089064261556,
|
| 144 |
+
"val_referable_acc": 0.9065952649379933,
|
| 145 |
+
"val_any_dr_acc": 0.879086809470124,
|
| 146 |
+
"val_severe_or_pdr_acc": 0.9450958286358512,
|
| 147 |
+
"val_qwk": 0.7577391366454651,
|
| 148 |
+
"val_referable_auc": 0.941599400380651,
|
| 149 |
+
"val_any_dr_auc": 0.9213001872922106,
|
| 150 |
+
"val_severe_or_pdr_auc": 0.9757958039866796
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"epoch": 11,
|
| 154 |
+
"lr": 7.524999999999999e-05,
|
| 155 |
+
"train_loss": 0.7444681421923756,
|
| 156 |
+
"train_acc": 0.7926251691474966,
|
| 157 |
+
"val_loss": 0.7777549177307421,
|
| 158 |
+
"val_acc": 0.743010146561443,
|
| 159 |
+
"val_referable_acc": 0.905749718151071,
|
| 160 |
+
"val_any_dr_acc": 0.8328635851183765,
|
| 161 |
+
"val_severe_or_pdr_acc": 0.9439120631341601,
|
| 162 |
+
"val_qwk": 0.7487336930435504,
|
| 163 |
+
"val_referable_auc": 0.9446526524090157,
|
| 164 |
+
"val_any_dr_auc": 0.9286820958770503,
|
| 165 |
+
"val_severe_or_pdr_auc": 0.9766265581046116
|
| 166 |
+
},
|
| 167 |
+
{
|
| 168 |
+
"epoch": 12,
|
| 169 |
+
"lr": 7.06334638322521e-05,
|
| 170 |
+
"train_loss": 0.7086018911610329,
|
| 171 |
+
"train_acc": 0.7951341903473161,
|
| 172 |
+
"val_loss": 0.5983526295040479,
|
| 173 |
+
"val_acc": 0.8147125140924465,
|
| 174 |
+
"val_referable_acc": 0.9256482525366404,
|
| 175 |
+
"val_any_dr_acc": 0.892728297632469,
|
| 176 |
+
"val_severe_or_pdr_acc": 0.9580608793686584,
|
| 177 |
+
"val_qwk": 0.8110785114483154,
|
| 178 |
+
"val_referable_auc": 0.9486358821012248,
|
| 179 |
+
"val_any_dr_auc": 0.9289309065981717,
|
| 180 |
+
"val_severe_or_pdr_auc": 0.9764373764737954
|
| 181 |
+
},
|
| 182 |
+
{
|
| 183 |
+
"epoch": 13,
|
| 184 |
+
"lr": 6.579634122155988e-05,
|
| 185 |
+
"train_loss": 0.685486784114943,
|
| 186 |
+
"train_acc": 0.798799052774019,
|
| 187 |
+
"val_loss": 0.7036147638802598,
|
| 188 |
+
"val_acc": 0.7593573844419391,
|
| 189 |
+
"val_referable_acc": 0.9249154453213078,
|
| 190 |
+
"val_any_dr_acc": 0.8441375422773394,
|
| 191 |
+
"val_severe_or_pdr_acc": 0.9520856820744081,
|
| 192 |
+
"val_qwk": 0.7909389147960119,
|
| 193 |
+
"val_referable_auc": 0.9498735397291792,
|
| 194 |
+
"val_any_dr_auc": 0.9288593958346787,
|
| 195 |
+
"val_severe_or_pdr_auc": 0.9767621284813532
|
| 196 |
+
},
|
| 197 |
+
{
|
| 198 |
+
"epoch": 14,
|
| 199 |
+
"lr": 6.079162869547907e-05,
|
| 200 |
+
"train_loss": 0.6543596743878665,
|
| 201 |
+
"train_acc": 0.8101037437979252,
|
| 202 |
+
"val_loss": 0.6764660255212794,
|
| 203 |
+
"val_acc": 0.7945885005636979,
|
| 204 |
+
"val_referable_acc": 0.9212514092446449,
|
| 205 |
+
"val_any_dr_acc": 0.8766065388951522,
|
| 206 |
+
"val_severe_or_pdr_acc": 0.9523111612175874,
|
| 207 |
+
"val_qwk": 0.8004058309513633,
|
| 208 |
+
"val_referable_auc": 0.9504607404671295,
|
| 209 |
+
"val_any_dr_auc": 0.9286490352111068,
|
| 210 |
+
"val_severe_or_pdr_auc": 0.9769738194948732
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"epoch": 15,
|
| 214 |
+
"lr": 5.567415893174884e-05,
|
| 215 |
+
"train_loss": 0.6133327330481538,
|
| 216 |
+
"train_acc": 0.8088774244474515,
|
| 217 |
+
"val_loss": 0.671032424091352,
|
| 218 |
+
"val_acc": 0.784216459977452,
|
| 219 |
+
"val_referable_acc": 0.9173055242390079,
|
| 220 |
+
"val_any_dr_acc": 0.8608229988726043,
|
| 221 |
+
"val_severe_or_pdr_acc": 0.9617812852311162,
|
| 222 |
+
"val_qwk": 0.7850222340142421,
|
| 223 |
+
"val_referable_auc": 0.9432520081634717,
|
| 224 |
+
"val_any_dr_auc": 0.9289369213684067,
|
| 225 |
+
"val_severe_or_pdr_auc": 0.9740109531464078
|
| 226 |
+
},
|
| 227 |
+
{
|
| 228 |
+
"epoch": 16,
|
| 229 |
+
"lr": 5.05e-05,
|
| 230 |
+
"train_loss": 0.5739147271398063,
|
| 231 |
+
"train_acc": 0.81670049616599,
|
| 232 |
+
"val_loss": 0.7213401265719563,
|
| 233 |
+
"val_acc": 0.7605411499436302,
|
| 234 |
+
"val_referable_acc": 0.9140360766629086,
|
| 235 |
+
"val_any_dr_acc": 0.8392897406989853,
|
| 236 |
+
"val_severe_or_pdr_acc": 0.9552987598647125,
|
| 237 |
+
"val_qwk": 0.7688554755328247,
|
| 238 |
+
"val_referable_auc": 0.9424395237007641,
|
| 239 |
+
"val_any_dr_auc": 0.9210517056966835,
|
| 240 |
+
"val_severe_or_pdr_auc": 0.9737944518080359
|
| 241 |
+
},
|
| 242 |
+
{
|
| 243 |
+
"epoch": 17,
|
| 244 |
+
"lr": 4.532584106825115e-05,
|
| 245 |
+
"train_loss": 0.5483453719564585,
|
| 246 |
+
"train_acc": 0.8217890166892197,
|
| 247 |
+
"val_loss": 0.6458704775860774,
|
| 248 |
+
"val_acc": 0.8037767756482526,
|
| 249 |
+
"val_referable_acc": 0.9226606538895152,
|
| 250 |
+
"val_any_dr_acc": 0.8786922209695603,
|
| 251 |
+
"val_severe_or_pdr_acc": 0.961837655016911,
|
| 252 |
+
"val_qwk": 0.8013663508734132,
|
| 253 |
+
"val_referable_auc": 0.9431509003462377,
|
| 254 |
+
"val_any_dr_auc": 0.9270491886099637,
|
| 255 |
+
"val_severe_or_pdr_auc": 0.9746947169560793
|
| 256 |
+
},
|
| 257 |
+
{
|
| 258 |
+
"epoch": 18,
|
| 259 |
+
"lr": 4.0208371304520894e-05,
|
| 260 |
+
"train_loss": 0.5206159053149393,
|
| 261 |
+
"train_acc": 0.8248054803788903,
|
| 262 |
+
"val_loss": 0.6574336617748257,
|
| 263 |
+
"val_acc": 0.787880496054115,
|
| 264 |
+
"val_referable_acc": 0.9196730552423901,
|
| 265 |
+
"val_any_dr_acc": 0.8589064261555807,
|
| 266 |
+
"val_severe_or_pdr_acc": 0.9645434047350621,
|
| 267 |
+
"val_qwk": 0.7916413157545019,
|
| 268 |
+
"val_referable_auc": 0.9478035943818823,
|
| 269 |
+
"val_any_dr_auc": 0.9298872303811361,
|
| 270 |
+
"val_severe_or_pdr_auc": 0.9746491841101529
|
| 271 |
+
},
|
| 272 |
+
{
|
| 273 |
+
"epoch": 19,
|
| 274 |
+
"lr": 3.520365877844009e-05,
|
| 275 |
+
"train_loss": 0.4738634637832964,
|
| 276 |
+
"train_acc": 0.8307115471357691,
|
| 277 |
+
"val_loss": 0.6353207715334457,
|
| 278 |
+
"val_acc": 0.7983089064261556,
|
| 279 |
+
"val_referable_acc": 0.9183201803833145,
|
| 280 |
+
"val_any_dr_acc": 0.8669109357384442,
|
| 281 |
+
"val_severe_or_pdr_acc": 0.9680383314543405,
|
| 282 |
+
"val_qwk": 0.7947142863535627,
|
| 283 |
+
"val_referable_auc": 0.9461027792896338,
|
| 284 |
+
"val_any_dr_auc": 0.9288580381916022,
|
| 285 |
+
"val_severe_or_pdr_auc": 0.9744999538796333
|
| 286 |
+
}
|
| 287 |
+
]
|
train.py
ADDED
|
@@ -0,0 +1,480 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
import json
|
| 3 |
+
import random
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
import numpy as np
|
| 7 |
+
import torch
|
| 8 |
+
import torch.nn.functional as F
|
| 9 |
+
from torch.utils.data import DataLoader
|
| 10 |
+
from tqdm import tqdm
|
| 11 |
+
|
| 12 |
+
from augmentations import get_train_transforms, get_val_transforms
|
| 13 |
+
from dataloader import EyePACSDataset
|
| 14 |
+
from model import DeepSeeNet
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
N_CLASSES = 5
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
class AlbumentationsTransform:
|
| 21 |
+
def __init__(self, transform):
|
| 22 |
+
self.transform = transform
|
| 23 |
+
|
| 24 |
+
def __call__(self, image):
|
| 25 |
+
return self.transform(image=np.asarray(image))["image"]
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def parse_args():
|
| 29 |
+
parser = argparse.ArgumentParser(description="Train EyePACS DR classifier.")
|
| 30 |
+
|
| 31 |
+
parser.add_argument("--root", required=True, help="EyePACS root folder.")
|
| 32 |
+
parser.add_argument("--output-dir", default="checkpoints/eyepacs_dr")
|
| 33 |
+
|
| 34 |
+
parser.add_argument("--backbone", default="inception_v3")
|
| 35 |
+
parser.add_argument("--image-size", type=int, default=1024)
|
| 36 |
+
parser.add_argument("--epochs", type=int, default=20)
|
| 37 |
+
parser.add_argument("--batch-size", type=int, default=32)
|
| 38 |
+
parser.add_argument("--num-workers", type=int, default=8)
|
| 39 |
+
|
| 40 |
+
parser.add_argument("--fold", type=int, default=0)
|
| 41 |
+
parser.add_argument("--n-folds", type=int, default=5)
|
| 42 |
+
parser.add_argument("--seed", type=int, default=42)
|
| 43 |
+
|
| 44 |
+
parser.add_argument("--lr", type=float, default=1e-4)
|
| 45 |
+
parser.add_argument("--weight-decay", type=float, default=1e-4)
|
| 46 |
+
parser.add_argument("--no-pretrained", action="store_true")
|
| 47 |
+
parser.add_argument("--freeze-backbone", action="store_true")
|
| 48 |
+
parser.add_argument("--no-class-weights", action="store_true")
|
| 49 |
+
|
| 50 |
+
parser.add_argument("--scheduler", choices=["none", "cosine", "step"], default="cosine")
|
| 51 |
+
parser.add_argument("--min-lr", type=float, default=1e-6)
|
| 52 |
+
parser.add_argument("--step-size", type=int, default=5)
|
| 53 |
+
parser.add_argument("--gamma", type=float, default=0.5)
|
| 54 |
+
|
| 55 |
+
parser.add_argument("--amp", action="store_true")
|
| 56 |
+
parser.add_argument("--grad-clip", type=float, default=0.0)
|
| 57 |
+
parser.add_argument("--save-every", type=int, default=0)
|
| 58 |
+
|
| 59 |
+
parser.add_argument("--wandb", action="store_true")
|
| 60 |
+
parser.add_argument("--wandb-project", default="eyepacs-dr")
|
| 61 |
+
|
| 62 |
+
return parser.parse_args()
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def set_seed(seed):
|
| 66 |
+
random.seed(seed)
|
| 67 |
+
np.random.seed(seed)
|
| 68 |
+
torch.manual_seed(seed)
|
| 69 |
+
torch.cuda.manual_seed_all(seed)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def unwrap_logits(output):
|
| 73 |
+
if isinstance(output, (tuple, list)):
|
| 74 |
+
return output[0]
|
| 75 |
+
return output
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
def get_class_weights(dataset, device):
|
| 79 |
+
labels = torch.tensor([s["label"] for s in dataset.samples], dtype=torch.long)
|
| 80 |
+
counts = torch.bincount(labels, minlength=N_CLASSES).clamp_min(1)
|
| 81 |
+
weights = counts.sum() / (N_CLASSES * counts)
|
| 82 |
+
return weights.to(device)
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def build_scheduler(optimizer, args):
|
| 86 |
+
if args.scheduler == "cosine":
|
| 87 |
+
return torch.optim.lr_scheduler.CosineAnnealingLR(
|
| 88 |
+
optimizer,
|
| 89 |
+
T_max=args.epochs,
|
| 90 |
+
eta_min=args.min_lr,
|
| 91 |
+
)
|
| 92 |
+
|
| 93 |
+
if args.scheduler == "step":
|
| 94 |
+
return torch.optim.lr_scheduler.StepLR(
|
| 95 |
+
optimizer,
|
| 96 |
+
step_size=args.step_size,
|
| 97 |
+
gamma=args.gamma,
|
| 98 |
+
)
|
| 99 |
+
|
| 100 |
+
return None
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def make_loader(dataset, batch_size, num_workers, shuffle, device):
|
| 104 |
+
return DataLoader(
|
| 105 |
+
dataset,
|
| 106 |
+
batch_size=batch_size,
|
| 107 |
+
shuffle=shuffle,
|
| 108 |
+
num_workers=num_workers,
|
| 109 |
+
pin_memory=device.type == "cuda",
|
| 110 |
+
drop_last=shuffle,
|
| 111 |
+
persistent_workers=num_workers > 0,
|
| 112 |
+
)
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def train_one_epoch(
|
| 116 |
+
model,
|
| 117 |
+
loader,
|
| 118 |
+
optimizer,
|
| 119 |
+
scaler,
|
| 120 |
+
criterion,
|
| 121 |
+
device,
|
| 122 |
+
use_amp=True,
|
| 123 |
+
grad_clip=0.0,
|
| 124 |
+
):
|
| 125 |
+
model.train()
|
| 126 |
+
|
| 127 |
+
total_loss = 0.0
|
| 128 |
+
total_correct = 0
|
| 129 |
+
total_samples = 0
|
| 130 |
+
|
| 131 |
+
pbar = tqdm(loader, desc="Train", leave=False)
|
| 132 |
+
|
| 133 |
+
for images, labels in pbar:
|
| 134 |
+
images = images.to(device, non_blocking=True)
|
| 135 |
+
labels = labels.to(device, non_blocking=True)
|
| 136 |
+
|
| 137 |
+
optimizer.zero_grad(set_to_none=True)
|
| 138 |
+
|
| 139 |
+
with torch.amp.autocast("cuda", enabled=use_amp and device.type == "cuda"):
|
| 140 |
+
logits = unwrap_logits(model(images))
|
| 141 |
+
loss = criterion(logits, labels)
|
| 142 |
+
|
| 143 |
+
if scaler is not None:
|
| 144 |
+
scaler.scale(loss).backward()
|
| 145 |
+
|
| 146 |
+
if grad_clip > 0:
|
| 147 |
+
scaler.unscale_(optimizer)
|
| 148 |
+
torch.nn.utils.clip_grad_norm_(model.parameters(), grad_clip)
|
| 149 |
+
|
| 150 |
+
scaler.step(optimizer)
|
| 151 |
+
scaler.update()
|
| 152 |
+
else:
|
| 153 |
+
loss.backward()
|
| 154 |
+
|
| 155 |
+
if grad_clip > 0:
|
| 156 |
+
torch.nn.utils.clip_grad_norm_(model.parameters(), grad_clip)
|
| 157 |
+
|
| 158 |
+
optimizer.step()
|
| 159 |
+
|
| 160 |
+
batch_size = labels.size(0)
|
| 161 |
+
total_loss += loss.item() * batch_size
|
| 162 |
+
total_correct += (logits.argmax(dim=1) == labels).sum().item()
|
| 163 |
+
total_samples += batch_size
|
| 164 |
+
|
| 165 |
+
pbar.set_postfix(
|
| 166 |
+
loss=f"{total_loss / total_samples:.4f}",
|
| 167 |
+
acc=f"{total_correct / total_samples:.4f}",
|
| 168 |
+
)
|
| 169 |
+
|
| 170 |
+
return {
|
| 171 |
+
"loss": total_loss / total_samples,
|
| 172 |
+
"acc": total_correct / total_samples,
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
@torch.no_grad()
|
| 177 |
+
def evaluate(model, loader, criterion, device, use_amp=True):
|
| 178 |
+
model.eval()
|
| 179 |
+
|
| 180 |
+
total_loss = 0.0
|
| 181 |
+
total_correct = 0
|
| 182 |
+
total_samples = 0
|
| 183 |
+
|
| 184 |
+
all_labels = []
|
| 185 |
+
all_probs = []
|
| 186 |
+
all_preds = []
|
| 187 |
+
|
| 188 |
+
pbar = tqdm(loader, desc="Val", leave=False)
|
| 189 |
+
|
| 190 |
+
for images, labels in pbar:
|
| 191 |
+
images = images.to(device, non_blocking=True)
|
| 192 |
+
labels = labels.to(device, non_blocking=True)
|
| 193 |
+
|
| 194 |
+
with torch.amp.autocast("cuda", enabled=use_amp and device.type == "cuda"):
|
| 195 |
+
logits = unwrap_logits(model(images))
|
| 196 |
+
loss = criterion(logits, labels)
|
| 197 |
+
|
| 198 |
+
probs = F.softmax(logits, dim=1)
|
| 199 |
+
preds = probs.argmax(dim=1)
|
| 200 |
+
|
| 201 |
+
batch_size = labels.size(0)
|
| 202 |
+
total_loss += loss.item() * batch_size
|
| 203 |
+
total_correct += (preds == labels).sum().item()
|
| 204 |
+
total_samples += batch_size
|
| 205 |
+
|
| 206 |
+
all_labels.append(labels.detach().cpu())
|
| 207 |
+
all_probs.append(probs.detach().cpu())
|
| 208 |
+
all_preds.append(preds.detach().cpu())
|
| 209 |
+
|
| 210 |
+
pbar.set_postfix(
|
| 211 |
+
loss=f"{total_loss / total_samples:.4f}",
|
| 212 |
+
acc=f"{total_correct / total_samples:.4f}",
|
| 213 |
+
)
|
| 214 |
+
|
| 215 |
+
labels = torch.cat(all_labels).numpy()
|
| 216 |
+
probs = torch.cat(all_probs).numpy()
|
| 217 |
+
preds = torch.cat(all_preds).numpy()
|
| 218 |
+
|
| 219 |
+
metrics = {
|
| 220 |
+
"loss": total_loss / total_samples,
|
| 221 |
+
"acc": total_correct / total_samples,
|
| 222 |
+
"referable_acc": float(((labels >= 2) == (preds >= 2)).mean()),
|
| 223 |
+
"any_dr_acc": float(((labels >= 1) == (preds >= 1)).mean()),
|
| 224 |
+
"severe_or_pdr_acc": float(((labels >= 3) == (preds >= 3)).mean()),
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
try:
|
| 228 |
+
from sklearn.metrics import cohen_kappa_score, roc_auc_score
|
| 229 |
+
|
| 230 |
+
metrics["qwk"] = float(cohen_kappa_score(labels, preds, weights="quadratic"))
|
| 231 |
+
metrics["referable_auc"] = float(
|
| 232 |
+
roc_auc_score((labels >= 2).astype(int), probs[:, 2:].sum(axis=1))
|
| 233 |
+
)
|
| 234 |
+
metrics["any_dr_auc"] = float(
|
| 235 |
+
roc_auc_score((labels >= 1).astype(int), probs[:, 1:].sum(axis=1))
|
| 236 |
+
)
|
| 237 |
+
metrics["severe_or_pdr_auc"] = float(
|
| 238 |
+
roc_auc_score((labels >= 3).astype(int), probs[:, 3:].sum(axis=1))
|
| 239 |
+
)
|
| 240 |
+
except Exception:
|
| 241 |
+
metrics["qwk"] = float("nan")
|
| 242 |
+
metrics["referable_auc"] = float("nan")
|
| 243 |
+
metrics["any_dr_auc"] = float("nan")
|
| 244 |
+
metrics["severe_or_pdr_auc"] = float("nan")
|
| 245 |
+
|
| 246 |
+
return metrics
|
| 247 |
+
|
| 248 |
+
|
| 249 |
+
def save_checkpoint(path, model, optimizer, scheduler, epoch, best_metric, args, model_only=False):
|
| 250 |
+
path = Path(path)
|
| 251 |
+
path.parent.mkdir(parents=True, exist_ok=True)
|
| 252 |
+
|
| 253 |
+
ckpt = {
|
| 254 |
+
"epoch": epoch,
|
| 255 |
+
"model": model.state_dict(),
|
| 256 |
+
"best_metric": best_metric,
|
| 257 |
+
"args": vars(args),
|
| 258 |
+
"id_to_label": {
|
| 259 |
+
0: "no_dr",
|
| 260 |
+
1: "mild_npdr",
|
| 261 |
+
2: "moderate_npdr",
|
| 262 |
+
3: "severe_npdr",
|
| 263 |
+
4: "pdr",
|
| 264 |
+
},
|
| 265 |
+
}
|
| 266 |
+
|
| 267 |
+
if not model_only:
|
| 268 |
+
ckpt["optimizer"] = optimizer.state_dict()
|
| 269 |
+
if scheduler is not None:
|
| 270 |
+
ckpt["scheduler"] = scheduler.state_dict()
|
| 271 |
+
|
| 272 |
+
torch.save(ckpt, path)
|
| 273 |
+
|
| 274 |
+
|
| 275 |
+
def main():
|
| 276 |
+
args = parse_args()
|
| 277 |
+
set_seed(args.seed)
|
| 278 |
+
|
| 279 |
+
output_dir = Path(args.output_dir)
|
| 280 |
+
output_dir.mkdir(parents=True, exist_ok=True)
|
| 281 |
+
|
| 282 |
+
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 283 |
+
use_amp = args.amp and device.type == "cuda"
|
| 284 |
+
|
| 285 |
+
train_dataset = EyePACSDataset(
|
| 286 |
+
root=args.root,
|
| 287 |
+
split="all",
|
| 288 |
+
all_mode="train",
|
| 289 |
+
transform=AlbumentationsTransform(get_train_transforms(args.image_size)),
|
| 290 |
+
seed=args.seed,
|
| 291 |
+
fold=args.fold,
|
| 292 |
+
n_folds=args.n_folds,
|
| 293 |
+
)
|
| 294 |
+
|
| 295 |
+
val_dataset = EyePACSDataset(
|
| 296 |
+
root=args.root,
|
| 297 |
+
split="all",
|
| 298 |
+
all_mode="val",
|
| 299 |
+
transform=AlbumentationsTransform(get_val_transforms(args.image_size)),
|
| 300 |
+
seed=args.seed,
|
| 301 |
+
fold=args.fold,
|
| 302 |
+
n_folds=args.n_folds,
|
| 303 |
+
)
|
| 304 |
+
|
| 305 |
+
train_loader = make_loader(
|
| 306 |
+
train_dataset,
|
| 307 |
+
batch_size=args.batch_size,
|
| 308 |
+
num_workers=args.num_workers,
|
| 309 |
+
shuffle=True,
|
| 310 |
+
device=device,
|
| 311 |
+
)
|
| 312 |
+
|
| 313 |
+
val_loader = make_loader(
|
| 314 |
+
val_dataset,
|
| 315 |
+
batch_size=args.batch_size,
|
| 316 |
+
num_workers=args.num_workers,
|
| 317 |
+
shuffle=False,
|
| 318 |
+
device=device,
|
| 319 |
+
)
|
| 320 |
+
|
| 321 |
+
model = DeepSeeNet(
|
| 322 |
+
n_classes=N_CLASSES,
|
| 323 |
+
backbone=args.backbone,
|
| 324 |
+
pretrained=not args.no_pretrained,
|
| 325 |
+
freeze_backbone=args.freeze_backbone,
|
| 326 |
+
).to(device)
|
| 327 |
+
|
| 328 |
+
class_weights = None
|
| 329 |
+
if not args.no_class_weights:
|
| 330 |
+
class_weights = get_class_weights(train_dataset, device)
|
| 331 |
+
|
| 332 |
+
train_criterion = torch.nn.CrossEntropyLoss(weight=class_weights)
|
| 333 |
+
val_criterion = torch.nn.CrossEntropyLoss()
|
| 334 |
+
|
| 335 |
+
optimizer = torch.optim.AdamW(
|
| 336 |
+
model.parameters(),
|
| 337 |
+
lr=args.lr,
|
| 338 |
+
weight_decay=args.weight_decay,
|
| 339 |
+
)
|
| 340 |
+
|
| 341 |
+
scheduler = build_scheduler(optimizer, args)
|
| 342 |
+
scaler = torch.amp.GradScaler("cuda") if use_amp else None
|
| 343 |
+
|
| 344 |
+
wandb = None
|
| 345 |
+
if args.wandb:
|
| 346 |
+
import wandb
|
| 347 |
+
|
| 348 |
+
wandb.init(project=args.wandb_project, config=vars(args))
|
| 349 |
+
|
| 350 |
+
print("\nEyePACS DR training")
|
| 351 |
+
print("-------------------")
|
| 352 |
+
print(f"Device: {device}")
|
| 353 |
+
print(f"Root: {args.root}")
|
| 354 |
+
print(f"Output: {output_dir}")
|
| 355 |
+
print(f"Backbone: {args.backbone}")
|
| 356 |
+
print(f"Image size: {args.image_size}")
|
| 357 |
+
print(f"Fold: {args.fold}/{args.n_folds}")
|
| 358 |
+
print(f"Train samples: {len(train_dataset)}")
|
| 359 |
+
print(f"Val samples: {len(val_dataset)}")
|
| 360 |
+
print(f"AMP: {use_amp}")
|
| 361 |
+
print(f"Pretrained: {not args.no_pretrained}")
|
| 362 |
+
|
| 363 |
+
if class_weights is not None:
|
| 364 |
+
print(f"Class weights: {class_weights.detach().cpu().tolist()}")
|
| 365 |
+
|
| 366 |
+
best_qwk = -float("inf")
|
| 367 |
+
history = []
|
| 368 |
+
|
| 369 |
+
for epoch in range(1, args.epochs + 1):
|
| 370 |
+
print(f"\nEpoch [{epoch:03d}/{args.epochs}]")
|
| 371 |
+
|
| 372 |
+
train_metrics = train_one_epoch(
|
| 373 |
+
model=model,
|
| 374 |
+
loader=train_loader,
|
| 375 |
+
optimizer=optimizer,
|
| 376 |
+
scaler=scaler,
|
| 377 |
+
criterion=train_criterion,
|
| 378 |
+
device=device,
|
| 379 |
+
use_amp=use_amp,
|
| 380 |
+
grad_clip=args.grad_clip,
|
| 381 |
+
)
|
| 382 |
+
|
| 383 |
+
val_metrics = evaluate(
|
| 384 |
+
model=model,
|
| 385 |
+
loader=val_loader,
|
| 386 |
+
criterion=val_criterion,
|
| 387 |
+
device=device,
|
| 388 |
+
use_amp=use_amp,
|
| 389 |
+
)
|
| 390 |
+
|
| 391 |
+
lr = optimizer.param_groups[0]["lr"]
|
| 392 |
+
|
| 393 |
+
row = {
|
| 394 |
+
"epoch": epoch,
|
| 395 |
+
"lr": lr,
|
| 396 |
+
**{f"train_{k}": v for k, v in train_metrics.items()},
|
| 397 |
+
**{f"val_{k}": v for k, v in val_metrics.items()},
|
| 398 |
+
}
|
| 399 |
+
history.append(row)
|
| 400 |
+
|
| 401 |
+
print(
|
| 402 |
+
f"lr={lr:.2e} "
|
| 403 |
+
f"train_loss={train_metrics['loss']:.4f} "
|
| 404 |
+
f"train_acc={train_metrics['acc']:.4f} "
|
| 405 |
+
f"val_loss={val_metrics['loss']:.4f} "
|
| 406 |
+
f"val_acc={val_metrics['acc']:.4f} "
|
| 407 |
+
f"val_qwk={val_metrics['qwk']:.4f} "
|
| 408 |
+
f"val_ref_auc={val_metrics['referable_auc']:.4f}"
|
| 409 |
+
)
|
| 410 |
+
|
| 411 |
+
if wandb is not None:
|
| 412 |
+
wandb.log(row)
|
| 413 |
+
|
| 414 |
+
with (output_dir / "history.json").open("w") as f:
|
| 415 |
+
json.dump(history, f, indent=2)
|
| 416 |
+
|
| 417 |
+
monitor = val_metrics["qwk"]
|
| 418 |
+
if np.isnan(monitor):
|
| 419 |
+
monitor = -val_metrics["loss"]
|
| 420 |
+
|
| 421 |
+
if monitor > best_qwk:
|
| 422 |
+
best_qwk = monitor
|
| 423 |
+
|
| 424 |
+
save_checkpoint(
|
| 425 |
+
output_dir / "best.pt",
|
| 426 |
+
model=model,
|
| 427 |
+
optimizer=optimizer,
|
| 428 |
+
scheduler=scheduler,
|
| 429 |
+
epoch=epoch,
|
| 430 |
+
best_metric=best_qwk,
|
| 431 |
+
args=args,
|
| 432 |
+
model_only=False,
|
| 433 |
+
)
|
| 434 |
+
|
| 435 |
+
save_checkpoint(
|
| 436 |
+
output_dir / "best_model_only.pt",
|
| 437 |
+
model=model,
|
| 438 |
+
optimizer=optimizer,
|
| 439 |
+
scheduler=scheduler,
|
| 440 |
+
epoch=epoch,
|
| 441 |
+
best_metric=best_qwk,
|
| 442 |
+
args=args,
|
| 443 |
+
model_only=True,
|
| 444 |
+
)
|
| 445 |
+
|
| 446 |
+
print(f"Saved best checkpoint: monitor={best_qwk:.4f}")
|
| 447 |
+
|
| 448 |
+
if args.save_every > 0 and epoch % args.save_every == 0:
|
| 449 |
+
save_checkpoint(
|
| 450 |
+
output_dir / f"epoch_{epoch:03d}.pt",
|
| 451 |
+
model=model,
|
| 452 |
+
optimizer=optimizer,
|
| 453 |
+
scheduler=scheduler,
|
| 454 |
+
epoch=epoch,
|
| 455 |
+
best_metric=best_qwk,
|
| 456 |
+
args=args,
|
| 457 |
+
model_only=False,
|
| 458 |
+
)
|
| 459 |
+
|
| 460 |
+
if scheduler is not None:
|
| 461 |
+
scheduler.step()
|
| 462 |
+
|
| 463 |
+
save_checkpoint(
|
| 464 |
+
output_dir / "last.pt",
|
| 465 |
+
model=model,
|
| 466 |
+
optimizer=optimizer,
|
| 467 |
+
scheduler=scheduler,
|
| 468 |
+
epoch=args.epochs,
|
| 469 |
+
best_metric=best_qwk,
|
| 470 |
+
args=args,
|
| 471 |
+
model_only=False,
|
| 472 |
+
)
|
| 473 |
+
|
| 474 |
+
print("\nTraining complete.")
|
| 475 |
+
print(f"Best monitor/QWK: {best_qwk:.4f}")
|
| 476 |
+
print(f"Saved to: {output_dir}")
|
| 477 |
+
|
| 478 |
+
|
| 479 |
+
if __name__ == "__main__":
|
| 480 |
+
main()
|