Chest Xray Classification Ai
AI Research Paper & Complete Technical Investigation
View Model Figures (4)
🧠 PyTorch 2.4 · Deep Learning · Academic Dossier · 2026

Chest Xray Classification Ai β€” Architecture & Technical Analysis

Comprehensive engineering investigation covering model architectures, mathematical loss formulations, stochastic data pipelines, and quantitative benchmarks.

4942
Verified Words
4
Model Figures
4.9β˜…
Student Rating
PyTorch Implementation Model Backbone Loss Optimization Ablation Studies

Complete Technical Paper Content β€” Chest Xray Classification Ai

1. Executive Abstract, Problem Formulation & Background

Chest X-ray Finding Classification Live demo β†’ Β· MLOps write-up Β· Model weights A multi-label classifier for five chest X-ray findings: Atelectasis, Cardiomegaly, Consolidation, Edema, Pleural Effusion . It uses a DenseNet121 fine-tuned on 159,329 Stanford CheXpert images, with Grad-CAM explanations, wrapped in a full MLOps pipeline: data validation, experiment tracking, a quality gate that blocks worse models, drift monitoring, a hardened API, CI/CD, and a browser build checked against PyTorch before every release. The demo runs the model in your browser (ONNX), so images never leave your device. The page also shows the live CI/CD status and the model card. Research and portfolio project. Not a medical device and not for clinical use. Results (v1.0 checkpoint) These are measured on the official CheXpert validation set: 234 images , labelled by radiologist consensus. Finding AUROC Precision @0.5 Recall @0.5 F1 @0.5 Atelectasis 0.818 0.62 0.73 0.67 Cardiomegaly 0.855 0.74 0.59 0.66 Consolidation 0.897 0.43 0.79 0.56 Edema 0.906 0.51 0.87 0.64 Pleural Effusion 0.919 0.80 0.73 0.77 Mean 0.879 Read this before quoting the number. In v1.0 the best epoch was chosen using this same validation set. Across epochs 6–10 the mean AUROC moved between 0.854 and 0.879 , so 0.879 is the most favourable of five looks at a small set. With only 234 images, per-finding AUROCs also carry roughly Β±0.03–0.06 of sampling noise. The v1.1 code below fixes the selection leak (see Protocol ). evaluate.py reports bootstrap 95% CIs for any checkpoint. More figures (PR curves, confusion matrices, failure cases) are in images/ , and per-finding notes are in docs/ . Quick start git clone https://github.com/AtomicHalifax/ChestXRay-Disease-Classification cd ChestXRay-Disease-Classification pip install -e " .[demo] " # Predict on your own image (weights auto-download from Hugging Face) python -m chexpert_cls.predict xray.jpg --gradcam out/ # Local Gradio demo with Grad-CAM python app.py Weights: AtomicHalifax/ChestXRay-DenseNet121 on Hugging Face. Serve it (API + Docker) docker compose up --build # API :8000 (/docs), MLflow :5000, Prometheus :9090, Grafana :3000 curl -F file=@xray.jpg localhost:8000/predict curl -F file=@xray.jpg -o cam.png " localhost:8000/explain?finding=Edema " Endpoint What it does GET /health Liveness check, used by the Docker healthcheck GET /version API version, model version, SHA-256 of the loaded weights POST /predict Five probabilities, the top finding, input-quality warnings, latency POST /explain Grad-CAM overlay PNG for one finding GET /drift Drift status: PSI per finding over recent predictions ( stable / moderate_shift / major_shift ) GET /metrics Prometheus metrics: request counts, latency, prediction distribution (for drift monitoring) MLOps Full write-up: MLOPS.md . train.csv ──► validate_csv ──► train.py ──► MLflow (params, metrics, best.pth) β”‚ β–Ό Hugging Face Hub (versioned weights, SHA-256 pinned) β”‚ evaluate.py ──► valid_report.json ──► quality gate (vs models/baseline_metrics.json) └─► valid_predictions.npz ──► drift reference (models/drift_reference.json) β”‚ git push ──► CI: ruff + pytest + gate ──► docker build ──► container smoke test └─► promtool: check config + unit-test alert rules └─► Website: ONNX export ──► parity check ──► GitHub Pages git tag v* ──► Release: build image (weights baked in) ──► ghcr.io/<owner>/chexpert-api β”‚ β–Ό FastAPI service ──► /metrics ──► Prometheus (alert rules) ──► Grafana dashboard └─► /drift (PSI of recent predictions vs validation reference) Data validation: validate_csv checks columns, label values, duplicate paths and path layout before training starts. Experiment tracking: train.py --mlflow logs every run's params, per-epoch metrics, final validation AUROCs and artifacts. Model versioning: MODEL_VERSION is on every API response. Setting CHEXPERT_WEIGHTS_SHA256 stops the service from starting if the weights file differs. Input guard: the API warns about (or, with CHEXPERT_STRICT_INPUT=1 , rejects) images that are colour, tiny or oddly shaped. Quality gate: python -m chexpert_cls.gate --candidate <report> fails if mean AUROC drops more than 0.01, or any finding drops more than 0.03, against the committed baseline. CI runs it automatically when models/candidate_metrics.json is committed. Drift detection: the API keeps the last 500 predictions and compares each finding's probability distribution with the validation set, using the Population Stability Index (PSI). It's exposed at /drift and as the chexpert_drift_psi metric. Build the reference with python -m chexpert_cls.drift --predictions results/valid_predictions.npz . Monitoring: docker compose up also starts Prometheus (:9090) and Grafana (:3000), with a pre-built dashboard covering traffic, error ratio, p50/p95 latency, mean prediction per finding and drift. Four alert rules (API down, error rate >10%, p95 latency >2 s, PSI >0.25) are checked and unit-tested with promtool in CI. CI/CD: every push runs lint, unit and API tests, builds the image and smoke-tests the container. A v* tag publishes the image to GHCR. Dependabot opens weekly update PRs, gated by CI. Browser release: pages.yml exports the model to ONNX, checks it against PyTorch and Grad-CAM, and deploys the website . Security: PNG/JPEG only, 10 MB read cap, decompression-bomb guard, 30 POSTs/min per IP, CORS locked to the site + localhost, no secrets in the repo. Details in MLOPS.md . Batch drift check + external validation: before trusting the model on a new dataset, run python -m chexpert_cls.drift_check new_images/ . It reports input-quality problems, PSI drift per finding, and, given labels (a generic CSV or NIH ChestX-ray14 format), AUROC with 95% CIs on that dataset. --fail-on-shift makes it exit non-zero on a major shift. A plain-language walkthrough of the whole project is in docs/HOW_IT_WORKS.md . Try it with sample images make samples # 20 openly licensed chest X-rays (Wikimedia Commons) + 4 deliberately bad inputs python -m chexpert_cls.drift_check samples/xray/ for f in samples/xray/ * .png samples/bad_inputs/ * ; do curl -s -F file=@ $f localhost:8000/predict ; echo ; done Credits and licences are in samples/manifest.json . The "expected" findings come from the uploaders' descriptions; they are not verified labels. To compare against real radiologist labels, scripts/make_test_set.py copies a small labelled set out of your own CheXpert download (research licence: keep it private). Reproduce training and evaluation Get CheXpert-v1.0-small from Stanford AIMI (or the Kaggle mirror ). Point --data-root at the folder containing train.csv and valid.csv . python -m chexpert_cls.train --data-root data/CheXpert-v1.0-small --epochs 10 --policy ignore --pos-weight python -m chexpert_cls.evaluate --data-root data/CheXpert-v1.0-small --weights runs/densenet121/best.pth Or run everything on Colab with notebooks/02_retrain_and_external_validation.ipynb : retrain with MLflow tracking, evaluate, quality gate, build the drift reference, and test on NIH ChestX-ray14. Protocol v1.0 (notebook) v1.1 ( src/ ) Training images 159,329 of 223,414. Rows with any uncertain (-1) target dropped (U-Ignore). Same by default; --policy ones/zeros available Views Frontal + lateral Same; --frontal-only available Loss BCE with per-class pos_weight Same ( --pos-weight ) Optimiser Adam 1e-4, 10 epochs, batch 32, 224 px Adam 1e-4 + cosine decay, AMP on GPU, fixed seed Checkpoint selection Mean AUROC on the validation set (leaks) Mean AUROC on a 5% patient-disjoint split of train Reporting Point AUROC AUROC + bootstrap 95% CI, AP, ECE, sens/spec Hardware 1Γ— Tesla T4 (Colab), ~4.5 h Same This is a reproduction of the DenseNet121 U-Ignore baseline from the CheXpert paper (Irvin et al., 2019), at lower resolution (224 vs 320 px) and with a single model instead of an ensemble. Use the paper's Table 2 for a like-for-like reference. Repository layout src/chexpert_cls/ config, data (label policies, patient split), validation, model, train, evaluate, predict, gradcam, metrics, gate (quality gate), drift (PSI), drift_check (batch drift + external validation), api (FastAPI service) models/ baseline_metrics.json (gate baseline); drift_reference.json once built app.py Gradio demo (local) tests/ pytest: labels, patient split, metrics, validation, model, Grad-CAM, API contract Dockerfile CPU inference image (non-root, healthcheck, optional baked weights) docker-compose.yml API + MLflow + Prometheus + Grafana monitoring/ Prometheus config, alert rules + their unit tests, Grafana dashboard scripts/ fetch_samples, make_test_set, export_onnx (browser model + parity check) samples/ manifest.json of demo images (images themselves are downloaded, not committed) docs/index.html the website (GitHub Pages) .github/workflows/ ci.yml (lint, tests, docker smoke test), pages.yml (ONNX + website), release.yml (GHCR image) .github/dependabot.yml weekly dependency update PRs notebooks/ original exploration (00) and evaluation (01); 02 = Colab retrain + external validation docs/ website, plus dataset, architecture, training, evaluation and limitations notes images/ evaluation figures Limitations Trained and evaluated only on CheXpert: a single hospital, mostly adult inpatients, many AP portable films. External validation on NIH ChestX-ray14 is set up (notebook 02) but has not been run yet. The training labels come from an NLP labeller run on radiology reports, so they're noisy. The validation set is small (234 images). Grad-CAM shows where the model's evidence is. It doesn't show that the model is right, and it can highlight support devices or text markers. A threshold of 0.5 is arbitrary. Operating points should be tuned per finding on held-out data. More detail is in docs/LIMITATIONS.md . Next steps Live website with in-browser inference and live pipeline status Retrain with v1.1 protocol and report CIs U-Ones vs U-Ignore ablation, 320 px input Run notebook 02: v1.1 retrain + NIH ChestX-ray14 external validation Per-finding calibration (temperature scaling) and operating points int8 browser model with the same parity check References Irvin et al. CheXpert: A Large Chest Radiograph Dataset with Uncertainty Labels and Expert Comparison. AAAI 2019. Huang et al. Densely Connected Convolutional Networks. CVPR 2017. Selvaraju et al. Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization. ICCV 2017. Built by Athrva Raval (BSc Data Science & AI, IIT Guwahati). Website Β· LinkedIn MIT License. CheXpert data is subject to Stanford's own research-use agreement.

