File size: 9,473 Bytes
888b377 6b52e57 888b377 6b52e57 888b377 6b52e57 b842c0f 6b52e57 b842c0f 6b52e57 b842c0f 6b52e57 b842c0f 6b52e57 b842c0f 6b52e57 b842c0f 6b52e57 b842c0f 6b52e57 b842c0f 6b52e57 b842c0f 6b52e57 b842c0f 6b52e57 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | ---
title: Skin Disease Detection Demo
emoji: π©Ί
colorFrom: blue
colorTo: pink
sdk: gradio
sdk_version: 4.44.0
app_file: app.py
pinned: false
license: apache-2.0
---
# π©Ί Skin Disease Detection β Demo
A demo Space with four tabs:
- **π· Quick Image Check** β upload a photo (or click a test image), get a
classifier prediction plus an LLM-generated plain-language assessment with
an explicit **Low / Medium / High severity** call.
- **π¬ Chat Assistant** β a multi-turn triage conversation. It asks about
onset, evolution, symptoms, triggers, and history over several exchanges
before giving a narrowed, severity-rated preliminary read β more targeted
than a single photo alone could support, without claiming false certainty.
- **π Model Performance** β real test-set metrics (accuracy, per-class
precision/recall/F1, confusion matrix) for whichever fine-tuned model(s)
are backing the app, pulled from `assets/`.
- **βΉοΈ About** β what this is, what models it uses, and its limitations.
> β οΈ **This is a research/portfolio demo, not a medical device.** It does not
> diagnose anyone with certainty. Always see a licensed dermatologist or
> doctor for real concerns.
## How it works
| Component | What it does | Default model |
|---|---|---|
| Image classifier | Predicts a skin condition category from a photo | [`Anwarkh1/Skin_Cancer-Image_Classification`](https://huggingface.co/Anwarkh1/Skin_Cancer-Image_Classification) (ViT, 7-class HAM10000) β recommended upgrade: train `finetune_unified_skin_model.ipynb` (24-class, see below) and point `IMAGE_MODEL_ID` at it |
| Second-opinion lesion model *(optional, redundant if using the unified model)* | Re-checks images the primary model flags as an ambiguous melanoma/mole label | Off by default β set `LESION_MODEL_ID` to a HAM10000-based model to enable |
| Chat / explanation | Multi-turn triage with enforced minimum question rounds, turns predictions into plain language | `Qwen/Qwen2.5-7B-Instruct` via the Hugging Face Inference Providers router |
All three model IDs are configurable via Space variables β see below.
## Multi-round chat behavior
The chat tab doesn't just *ask* the model to have a longer conversation β
`app.py` counts user turns explicitly and injects a stage-aware instruction
on every call (`MIN_ROUNDS_BEFORE_ASSESSMENT = 4` by default, adjustable
in code): before that many exchanges, the model is told to keep gathering
information; after, it's told enough rounds have happened and to give its
assessment. Red-flag symptoms override this and get addressed immediately
regardless of turn count.
## Severity levels
Every assessment states one of three levels explicitly:
- π΄ **High** β cancer-related, ambiguous-but-could-be-serious, systemic/
autoimmune conditions, or red-flag symptoms. Recommends seeing a doctor soon.
- π‘ **Medium** β likely needs a proper diagnosis and prescription
(infections, infestations). Recommends a doctor visit, not urgent.
- π’ **Low** β typically manageable with general skin care. Doctor visit
optional.
Tiering is **keyword-based** (see `classify_tier()` in `app.py`), so it works
across different classifier taxonomies without hardcoding every exact label
string β including correctly flagging DermNet's mixed
*"Melanoma Skin Cancer, Nevi and Moles"* label as High by default, since that
one label can't distinguish the dangerous case from the harmless one.
## π Deploy in 3 steps
1. **Create a new Space**
Go to [huggingface.co/new-space](https://huggingface.co/new-space) β
choose **Gradio** as the SDK β CPU basic hardware is fine for the classifier
(or ZeroGPU if you want faster inference β see the `@spaces.GPU` decorator
already applied to `diagnose_image`).
2. **Upload these files**
Upload `app.py`, `requirements.txt`, this `README.md`, the `examples/`
folder (if you generated test images), and the `assets/` folder (if you
exported model performance metrics β see below), either via the web UI
("Add file") or:
```bash
git clone https://huggingface.co/spaces/<your-username>/<your-space-name>
cp -r app.py requirements.txt README.md examples assets <your-space-name>/
cd <your-space-name>
git add . && git commit -m "Initial commit" && git push
```
3. **Add an `HF_TOKEN` secret (to enable the chatbot)**
In your Space β **Settings β Variables and secrets** β **New secret**:
- Name: `HF_TOKEN`
- Value: a Hugging Face access token (create one at
[huggingface.co/settings/tokens](https://huggingface.co/settings/tokens),
"Read" scope is enough)
Without this secret, image classification still works β only the
LLM-generated explanations and the chat tab need the token.
That's it β the Space will build and the app will be live.
## πΌοΈ Adding test images (optional but recommended)
So users have something to click without needing their own photo, generate a
few sample images once, locally, before you push:
```bash
pip install datasets pillow
python scripts/download_examples.py
```
This saves a handful of JPEGs into `examples/`. Include that folder when you
push to your Space. You can also just drop in your own sample `.jpg`/`.png`
files instead.
## βοΈ Configuration
Set these as Space **variables** (not secret, unless noted) to customize:
- `IMAGE_MODEL_ID` β any Hugging Face image-classification model compatible
with `transformers.pipeline("image-classification", ...)`.
- `LESION_MODEL_ID` *(optional)* β a second, pigmented-lesion-specific model
(like the HAM10000 fine-tune below) used automatically as a second opinion
when the primary model's top prediction is an ambiguous melanoma/mole label.
Leave unset to disable.
- `CHAT_MODEL_ID` β any chat-completion-capable model available via the HF
Inference Providers router.
- `HF_TOKEN` *(secret)* β required for the chat tab and the LLM explanations.
## π§ Fine-tuning your own model
Three self-contained Colab notebooks are included:
### `finetune_unified_skin_model.ipynb` β β recommended: 24-class unified model
- **Retrained from scratch**, not resumed β fresh weights each run
- Merges DermNet's 22 clean categories with HAM10000's melanoma and nevi
as their own separate classes, **replacing DermNet's ambiguous combined
"Melanoma Skin Cancer, Nevi and Moles" label entirely** β melanoma finally
gets a clean training signal instead of being merged with benign moles
- Early stopping (up to 14 epochs, stops automatically once validation
macro-F1 plateaus) + cosine LR schedule β addresses the previous
DermNet-only run's validation loss not having converged at 6 epochs
- Melanoma threshold-tuning (now meaningful, since melanoma is unambiguous)
- Exports `unified_metrics.json` + `unified_confusion_matrix.png`
- **Honest tradeoff:** melanoma/nevi images come from HAM10000's
dermatoscope close-ups, not regular phone photos like the rest of the
dataset β a real domain gap, flagged in the notebook rather than hidden
### `finetune_skin_lesion_model.ipynb` β 7-class pigmented lesions (HAM10000 only)
- Useful if you want a smaller, faster, cancer-focused model specifically
- class-weighted loss, melanoma recall tracking, threshold tuning
- exports `ham10000_metrics.json` + `ham10000_confusion_matrix.png`
### `finetune_dermnet_23class.ipynb` β 23-class DermNet only (superseded by the unified notebook above, kept for reference)
- Same as the unified notebook's DermNet portion, but keeps DermNet's
original ambiguous melanoma/nevi label instead of replacing it
- exports `dermnet_metrics.json` + `dermnet_confusion_matrix.png`
**To use any of them:** upload the `.ipynb` to
[Google Colab](https://colab.research.google.com), set **Runtime β Change
runtime type β T4 GPU**, and run cells top to bottom. The unified notebook
takes roughly 60β100 minutes on a free T4 depending on when early stopping
kicks in; keep the tab active so the session doesn't disconnect.
**Before treating any of these as more than a research project**, see the
"Next steps" section at the end of each notebook β a higher benchmark score
is not the same as a clinically validated model.
## π Populating the Model Performance tab
After running a fine-tuning notebook, download the two files it exports
(`*_metrics.json` and `*_confusion_matrix.png`) from Colab's file browser and
place them in this Space's `assets/` folder, then redeploy. The tab picks up
any matching pair automatically β you can have both the HAM10000 and DermNet
reports side by side if you've fine-tuned both.
## Limitations & responsible use
- Neither bundled classifier has been clinically validated β treat their
output as a talking point, not a result.
- Performance depends heavily on image quality, lighting, and skin tone
representation in the training data; public dermatology datasets skew
toward lighter skin tones.
- DermNet's melanoma/nevi label limitation (above) means that category's
severity is intentionally conservative rather than precise.
- This app must not be used as a substitute for professional medical
evaluation. The chatbot is instructed to narrow toward likely categories
and state a severity level, but never to claim certainty, prescribe
treatment, or give dosages.
## Local development
```bash
pip install -r requirements.txt
export HF_TOKEN=your_token_here # optional, for chat
python app.py
```
|