dl4h final - #1069
Open
raymondcoding15 wants to merge 14 commits into
Open
Conversation
…NOTEBOOK_GUIDE.txt
raymondcoding15
force-pushed
the
DL4H_final
branch
from
April 22, 2026 03:22
4220bc7 to
0b5e6f3
Compare
|
This PR has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Contributor: Andrew Raymond (
andrew46@illinois.edu), CS 598 DL4H SP26 final project.Type of contribution: Option 2, Model.
Paper: Kim et al., "Integrating ChatGPT into Secure Hospital Networks: A Case Study on Improving Radiology Report Analysis." CHIL 2024. PMLR 248:72-87.
What this PR does
This PR adds
SentenceKDTransformertopyhealth.models. It's the student-side model from Kim et al.: a BERT-family encoder trained on sentence-level labels with a combined cross-entropy plus supervised-contrastive objective (paper Eq. 5, contrastive term from Khosla et al., NeurIPS 2020). A small helper aggregates per-sentence probabilities into a document-level anomaly score the way the paper does in Eq. 4 (max over sentences), and also exposes two other aggregation modes I found useful during ablations.No new dataset or task is introduced. The example exercises the model on the existing
MedicalTranscriptionsDatasetso reviewers don't need a DUA, Kaggle key, or anything else.Files to review
The diff is limited to seven files:
pyhealth/models/sentence_kd_transformer.py: the model and a module-levelsupervised_contrastive_losshelper. Start here.pyhealth/models/__init__.py: one-line export of both symbols.docs/api/models/pyhealth.models.SentenceKDTransformer.rst: Sphinx autodoc page.docs/api/models.rst: toctree entry.tests/core/test_sentence_kd_transformer.py: 16 unit tests, all synthetic.examples/medical_transcriptions_classification_sentence_kd_transformer.py: the headless ablation suite.examples/medical_transcriptions_classification_sentence_kd_transformer.ipynb: Colab-runnable walkthrough of the same ablations.What I replicated vs. what I extended
Faithful to the paper: BERT student with a
[CLS]classifier head, the combined CE + λ·SupCon loss, RadBERT as the default backbone, and max-pool document scoring.Things the paper doesn't do that this PR adds:
{0, 0.1, 0.5, 1, 2, 5}. The paper only compares λ=0 to λ=1 in Table 4, so it can't tell you where the contrastive term starts to dominate cross-entropy; the sweep does.{0.05, 0.1, 0.2, 0.5, 1.0}. The paper inherits Khosla et al.'s default of 0.07 without evaluating it, so I treated τ as a free knob.max: atopk_meanthat's less sensitive to a single high-scoring sentence, and an attention-pooled variant.A note on the teacher step
Kim et al. use ChatGPT as a cloud teacher to produce ternary sentence labels (
normal/abnormal/uncertain) for MIMIC-CXR, and then distill a BERT student against those labels. I deliberately did not replicate that step here, for three reasons:mtsamples) ships with ground-truth specialty labels, so an LLM teacher isn't needed to train the student.The model itself is teacher-agnostic: whatever source produces the sentence labels (a human annotator, a rule-based labeler, or an on-prem model like Llama-3-8B) drops in without code changes. What this PR covers is the student side of the pipeline (the loss, the forward pass, and the aggregation), which is the portion of the paper PyHealth can actually ship.
How to test locally
Unit tests run on CPU and use
prajjwal1/bert-tiny(~17 MB, one-time HuggingFace cache download). Full suite finishes in roughly 6 seconds, with each individual test under 2 seconds:For a fast end-to-end sanity check without touching real data:
For the real mtsamples run (same code path the notebook uses):
python examples/medical_transcriptions_classification_sentence_kd_transformer.py \ --data_root /path/to/mtsamples --epochs 3If you're compute-constrained, cap the dataset with
--max_samples:python examples/medical_transcriptions_classification_sentence_kd_transformer.py \ --data_root /path/to/mtsamples --epochs 2 --max_samples 1500The notebook is set up for Colab with a T4 and takes about 3 to 4 minutes end to end with the default 1500-row subsample; flip
MAX_SAMPLES = Nonein the data cell to run on the full ~5,000 mtsamples corpus instead, which takes about 10 to 12 minutes. The notebook auto-downloads mtsamples fromharishnair04/mtsampleson HuggingFace (CC0, ~17 MB), so there's no credential setup. Subsampling is seeded, so every ablation run sees the same data and trends are preserved at 1500 rows.