A multi-label classifier for five chest X-ray findings: Atelectasis, Cardiomegaly, Consolidation, Edema, Pleural Effusion . It uses a DenseNet121 fine-tuned on 159,329 Stanford CheXpert images, with Grad-CAM explanations, wrapped in a full MLOps pipeline: data validation, experiment tracking, a quality gate that blocks worse models, drift monitoring, a hardened API, CI/CD, and a browser build checked against PyTorch before every release.

The demo runs the model in your browser (ONNX), so images never leave your device. The page also shows the live CI/CD status and the model card.

These are measured on the official CheXpert validation set: 234 images , labelled by radiologist consensus.

Read this before quoting the number. In v1.0 the best epoch was chosen using this same validation set. Across epochs 6–10 the mean AUROC moved between 0.854 and 0.879 , so 0.879 is the most favourable of five looks at a small set. With only 234 images, per-finding AUROCs also carry roughly Β±0.03–0.06 of sampling noise. The v1.1 code below fixes the selection leak (see Protocol ). evaluate.py reports bootstrap 95% CIs for any checkpoint.

More figures (PR curves, confusion matrices, failure cases) are in images/ , and per-finding notes are in docs/ .

git clone https://github.com/AtomicHalifax/ChestXRay-Disease-Classification cd ChestXRay-Disease-Classification pip install -e " .[demo] " # Predict on your own image (weights auto-download from Hugging Face) python -m chexpert_cls.predict xray.jpg --gradcam out/ # Local Gradio demo with Grad-CAM python app.py

