Skip to content

Repository files navigation

GrayNet: A Grayscale-Native CNN for Brain Tumor MRI Classification

Streamlit App Python License Model

GrayNet is a lightweight, purpose-built convolutional neural network designed exclusively for single-channel (grayscale) medical imaging. Unlike conventional architectures that repurpose RGB-pretrained backbones and discard two-thirds of their learned color representations, GrayNet treats grayscale as a first-class input modality — every module in the pipeline is engineered to extract the maximum signal from a single intensity channel.

This repository provides the complete research pipeline: data integrity auditing, dataset construction, model training with 5-fold cross-validation, knowledge distillation for edge deployment, ablation studies, explainability visualisations, and modular benchmarking tools for paper-ready metrics.


🚀 Quick Demo

Run the Streamlit app locally:

pip install -r requirements_app.txt
streamlit run app.py

The app runs a 5-fold ensemble of GrayNet Mini (110K params) with:

  • ✅ Exact training preprocessing (InstanceNormalize — not (x-0.5)/0.5)
  • ✅ Analytical Grad-CAM in a single forward pass (no backprop needed)
  • ✅ 🔒 100% local inference — your MRI never leaves your machine

Related: GreyNet-Website — a companion Next.js app that runs GrayNet fully in the browser via ONNX Runtime Web (zero server, offline-capable, WebAssembly inference).


Key Contributions

  1. Exposing Data Leakage in Public Benchmarks. Using Perceptual Hashing (pHash), we discovered a 31.44% test-to-train leakage rate in one of the most widely cited brain tumor datasets on Kaggle, and 16.20% in the BRISC dataset. Published results trained and evaluated on these leaked splits are unreliable.

  2. A Verified 0%-Leakage Dataset. We merged the two source datasets, deduplicated across all 13,200 images (removing 6,308 near-duplicates at a Hamming distance threshold ≤ 3), and produced a mathematically verified, 6,892-image clean dataset split into 5 stratified folds for rigorous cross-validation.

  3. The GrayNet Architecture. An 813K-parameter model featuring six novel or adapted modules — ACE, TEB, MSDC, FAM, SFA, and CBAM++ — achieves 98.11% accuracy (98.13% with TTA) on the 0%-leakage benchmark, while remaining small enough for edge deployment.

  4. Parametric Width Scaling. A single architecture with width multiplier $w$ spans five deployment tiers from 813K (Master) to 24.7K (Femto) parameters, maintaining >97% accuracy at all scales.


Model Zoo

All models are evaluated via 5-fold cross-validation on the verified 0%-leakage dataset. Latency is measured on a single NVIDIA GPU with batch size 1.

Model Params Size (KB) CPU 1T (ms) CPU 4T (ms) GPU (ms) Std Acc (%) TTA Acc (%)
GrayNet Master 813.1K 3,290 101.98 38.60 3.73 98.11 98.13
GrayNet Lite 249.5K 1,066 48.79 22.32 3.98 97.87 97.98
GrayNet Mini 110.5K 515 31.92 17.26 3.83 97.87 97.95
GrayNet Pico 52.9K 282 23.59 14.78 3.80 97.66 97.75
GrayNet Femto 24.7K 168 29.69 30.49 8.72 96.94 97.42

Key finding: GrayNet Pico (52.9K parameters) achieves 97.75% TTA accuracy while delivering a 4.3× CPU speedup (23.59 ms vs 101.98 ms), proving that depthwise-separable width scaling enables ultra-fast edge inference with minimal diagnostic accuracy loss.


Architecture

GrayNet is a 10-stage pipeline with a width_mult parameter that uniformly scales all channel counts, enabling a family of models from 24.7K to 813K parameters using a single architecture definition.

