Flask / TensorFlow service for research and educational mole-image analysis used by the MoleCare skin-health apps.
Not a medical device. Predictions and ABCDE helpers are not diagnoses. Always seek care from a qualified clinician for concerning skin changes.
Sensitivity and AUC are now measured, and the model misses its targets on recent images. The results and their limits · why 94% meant very little
An image classifier — a convolutional neural network (CNN). It takes one picture and returns scores for a fixed set of classes. It does not generate text, does not hold a conversation, and is not a language model of any kind.
Here that is Xception: 20.9M parameters, 299×299 input, a TensorFlow
SavedModel of about 88 MB served by Flask. Test accuracy is 0.9422, and that is
the only thing measured — see the note above. The optional
/predict-advanced path is scaffolded for Google Derm Foundation
embeddings, a separate gated vision foundation model that Google now calls legacy
— see Derm Foundation, and what replaces it.
| Endpoint area | What it does |
|---|---|
/predict |
Melanoma vs not-melanoma score (baseline CNN) |
/analyze, /analyze/abcde |
Structured analysis + ABCDE-oriented CV signals |
/detect |
Lesion detection helpers |
/evolution |
Temporal comparison between images |
/predict-advanced, /compare-models |
Multi-model / premium paths (optional) |
/health |
Liveness |
Optional: Google Derm Foundation embeddings (gated model; requires Hugging Face token + acceptance of Google Health AI terms). See the status note below before building on it.
Two things are true about the /predict-advanced path, and both should be known
before anyone extends it.
It does not run today. DERM_FOUNDATION_AVAILABLE turns true only once a trained
classifier and scaler load, and neither artefact is in this repository;
scripts/train_derm_classifier.py is what would produce them. The path is scaffolding.
The model it is aimed at is legacy. Google's model card now states that Derm Foundation "is now legacy, but remains available for existing applications", and points new development at MedSigLIP — a 400M-parameter image/text encoder at 448×448 that also does zero-shot classification and semantic retrieval, rather than embeddings alone.
So the choice is to repoint this path at MedSigLIP or to delete it, and that choice is not only technical. The HAI-DEF terms define Clinical Use as "any use in diagnosis or treatment of patients", require Health Regulatory Authorization from the relevant authority where applicable, and make the developer solely responsible for validating the result. Measuring what is already deployed (#23) comes first: without sensitivity and AUC for the current model, a swap cannot be shown to have helped.
Requires Python 3.12+.
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt # or requirements.lock for the exact pinned set
# Fetch the trained SavedModel (~88 MB, published as a GitHub Release asset)
scripts/fetch-model.sh
export MODEL_PATH=./cnn-models/xception/1
gunicorn --bind 0.0.0.0:5000 --timeout 300 wsgiDocker:
scripts/fetch-model.sh # weights are not in git
docker build -f deploy/Dockerfile.web -t molecare-ml . # build from the repo root
docker run --rm -p 5000:5000 -e PORT=5000 molecare-ml
curl http://localhost:5000/healthThere is no Dockerfile at the repository root — pass -f to pick one. deploy/Dockerfile.web
is the Flask service; Dockerfile.lambda builds the AWS Lambda container image instead.
Compose (nginx + serving + app) lives in deploy/docker-compose.yml and builds from the
repository root:
scripts/fetch-model.sh
docker compose -f deploy/docker-compose.yml up --buildUse localhost only; do not bake cloud credentials into images.
| Variable | Purpose |
|---|---|
MODEL_PATH |
Path to TensorFlow SavedModel |
PORT |
HTTP port (default 5000) |
HUGGINGFACE_TOKEN |
Optional Derm Foundation access |
WANDB_API_KEY |
Optional training logging |
AWS_* |
Optional deploy tooling — use IAM roles / local profile, never commit keys |
CORS_ALLOWED_ORIGINS |
Comma-separated origin allowlist. Defaults to localhost only — set this in production |
MAX_UPLOAD_MB |
Maximum request body size, default 10. Oversized requests get a JSON 413 |
FLASK_DEBUG |
1 enables the Werkzeug debugger. Never set in production — it permits arbitrary code execution |
FLASK_HOST |
Bind address for local runs, default 127.0.0.1 |
doc/data.md is the first stop. No images ship with this repository, the loader expects a particular directory layout, and every open issue that needs the held-out test split starts there. It covers getting images from ISIC, the exact layout, why splitting at random inflates the score, and which class index melanoma actually is.
- Experiment notebooks live under
training-notebooks/ - Metaflow flow:
flows/training_flow.py(set your own S3 bucket via env/flags) - Public derm datasets (e.g. Kaggle) have their own licenses — document provenance before redistributing weights or images
Do not commit kaggle.json, AWS keys, or patient photos.
# Health
curl -s http://localhost:5000/health
# Predict — JSON body, base64 image (NOT multipart)
curl -s -X POST http://localhost:5000/predict \
-H 'Content-Type: application/json' \
-d "{\"predictionid\":\"$(uuidgen)\",\"imagebase64\":\"$(base64 < sample.jpg | tr -d '\n')\"}"/predict returns melanomaProbability (P(melanoma), 0-1). It also returns a deprecated
percent field which is P(not melanoma) as 0-100 — a high percent means low risk. Use
melanomaProbability.
See ml_model_serving/ for route definitions and response schemas. Responses include a
non-diagnostic disclaimer.
| Component | Notes |
|---|---|
| Xception / ImageNet-initialized Keras backbones | Follow TensorFlow / Keras license terms |
| Google Derm Foundation | Terms; HF gated |
| Training data | Cite dataset sources (ISIC / HAM10000 / your Kaggle dataset) and redistribution rules |
Publish large weights via GitHub Releases or object storage — avoid committing multi‑MB binaries if possible.
The models in this repository were trained on dermoscopic images from the
ISIC Archive (International Skin Imaging Collaboration).
No sample images ship in this repository: CI rejects image files, and the
dermoscopic samples that once lived under data/static/test_images/ were removed
before the code was published. Historical commits reference them by their ISIC
identifiers (for example ISIC_0034074.jpg).
No MoleCare user or patient images are included in this repository or its history.
ISIC Archive images are contributed under a range of licences (CC-0, CC-BY, CC-BY-NC) that vary by contributing collection. If you intend to use the trained weights commercially, verify the licence terms of the specific collections involved — a CC-BY-NC source restricts commercial redistribution of derived artefacts. Attribution to the ISIC Archive is expected in all cases.
Contributions are welcome. Start with CONTRIBUTING.md — in particular the
pre-commit install step, which prevents credentials and notebook data from entering git history.
- MODEL_CARD.md — what the model is, what was measured, and what was not
- SECURITY.md — reporting a vulnerability or a clinical-safety concern
- doc/data.md — how to get the training data, which most issues need first
- Good first issues
The open problem we care most about is performance across Fitzpatrick skin types, which is currently unmeasured. Why our 94% accuracy number means very little explains what was and was not evaluated and why the gap matters; the work itself is tracked in issue #10. Results that make the model look worse are as welcome as results that improve it.
- Intended: research, education, product prototyping behind MoleCare’s own clinical disclaimers
- Not intended: autonomous diagnosis, triage without a clinician, or regulatory claims
- Performance varies by skin type, lighting, image quality, and dataset bias — evaluate before any production use
- Never commit PEM files, AWS keys, or
.env - Rotate any credential that ever appeared in git history
- Keep nested product docs / runbooks out of this repository
See SECURITY.md for how to report anything that slipped through.
- MoleCare
- molecare-mcp — MCP server, assistant and ops tools
- Mobile apps on App Store and Google Play
Thank you to everyone who has helped molecare-ml.
The list is filled by Contributors from GitHub commits, bots omitted — never hand-maintained, because a stale list is worse than none. Contributor graph · good first issue
Licensed under the Apache License 2.0.
Third-party model and dataset licences still apply and are not granted by this licence — see Training data and provenance below.