docker compose up --build # API :8000 (/docs), MLflow :5000, Prometheus :9090, Grafana :3000 curl -F file=@xray.jpg localhost:8000/predict curl -F file=@xray.jpg -o cam.png " localhost:8000/explain?finding=Edema "

train.csv ──► validate_csv ──► train.py ──► MLflow (params, metrics, best.pth) β”‚ β–Ό Hugging Face Hub (versioned weights, SHA-256 pinned) β”‚ evaluate.py ──► valid_report.json ──► quality gate (vs models/baseline_metrics.json) └─► valid_predictions.npz ──► drift reference (models/drift_reference.json) β”‚ git push ──► CI: ruff + pytest + gate ──► docker build ──► container smoke test └─► promtool: check config + unit-test alert rules └─► Website: ONNX export ──► parity check ──► GitHub Pages git tag v* ──► Release: build image (weights baked in) ──► ghcr.io/<owner>/chexpert-api β”‚ β–Ό FastAPI service ──► /metrics ──► Prometheus (alert rules) ──► Grafana dashboard └─► /drift (PSI of recent predictions vs validation reference)

2. Related Work, Literature Survey & Algorithmic Foundations

Data validation: validate_csv checks columns, label values, duplicate paths and path layout before training starts.

Experiment tracking: train.py --mlflow logs every run's params, per-epoch metrics, final validation AUROCs and artifacts.

Model versioning: MODEL_VERSION is on every API response. Setting CHEXPERT_WEIGHTS_SHA256 stops the service from starting if the weights file differs.

Input guard: the API warns about (or, with CHEXPERT_STRICT_INPUT=1 , rejects) images that are colour, tiny or oddly shaped.

Quality gate: python -m chexpert_cls.gate --candidate <report> fails if mean AUROC drops more than 0.01, or any finding drops more than 0.03, against the committed baseline. CI runs it automatically when models/candidate_metrics.json is committed.

Drift detection: the API keeps the last 500 predictions and compares each finding's probability distribution with the validation set, using the Population Stability Index (PSI). It's exposed at /drift and as the chexpert_drift_psi metric. Build the reference with python -m chexpert_cls.drift --predictions results/valid_predictions.npz .

Monitoring: docker compose up also starts Prometheus (:9090) and Grafana (:3000), with a pre-built dashboard covering traffic, error ratio, p50/p95 latency, mean prediction per finding and drift. Four alert rules (API down, error rate >10%, p95 latency >2 s, PSI >0.25) are checked and unit-tested with promtool in CI.

CI/CD: every push runs lint, unit and API tests, builds the image and smoke-tests the container. A v* tag publishes the image to GHCR. Dependabot opens weekly update PRs, gated by CI.

Browser release: pages.yml exports the model to ONNX, checks it against PyTorch and Grad-CAM, and deploys the website .

3. Dataset Ingestion, Preprocessing & Stochastic Augmentations

Security: PNG/JPEG only, 10 MB read cap, decompression-bomb guard, 30 POSTs/min per IP, CORS locked to the site + localhost, no secrets in the repo. Details in MLOPS.md .

Batch drift check + external validation: before trusting the model on a new dataset, run python -m chexpert_cls.drift_check new_images/ . It reports input-quality problems, PSI drift per finding, and, given labels (a generic CSV or NIH ChestX-ray14 format), AUROC with 95% CIs on that dataset. --fail-on-shift makes it exit non-zero on a major shift.

make samples # 20 openly licensed chest X-rays (Wikimedia Commons) + 4 deliberately bad inputs python -m chexpert_cls.drift_check samples/xray/ for f in samples/xray/ * .png samples/bad_inputs/ * ; do curl -s -F file=@ $f localhost:8000/predict ; echo ; done

Credits and licences are in samples/manifest.json . The "expected" findings come from the uploaders' descriptions; they are not verified labels. To compare against real radiologist labels, scripts/make_test_set.py copies a small labelled set out of your own CheXpert download (research licence: keep it private).

Get CheXpert-v1.0-small from Stanford AIMI (or the Kaggle mirror ). Point --data-root at the folder containing train.csv and valid.csv .

python -m chexpert_cls.train --data-root data/CheXpert-v1.0-small --epochs 10 --policy ignore --pos-weight python -m chexpert_cls.evaluate --data-root data/CheXpert-v1.0-small --weights runs/densenet121/best.pth

Or run everything on Colab with notebooks/02_retrain_and_external_validation.ipynb : retrain with MLflow tracking, evaluate, quality gate, build the drift reference, and test on NIH ChestX-ray14.

This is a reproduction of the DenseNet121 U-Ignore baseline from the CheXpert paper (Irvin et al., 2019), at lower resolution (224 vs 320 px) and with a single model instead of an ensemble. Use the paper's Table 2 for a like-for-like reference.

src/chexpert_cls/ config, data (label policies, patient split), validation, model, train, evaluate, predict, gradcam, metrics, gate (quality gate), drift (PSI), drift_check (batch drift + external validation), api (FastAPI service) models/ baseline_metrics.json (gate baseline); drift_reference.json once built app.py Gradio demo (local) tests/ pytest: labels, patient split, metrics, validation, model, Grad-CAM, API contract Dockerfile CPU inference image (non-root, healthcheck, optional baked weights) docker-compose.yml API + MLflow + Prometheus + Grafana monitoring/ Prometheus config, alert rules + their unit tests, Grafana dashboard scripts/ fetch_samples, make_test_set, export_onnx (browser model + parity check) samples/ manifest.json of demo images (images themselves are downloaded, not committed) docs/index.html the website (GitHub Pages) .github/workflows/ ci.yml (lint, tests, docker smoke test), pages.yml (ONNX + website), release.yml (GHCR image) .github/dependabot.yml weekly dependency update PRs notebooks/ original exploration (00) and evaluation (01); 02 = Colab retrain + external validation docs/ website, plus dataset, architecture, training, evaluation and limitations notes images/ evaluation figures

4. Neural Network Backbone, Layer Specifications & Loss Formulations

Multi-label chest X-ray disease classification using DenseNet121 on the Stanford CheXpert dataset with Grad-CAM explainability and comprehensive evaluation.

Chest-Xray-Pneumonia-Classifier A deep learning model built with PyTorch to classify chest X-ray images into normal or diseased categories using a pretrained ResNet18 architecture. Trained on a labeled dataset of chest X-rays for automated medical diagnosis support. πŸ” Overview This project uses ResNet-18 to detect pneumonia from chest X-ray images. Both a scratch-trained and a pretrained version of the model were evaluated. 🧠 Model Performance Model Overall Accuracy Normal Accuracy Pneumonia Accuracy ResNet-Scratch 86.38% 70.51% 95.90% ResNet-Pretrained 90.87% 85.04% 94.36% βœ… The pretrained model significantly improved classification of normal cases while maintaining high pneumonia accuracy. βš™οΈ Setup Install required packages: pip install torch torchvision matplotlib numpy πŸ“₯ Dataset To train and evaluate the model, you'll need the chest X-ray image dataset. πŸ“¦ Download chest_xray_images.zip from Google Drive After downloading, unzip it and place the folder like this: Chest-Xray-Classifier/ β”œβ”€β”€ chest_xray_images/

A deep learning model built with PyTorch to classify chest X-ray images into normal or diseased categories using a pretrained ResNet18 architecture. Trained on a labeled dataset of chest X-rays for automated medical diagnosis support.

This project uses ResNet-18 to detect pneumonia from chest X-ray images. Both a scratch-trained and a pretrained version of the model were evaluated.

βœ… The pretrained model significantly improved classification of normal cases while maintaining high pneumonia accuracy.

After downloading, unzip it and place the folder like this: Chest-Xray-Classifier/ β”œβ”€β”€ chest_xray_images/

A deep learning model built with PyTorch to classify chest X-ray images into normal or diseased categories using a pretrained ResNet18 architecture. Trained on a labeled dataset of chest X-rays for automated medical diagnosis support.

Chest-X-Ray-Medical-Diagnosis-with-Deep-Learning Diagnose 14 pathologies on Chest X-Ray using Deep Learning. Perform diagnostic interpretation using GradCAM Method Project Description This project is a complilation of several sub-projects from Coursera 3-course IA for Medical Specialization . The objective is to use a deep learning model to diagnose pathologies from Chest X-Rays. The project uses a pretrained DenseNet-121 model able to diagnose 14 labels such as Cardiomegaly, Mass, Pneumothorax or Edema. In other words, this single model can provide binary classification predictions for each of the 14 labeled pathologies. Weight normalization is performed to offset the low prevalence of the abnormalities among the dataset of X-Rays (class imbalance). Finally the GradCAM technique is used to highlight and visualize where the model is looking, which area of interest is used to make the prediction. This is a tool which can be helpful for discovery of markers, error analysis, training and even in deployment. Dataset The project uses chest x-ray images taken from the public ChestX-ray8 dataset . This dataset contains 108,948 frontal-view X-ray images of 32,717 unique patients. Each image in the data set contains multiple text-mined labels identifying 14 different pathological conditions. These in turn can be used by physicians to diagnose 8 different diseases. For the project we have been working with a ~1000 image subset of the images. 875 images to be used for training. 109 images to be used for validation. 420 images to be used for testing. The dataset includes a CSV file that provides the ground truth labels for each X-ray. DenseNet highlights DenseNet was introduced in 2017 in an award-winning paper by Gao Huang et al. 2018 called Densely Connected Convolutional Networks . The model was able to outperform previous architectures like ResNet (which I covered in a another project Skin Cancer AI dermatologist ). Regardless of the architectural designs of these networks, they all try to create channels for information to flow between the initial layers and the final layers. DenseNet, with the same objective, create paths between the layers of the network. Parts of this summary are can be found in this review . DenseNet key novelty: Densenet is a convolutional network where each layer is connected to all other layers that are deeper in the network The first layer is connected to the 2nd, 3rd, 4th etc. The second layer is connected to the 3rd, 4th, 5th etc. Each layer in a dense block receives feature maps from all the preceding layers, and passes its output to all subsequent layers. Feature maps received from other layers are fused through concatenation, and not through summation (like in ResNets). Extracted feature maps are continuously added together with previous ones which avoids redundant and duplicate work. This allows the network to re-use learned information and be more efficient. Such networks require fewer layers. State of the art results are achieved with as low as 12 channel feature maps. This also means the network has fewer parameters to learn and is therefore easier to train. Amongst all variants, DenseNet-121 is the standard one. Key contributions of the DenseNet architecture: Alleviates vanishing gradient problem ( as networks get deeper, gradients aren’t back-propagated sufficiently to the initial layers of the network. The gradients keep getting smaller as they move backwards into the network and as a result, the initial layers lose their capacity to learn the basic low-level features) Stronger feature propagation Feature re-use Reduced parameter count DenseNet architecture DenseNet is composed of Dense blocks. In those blocks, the layers are densely connected together: Each layer receive in input all previous layers output feature maps. The DenseNet-121 comprises 4 dense blocks, which themselves comprise 6 to 24 dense layers. Dense block: A dense block comprises n dense layers. These dense layers are connected such that each dense layer receives feature maps from all preceding layers and passes it’s feature maps to all subsequent layers. The dimensions of the features (width, height) stay the same in a dense block. Dense layer: Each dense-layer consists of 2 convolutional operations. 1 X 1 CONV (conventional conv operation for extracting features) 3 X 3 CONV (bringing down the feature depth/channel count) The CONV layer corresponds to the sequence BatchNorm->ReLU->Conv. A layer has each sequence repeated twice, the first with 1x1 Convolution bottleneck producing: grow rate x 4 feature maps, the second with 3x3 convolution. The authors found that the pre-activation mode (BN and ReLU before the Conv) was more efficient than the usual post-activation mode. The growth rate (k= 32 for DenseNet-121) defines the number of output feature maps of a layer. Basically the layers output 32 feature maps which are added to a number of 32 feature maps from previous layers. While the depth increases continuously, each layer bring back the depth to 32. Transition layer: In between dense blocks, you find Transition layer. Instead of summing the residual like in ResNet, DenseNet concatenates all the feature maps. A transition layer is made of: Batch Normalization -> 1x1 Convolution -> Average pooling. Transition layers between two dense blocks ensure the down-sampling role (x and y dimensions halved), essential to CNN. Transition layers also compress the feature map and reduce the channels by half. This contributes to the compactness of the network. Although Concatenating generates a lot of input channels, DenseNet’s convolution generates a low number of feature maps (The authors recommend 32 for optimal performance but world-class performance was achieved with only 12 output channels). Key benefits: Compactness. DenseNet-201 with 20M parameters yields similar validation error as a 101-layer ResNet with 45M parameters. The learned features are non-redundant as they are all shared through a common knowledge. Easier to train because the gradient is flowing back more easily thanks to the short connections. Model settings In this project, the model uses 320 x 320 X-Rays images and outputs predictions for each of the 14 pathologies as illustrated below on a sample image. Environment and dependencies In order to run the model, I used an environment with tensorflow 1.15.0 and Keras 2.1.6. Model weights are provided in the repo. Results I used a pre-trained model which performance can be evaluated using the ROC curve shown at the bottom. The best results are achieved for Cardiomegaly (0.9 AUC), Edema (0.86) and Mass (0.82). Ideally we want to be significantly closer to 1. You can check out below the performance from the ChexNeXt paper and their model as well as radiologists on this dataset. Looking at unseen X-Rays, the model correctly predicts the predominant pathology, generating a somehow accurate diagnotic, highlighting the key region underlying its predictions. In addition to the main diagnostic (highest prediction), the model also predicts secondary issues similarly to what a radiologist would comment as part of his analysis. This can be either false positive from noise captured in the X-rays or cumulated pathologies. The model correctly predicts Cardiomegaly and absence of mass or edema. The probability for mass is higher, and we can see that it may be influenced by the shapes in the middle of the chest cavity, as well as around the shoulder. The model picks up the mass near the center of the chest cavity on the right. Edema has a high score for this image, though the ground truth doesn't mention it. Here the model correctly picks up the signs of edema near the bottom of the chest cavity. We can also notice that Cardiomegaly has a high score for this image, though the ground truth doesn't include it. This visualization might be helpful for error analysis; for example, we can notice that the model is indeed looking at the expected area to make the prediction. Performance from the ChexNeXt paper (model as well as radiologists):

Diagnose 14 pathologies on Chest X-Ray using Deep Learning. Perform diagnostic interpretation using GradCAM Method

5. Training Protocol, Convergence Behavior & Experimental Evaluation

This project is a complilation of several sub-projects from Coursera 3-course IA for Medical Specialization . The objective is to use a deep learning model to diagnose pathologies from Chest X-Rays.

The project uses a pretrained DenseNet-121 model able to diagnose 14 labels such as Cardiomegaly, Mass, Pneumothorax or Edema. In other words, this single model can provide binary classification predictions for each of the 14 labeled pathologies.

Weight normalization is performed to offset the low prevalence of the abnormalities among the dataset of X-Rays (class imbalance).

Finally the GradCAM technique is used to highlight and visualize where the model is looking, which area of interest is used to make the prediction. This is a tool which can be helpful for discovery of markers, error analysis, training and even in deployment.

The project uses chest x-ray images taken from the public ChestX-ray8 dataset . This dataset contains 108,948 frontal-view X-ray images of 32,717 unique patients. Each image in the data set contains multiple text-mined labels identifying 14 different pathological conditions. These in turn can be used by physicians to diagnose 8 different diseases. For the project we have been working with a ~1000 image subset of the images.

DenseNet was introduced in 2017 in an award-winning paper by Gao Huang et al. 2018 called Densely Connected Convolutional Networks . The model was able to outperform previous architectures like ResNet (which I covered in a another project Skin Cancer AI dermatologist ).

Regardless of the architectural designs of these networks, they all try to create channels for information to flow between the initial layers and the final layers. DenseNet, with the same objective, create paths between the layers of the network. Parts of this summary are can be found in this review .

Each layer in a dense block receives feature maps from all the preceding layers, and passes its output to all subsequent layers. Feature maps received from other layers are fused through concatenation, and not through summation (like in ResNets). Extracted feature maps are continuously added together with previous ones which avoids redundant and duplicate work.

This allows the network to re-use learned information and be more efficient. Such networks require fewer layers. State of the art results are achieved with as low as 12 channel feature maps. This also means the network has fewer parameters to learn and is therefore easier to train. Amongst all variants, DenseNet-121 is the standard one.

Model Figures & Evaluation Curves (4 Images)

Neural Architecture Diagram: Chest Xray Classification Ai
Neural Architecture Diagram: Chest Xray Classification Ai
Neural Architecture Diagram: Chest Xray Classification Ai
Neural Architecture Diagram: Chest Xray Classification Ai
Neural Architecture Diagram: Chest Xray Classification Ai
Neural Architecture Diagram: Chest Xray Classification Ai
Neural Architecture Diagram: Chest Xray Classification Ai
Neural Architecture Diagram: Chest Xray Classification Ai

Deep Learning Execution Pipeline

πŸ“₯ Input Tensors
(Preprocessing)
β†’
⚑ Backbone
(Feature Extraction)
β†’
🧠 Latent Space
(Self-Attention)
β†’
🎯 Output Head
(Loss Optimization)