graph TD
    classDef stem fill:#2c3e50,stroke:#34495e,stroke-width:2px,color:#fff;
    classDef contrast fill:#d35400,stroke:#e67e22,stroke-width:2px,color:#fff;
    classDef texture fill:#f39c12,stroke:#f1c40f,stroke-width:2px,color:#fff;
    classDef attention fill:#8e44ad,stroke:#9b59b6,stroke-width:2px,color:#fff;
    classDef conv fill:#2980b9,stroke:#3498db,stroke-width:2px,color:#fff;
    classDef stats fill:#27ae60,stroke:#2ecc71,stroke-width:2px,color:#fff;
    classDef head fill:#c0392b,stroke:#e74c3c,stroke-width:2px,color:#fff;

    Input["MRI Input (1ch, 256x256)"] --> Stem["GrayscaleStem (Stage 1)<br>1 → 24ch"]:::stem
    Stem --> ACE["ACE Block (Stage 2)<br>Adaptive Contrast Maps"]:::contrast
    ACE --> TEB["TEB Block (Stage 3)<br>Multi-scale Textures"]:::texture
    TEB --> FAMFine["FAM-Fine (Stage 4)<br>FFT Spectral Attention"]:::attention
    FAMFine --> MSDCA["MSDC-A x2 (Stage 5a)<br>Ghost 5x5 Conv (112 to 56)"]:::conv
    MSDCA --> SFA["SFA Block (Stage 5b)<br>Statistical Entropy Proxy"]:::stats
    SFA --> MSDCB["MSDC-B x2 (Stage 5c)<br>Ghost 5x5 Conv (56 to 28)"]:::conv
    MSDCB --> CBAM["CBAM++ (Stage 5d)<br>VarPool Attention"]:::attention
    CBAM --> MSDCC["MSDC-C x1 (Stage 5e)<br>Ghost 5x5 Conv (28 to 14)"]:::conv
    MSDCC --> FAMCoarse["FAM-Coarse (Stage 5f)<br>FFT Spectral Attention"]:::attention
    FAMCoarse --> Head["Dual-Pool Head (Stage 6)<br>AvgPool + MaxPool → Logits"]:::head
Loading

Core Modules

Module File Purpose
ACE — Adaptive Contrast Enhancement ace.py Learns spatially-varying gain (0, 2) and bias maps via shared depthwise context. Enables both suppression and amplification of local contrast — critical for faint low-grade glioma borders.
TEB — Texture Extraction Block teb.py Four parallel depthwise paths (3×3, 5×5, 7×7, dilated-3×3) capture multi-scale texture, then project from 24 → 64 channels with a residual shortcut.
MSDC — Multi-Scale Depthwise Conv msdc.py Inverted bottleneck block with GhostNet-inspired 5×5 cheap operations for wider texture receptive fields at minimal parameter cost. Includes stochastic depth (DropPath).
FAM — Frequency Attention Module fam.py Performs FFT, applies a two-factor spectral mask (static learnable freq_mask × dynamic per-image MLP gate), then IFFT. Used at both fine (128×128) and coarse (16×16) resolutions.
SFA — Statistical Feature Aggregator sfa.py Computes local variance and log-variance (differential entropy proxy) at dual window sizes (3×3, 5×5), fuses with original features via learned sigmoid gate.
CBAM++ — Channel + Spatial Attention cbam.py Three-branch channel attention (AvgPool, MaxPool, VarPool) with a shared MLP, followed by spatial attention. VarPool adds sensitivity to heterogeneous tumor textures.
Focal Loss loss.py Class-imbalance-aware loss with configurable gamma, label smoothing, and per-class weights.
Edge Metrics edge_metrics.py Computes FLOPs, multi-device latency (CPU 1T/4T, GPU), throughput, peak memory, and model size for deployment profiling.

Repository Structure

