AapdaSetu Damage Assessment β ResNet50
Post-disaster building damage classifier for the AapdaSetu platform. Given a photo of a disaster-affected building, the model classifies damage severity into one of three grades and drives automated compensation assessment in the AapdaSetu relief pipeline.
Part of the AapdaSetu project (Smart India Hackathon).
Live Deployment
The full assessment service (this model + EXIF authenticity checks + pHash duplicate detection + compensation estimation) is deployed and publicly accessible:
π https://aapdasetu-damage-api.onrender.com
- Interactive demo UI:
/Β· Swagger API docs:/docsΒ· Health check:/health - Main endpoint:
POST /api/assess-damage(multipart:photo,claimed_lat,claimed_lng,property_type,disaster_cutoff) - Production inference runs on ONNX Runtime using
best.onnxfrom this repo (torch-free, fits Render's 512 MB free tier). Free-tier instances sleep after ~15 min idle, so the first request after a pause cold-starts in a few seconds.
Model Details
| Architecture | ResNet50 (ImageNet-1K V2 pretrained backbone) + custom FC head (Dropout β Linear(2048, 3)) |
| Input | 224Γ224 RGB image |
| Preprocessing | Resize(256) β CenterCrop(224) β ToTensor β Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) |
| Classes | MINOR, MAJOR, DESTROYED (alphabetical ImageFolder order: DESTROYED=0, MAJOR=1, MINOR=2 β see class_mapping.json) |
| Checkpoint | best.pt (~271 MB, PyTorch dict β keys: model_state, class_to_idx, classes, epoch, val_acc, val_loss, optim_state) |
| ONNX export | best.onnx (~94 MB, opset 17, softmax baked in, input image, output scores, dynamic batch) β parity with PyTorch verified (max abs diff β 6e-8) |
Training Recipe
- Dataset: 2,400 post-disaster building images β MINOR (846), MAJOR (525), DESTROYED (1,029), split 75 / 15 / 10 per class with a leak check (image hashes verified disjoint across splits β see
leak_check.json). Dataset hosted at Divyanshu-Kumar19/aapdasetu-damage-dataset. - Two-phase training:
- Backbone frozen β only the new FC head trains
- Full fine-tuning of the entire network
- Evaluation: 5-crop Test-Time Augmentation (TTA) on the held-out test set.
Evaluation Results
Held-out test set (244 images), with TTA:
| Class | Precision | Recall | F1 | Support |
|---|---|---|---|---|
| DESTROYED | 0.990 | 0.981 | 0.986 | 104 |
| MAJOR | 0.982 | 1.000 | 0.991 | 54 |
| MINOR | 0.977 | 0.977 | 0.977 | 86 |
| Overall accuracy | 98.36% |
Full metrics: eval_report.json Β· Confusion matrix: confusion_matrix.png Β· ROC curves: roc_curves.png Β· Training curves: training_curves.png Β· Misclassified samples: misclassified.png Β· Training history: history.json Β· Split leak audit: leak_check.json
Quick Start β ONNX (recommended, CPU-friendly)
import json
import onnxruntime as ort
import numpy as np
from PIL import Image
from torchvision import transforms
mapping = json.load(open("class_mapping.json")) # {"DESTROYED": 0, "MAJOR": 1, "MINOR": 2}
idx_to_class = {int(v): k for k, v in mapping.items()}
transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
img = Image.open("building.jpg").convert("RGB")
x = transform(img).unsqueeze(0).numpy()
sess = ort.InferenceSession("best.onnx", providers=["CPUExecutionProvider"])
probs = sess.run(["scores"], {"image": x})[0][0] # softmax already baked in
print("Damage grade:", idx_to_class[int(probs.argmax())])
print("All scores:", {idx_to_class[i]: round(float(p), 4) for i, p in enumerate(probs)})
Quick Start β PyTorch (best.pt)
import torch
import torch.nn as nn
from torchvision import models, transforms
from PIL import Image
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 1. Build the exact architecture used during training
model = models.resnet50(weights=None)
model.fc = nn.Sequential(
nn.Dropout(p=0.0), # training-only; inert at inference
nn.Linear(model.fc.in_features, 3),
)
# 2. Load the checkpoint
ckpt = torch.load("best.pt", map_location=device, weights_only=True)
model.load_state_dict(ckpt["model_state"])
model.to(device).eval()
# 3. IMPORTANT β use the checkpoint's index->class mapping.
# ImageFolder trained classes in ALPHABETICAL order
# (DESTROYED=0, MAJOR=1, MINOR=2), NOT ["MINOR", "MAJOR", "DESTROYED"].
idx_to_class = {int(v): k for k, v in ckpt["class_to_idx"].items()}
# 4. Preprocess exactly like training validation
transform = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
# 5. Predict
img = Image.open("building.jpg").convert("RGB")
x = transform(img).unsqueeze(0).to(device)
with torch.no_grad():
probs = torch.softmax(model(x), dim=1)[0]
scores = {idx_to_class[i]: round(float(p), 4) for i, p in enumerate(probs)}
print("Damage grade:", idx_to_class[int(probs.argmax())])
print("All scores:", scores)
Download the checkpoints with:
hf download Divyanshu-Kumar19/aapdasetu-damage-assessment --local-dir ./model
Intended Use
- Triage of post-disaster building damage photos in the AapdaSetu claim pipeline (maps grade β compensation under NDRF/SDRF norms).
- Not a substitute for a certified structural engineer's assessment.
- Out of scope: images that are not disaster-affected buildings, and safety-critical decisions without human review.
Files in This Repository
| File | Description |
|---|---|
best.pt |
Trained PyTorch checkpoint (state dict + metadata) |
best.onnx |
ONNX export for CPU inference (softmax baked in) β used by the live deployment |
class_mapping.json |
Class β index mapping (DESTROYED=0, MAJOR=1, MINOR=2) |
eval_report.json |
Per-class precision / recall / F1 on the test set |
confusion_matrix.png |
Confusion matrix visualization |
roc_curves.png |
One-vs-rest ROC curves |
training_curves.png |
Train/val loss & accuracy curves |
confidence_distribution.png |
Prediction confidence distribution |
misclassified.png |
Test samples the model got wrong |
history.json |
Per-epoch training history |
leak_check.json |
Train/val/test split leak audit |
License
MIT
Evaluation results
- accuracy on AapdaSetu Building Damage Datasetself-reported98.36%