Views
No views yet
LogisticRegression using the saga solver (data‑efficient and scalable), then converted into a torch linear head for deployment. The training code also handles image decoding failures (Pillow -> OpenCV fallback), optional preprocessing toggles, and supports threshold calibration for high‑recall deployment.artifacts/vision_model/ (MedSigLIP vision encoder weights + config)artifacts/linear_head.pt (linear probe head)artifacts/scaler.joblib (mean/std for embedding standardization)artifacts/config.json (threshold + preprocessing flags)artifacts/optimized/ (color constancy utilities)artifacts/config.json): 0.31.Dataset/dataset anemia/ with class folders Anemia and Non-Anemia.LogisticRegression with solver=\"saga\".scaler.joblib.Linear head and saved as linear_head.pt.1# 1) Extract frozen MedSigLIP embeddings
2vision_model.eval()
3with torch.no_grad():
4 outputs = vision_model(pixel_values=tensor)
5 embeds = outputs.pooler_output
6 embeds = embeds / embeds.norm(p=2, dim=-1, keepdim=True)
7
8# 2) Standardize embeddings (mean/std from train set)
9x_std = (x - scaler["mean"]) / scaler["std"]
10
11# 3) Train linear probe (logistic regression, saga)
12model = LogisticRegression(
13 solver="saga",
14 max_iter=5000,
15 C=best_c,
16 n_jobs=-1,
17)
18model.fit(x_train_std, y_train)
19
20# 4) Convert to torch Linear head for deployment
21linear_head = torch.nn.Linear(vision_model.config.hidden_size, 1, bias=True)
22linear_head.weight.data.copy_(torch.from_numpy(model.coef_))
23linear_head.bias.data.copy_(torch.from_numpy(model.intercept_))
24torch.save(linear_head.state_dict(), "linear_head.pt")| Experiment | Accuracy | Precision | Recall | F1 | ROC-AUC | Confusion Matrix | Threshold |
|---|---|---|---|---|---|---|---|
| Zero-shot baseline (subject-level) | 0.487654 | 0.490446 | 0.962500 | 0.649789 | 0.562348 | [[2, 80], [3, 77]] | n/a |
| Linear probe (before OpenCV fallback) | 0.558333 | 0.500000 | 0.962264 | 0.658065 | 0.692763 | [[16, 51], [2, 51]] | n/a |
| Linear probe (after OpenCV fallback) | 0.598765 | 0.556391 | 0.925000 | 0.694836 | 0.652896 | [[23, 59], [6, 74]] | n/a |
| Linear probe (full cleaned dataset) | 0.715116 | 0.714286 | 0.670732 | 0.691824 | 0.783740 | [[68, 22], [27, 55]] | n/a |
| Linear probe (TF resize + SAGA) | 0.686047 | 0.694444 | 0.609756 | 0.649351 | 0.812195 | [[68, 22], [32, 50]] | 0.1475936 (ROC best) |
| Linear probe (Auto-PIL + Torch) | 0.726744 | 0.733333 | 0.670732 | 0.700637 | 0.784688 | [[70, 20], [27, 55]] | 0.5850275 (ROC best) |
| Optimized segmented split (recall target 0.90) | 0.710000 | 0.652174 | 0.900000 | 0.756303 | 0.836800 | [[26, 24], [5, 45]] | 0.05 |
| Full-dataset linear probe (latest, recall target 0.90) | 0.823580 | 0.775249 | 0.920608 | 0.841699 | 0.912441 | [[412, 158], [47, 545]] | 0.31 |
Sidharth1743).