graynet/
├── graynet/                     # Core PyTorch architecture package
│   ├── model.py                 # Full GrayNet model assembly
│   ├── stem.py                  # Stage 1: Grayscale-native stem
│   ├── ace.py                   # Stage 2: Adaptive Contrast Enhancement
│   ├── teb.py                   # Stage 3: Texture Extraction Block
│   ├── msdc.py                  # MSDC blocks with Ghost convolutions
│   ├── fam.py                   # Frequency Attention Module (FFT-based)
│   ├── sfa.py                   # Statistical Feature Aggregator
│   ├── cbam.py                  # CBAM++ with VarPool
│   ├── head.py                  # Dual-pool classification head
│   ├── loss.py                  # Focal Loss implementation
│   └── edge_metrics.py          # Deployment profiling (FLOPs, latency, memory)
│
├── data/                        # PyTorch data loading module
│   └── dataset.py               # GrayscaleImageFolder, augmentations, BrainCropTransform
│
├── dataset/                     # Dataset construction pipeline
│   ├── 01_check_leakage.py      # pHash-based train/test leakage detection
│   ├── 02_merge_datasets.py     # Cross-dataset merging and class standardisation
│   ├── 03_clean_duplicates.py   # Perceptual deduplication (Hamming ≤ 3)
│   ├── 04_create_folds.py       # Stratified 5-fold split generation
│   ├── raw/                     # Original source datasets (BRISC, BTD)
│   ├── intermediate/            # Merged intermediate datasets
│   ├── processed/               # Clean dataset and 5-fold splits
│   └── reports/                 # Leakage and duplication audit reports (.xlsx)
│
├── configs/                     # YAML training configurations
│   ├── master.yaml              # GrayNet Master (width_mult=1.0, 813K params)
│   ├── 250k.yaml                # GrayNet Lite  (width_mult≈0.55, 249.5K params)
│   ├── 100k.yaml                # GrayNet Mini  (width_mult≈0.35, 110.5K params)
│   ├── 50k.yaml                 # GrayNet Pico  (width_mult≈0.23, 52.9K params)
│   └── 25k.yaml                 # GrayNet Femto (width_mult≈0.15, 24.7K params)
│
├── runs/                        # Training outputs (checkpoints, logs, reports)
│   ├── master/                  # GrayNet Master (5 folds + master_teacher/)
│   ├── 250k_lite/               # Each run contains fold_1/ … fold_5/
│   ├── 100k_mini/               #   └── best_model.pt, train.log,
│   ├── 50k_pico/                #       classification_report_fold_*.txt
│   ├── 25k_femto/
│   ├── training_convergence_report.md
│   └── defence_training_convergence_report.md
│
├── ablation/                    # Self-contained ablation study workspace
│   ├── run_all_ablations.py     # One-click runner for all 7 experiments
│   ├── configs/                 # Per-experiment YAML configs (no_ace, no_teb, etc.)
│   ├── graynet/                 # Local copy of architecture with ablation flags
│   ├── results/                 # Comprehensive ablation report (Markdown)
│   └── README.md                # Ablation study documentation
│
├── scripts/                     # Utility and analysis scripts
│   ├── research_metrics/        # Modular CLI tools for paper metrics
│   │   ├── compute_params.py    # Parameter count
│   │   ├── compute_size.py      # Model size (KB)
│   │   ├── compute_flops.py     # FLOPs / MACs via thop
│   │   ├── compute_latency.py   # CPU/GPU latency benchmarking
│   │   ├── compute_acc.py       # 5-fold accuracy + TTA evaluation
│   │   └── orchestrate_all_metrics.py  # Full benchmark across all 9 models
│   ├── evaluation/              # Model evaluation and error analysis
│   ├── explainability/          # GradCAM, GradCAM++, ScoreCAM, Occlusion maps
│   ├── architecture/            # Architecture validation, width search, ONNX export
│   ├── data_processing/         # Dataset download and preprocessing
│   └── publishing/              # Paper PDF generation (Springer LNCS format)
│
├── plots/                       # Latency scaling visualisations
│
├── train.py                     # Single-run training script
├── train_kfold.py               # 5-fold cross-validation training
├── requirements.txt             # Python dependencies
└── LICENSE                      # MIT License

Setup & Installation

Prerequisites

  • Python ≥ 3.9
  • CUDA-capable GPU (recommended; CPU training is supported but slow)

Install

git clone https://github.com/yourusername/graynet.git
cd graynet
pip install -r requirements.txt

Dataset

The raw MRI images are not included in the repository. To build the verified dataset from scratch, follow the step-by-step instructions in the Dataset README. The pipeline will:

  1. Audit the original train/test splits for leakage (01_check_leakage.py)
  2. Merge and standardise class names across datasets (02_merge_datasets.py)
  3. Deduplicate using perceptual hashing at Hamming distance ≤ 3 (03_clean_duplicates.py)
  4. Generate stratified 5-fold cross-validation splits (04_create_folds.py)

Training

All training scripts accept a --config flag pointing to a YAML configuration file. Configs specify the model architecture (width multiplier, dropout, input size), data paths, optimiser settings, scheduler, and logging directory.

1. Train the Master Model (5-Fold Cross-Validation)

Trains GrayNet at full width (width_mult=1.0, 813K params) across all 5 folds.

python train_kfold.py --config configs/master.yaml

To train only specific folds:

python train_kfold.py --config configs/master.yaml --folds 1 3 5

Training features include:

  • Cosine annealing with linear warmup
  • Mixed precision training (AMP)
  • Focal Loss with class weights and label smoothing
  • Exponential Moving Average (EMA) with decay warmup
  • Stochastic Weight Averaging (SWA) over the final training window
  • Test Time Augmentation (TTA) — 5-view MRI-appropriate ensemble
  • Automatic best-method selection (Standard / EMA / SWA / TTA combinations)
  • CutMix support (disabled by default — proven harmful on this dataset)
  • Per-fold classification reports with edge deployment metrics

2. Single-Run Training

For quick prototyping or non-cross-validated experiments:

python train.py --config configs/master.yaml

Research Metrics

The scripts/research_metrics/ directory provides modular CLI tools that can extract individual metrics for any model configuration:

# Parameter count
python scripts/research_metrics/compute_params.py --config configs/master.yaml

# FLOPs and MACs
python scripts/research_metrics/compute_flops.py --config configs/25k.yaml

# CPU/GPU latency benchmarking
python scripts/research_metrics/compute_latency.py --config configs/100k.yaml

# 5-fold accuracy with TTA
python scripts/research_metrics/compute_acc.py --config configs/100k.yaml --run runs/100k_mini

To regenerate the full metrics table across all models:

python scripts/research_metrics/orchestrate_all_metrics.py

Ablation Study

The ablation/ directory is a fully self-contained workspace that measures the contribution of each architectural module. Seven experiments systematically remove individual components (ACE, TEB, FAM, SFA, CBAM++, Ghost convolutions, dual-pool head) and retrain from scratch to quantify their impact.

cd ablation
python run_all_ablations.py

Results are documented in ablation/results/comprehensive_ablation_report.md. See the Ablation README for full details.


Explainability

The scripts/explainability/ directory generates publication-quality visual interpretability maps to validate that GrayNet's predictions are grounded in clinically relevant features rather than spurious artefacts:

  • GradCAM and GradCAM++ — gradient-weighted class activation maps
  • ScoreCAM — gradient-free activation mapping
  • Occlusion Sensitivity — systematic region masking
  • Segmentation Overlay — CAM-derived tumor region segmentation on MRI scans

Outputs (including Monte Carlo Dropout uncertainty analysis) are stored in scripts/outputs/.


Data Pipeline

The data/dataset.py module provides the PyTorch data loading infrastructure:

  • GrayscaleImageFolder — grayscale-native dataset loader with automatic class discovery
  • InstanceNormalize — per-image zero-mean/unit-std normalisation that handles scanner variation (1.5T vs 3T MRI) without destroying inter-class intensity differences
  • BrainCropTransform — Otsu-based skull stripping and ROI extraction, ensuring 100% of input resolution is dedicated to brain tissue
  • Train augmentations — RandomResizedCrop, flips, rotation, affine, colour jitter, and RandomErasing
  • Validation transforms — deterministic resize + centre crop with InstanceNormalize

Dataset Integrity

Our dataset pipeline exposed severe integrity issues in popular public benchmarks:

Dataset Train Images Test Images Leaked Test Images Leakage Rate
Brain Tumour Dataset (Kaggle) 5,600 1,600 503 31.44%
BRISC 5,000 1,000 162 16.20%

After merging and deduplication, 6,308 duplicate images (47.79%) were removed from the combined 13,200-image pool, yielding a final clean dataset of 6,892 unique images distributed across 4 classes (Glioma, Meningioma, Pituitary, No Tumor).

Full methodology and per-class statistics are documented in the Dataset README.


Configuration Reference

Each YAML config controls the full training pipeline. Key parameters:

model:
  width_mult: 1.0         # Channel scaling (1.0=813K, 0.55=250K, 0.35=110K, 0.23=53K, 0.15=25K)
  dropout: 0.2            # Classifier dropout
  drop_path_rate: 0.05    # Stochastic depth rate
  input_size: 224         # Input resolution

training:
  epochs: 400             # Maximum training epochs
  lr: 1.0e-3              # Peak learning rate
  patience: 80            # Early stopping patience
  use_ema: true           # Exponential Moving Average
  swa_window: 25          # SWA rolling window size
  fam_lr_scale: 0.1       # Reduced LR for FAM freq_mask parameters

License

This project is licensed under the MIT License — see LICENSE for details.

Copyright (c) 2026 Author A, Author B

Citation

If you use the GrayNet architecture or our cleaned dataset in your research, please cite:

@article{graynet2026,
  title   = {GrayNet: A Grayscale-Native CNN for Brain Tumor MRI Classification},
  author  = {Rama ,Hari krishna},
  year    = {2026}
}

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages