- Nepali Banknote Models
- Pipeline Overview
- Model 1: ConvNeXt Tiny β Binary Classifier (
best_model_convnext_tiny_20260810_1038.pth) - Model 2: YOLO β Denomination Detector (
best.pt) - Model 3: RFDETR-Large β Signature Detector (
detector.pth) - Model 4: Swin-Base β Signature Classifier (
classifier.pth) - Model 5: Year Detector + Classifier (
year/best.pt,year/best_classifier.pt) - File Inventory
- Additional Model (not in this repo)
- License
- Pipeline Overview
Nepali Banknote Models
A collection of models for the bankNotes-OCR pipeline β a hierarchical 2-stage banknote retrieval system for Nepalese banknotes.
Pipeline Overview
Query Image
βββ Stage 0: ConvNeXt Tiny Binary Classifier (banknote vs. random)
βββ Stage 1a: YOLO Denomination Detector (11 denominations)
βββ Stage 1b: RFDETR + Swin Signature Classifier (20 governors)
βββ Stage 1c: YOLO + MobileNetV3 Year Classifier
βββ Stage 2: DinoV2-Base patch embeddings + Qdrant vector search
Model 1: ConvNeXt Tiny β Binary Classifier (best_model_convnext_tiny_20260810_1038.pth)
Stage 0: Determines if an image is a banknote or a random image. This is the current model used by the pipeline (since 2026-08-10).
| Architecture | convnext_tiny (torchvision) |
| Classes | 2: random (0), banknote (1) |
| Input size | 224x224 RGB |
| Normalization | ImageNet mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225] |
| Precision | FP32 |
| Weight size | ~334 MB |
| Checkpoint format | dict: config + model_state_dict (+ optimizer, epoch, best_score) |
from huggingface_hub import hf_hub_download
import torch
from src.models.resnet import get_model
model_path = hf_hub_download(
"Imbatmann/nepali-banknote-models",
"best_model_convnext_tiny_20260810_1038.pth",
)
checkpoint = torch.load(model_path, map_location="cpu", weights_only=False)
model = get_model(model_name=checkpoint["config"]["model_name"],
num_classes=checkpoint["config"]["num_classes"],
pretrained=False)
model.load_state_dict(checkpoint["model_state_dict"])
model.eval()
Training checkpoints can be recreated from the deploy package (
deploy-noteclassifer.zip,deploy/models/model_zoo.py). The classifier head isnn.Sequential(Dropout(0.2), Linear(in_features, num_classes)), identical tocreate_convnext_tiny_modelinsrc/models/resnet.py.
Model 2: YOLO β Denomination Detector (best.pt)
Stage 1a: Detects and classifies the denomination of a banknote.
| Architecture | YOLO (Ultralytics) |
| Classes (11) | 1, 2, 5, 10, 20, 25, 50, 100, 250, 500, 1000 |
| Input size | 640x640 RGB |
| Weight size | ~113 MB |
from ultralytics import YOLO
from huggingface_hub import hf_hub_download
model_path = hf_hub_download("Imbatmann/nepali-banknote-models", "best.pt")
model = YOLO(str(model_path))
results = model("image.jpg", conf=0.5, device="cpu")
Model 3: RFDETR-Large β Signature Detector (detector.pth)
Stage 1b: Detects the governor signature region on a banknote.
| Architecture | RFDETRLarge (rfdetr library) |
| Detection threshold | 0.3 |
| Weight size | ~128 MB |
from rfdetr import RFDETRLarge
from huggingface_hub import hf_hub_download
model_path = hf_hub_download("Imbatmann/nepali-banknote-models", "detector.pth")
detector = RFDETRLarge.from_checkpoint(model_path, device="cpu")
Model 4: Swin-Base β Signature Classifier (classifier.pth)
Stage 1b: Classifies a cropped signature region into one of 20 Nepali governors.
| Architecture | swin_base_patch4_window7_224 (timm) |
| Classes | 20 Nepali governors |
| Input size | 224x224 RGB |
| Normalization | ImageNet mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225] |
| Weight size | ~331 MB |
Governor Classes
Bharat_Raj_Pandey, Bhekh_Bahadur_Thapa, Bijaynath_Bhattarai,
Chiranjibi_Nepal, Dipendra_Purush_Dhakal, Ganesh_Bahadur_Thapa,
Hari_Shankar_Tripathi, Himalaya_SJB_Rana, Janak_Raj_Pandey,
Kalyan_Bikram_Adhikari, Krishna_Bahadur_Manandhar, Kul_Sekhar_Sharma,
Laxmi_Nath_Gautam, Maha_Prasad_Adhikari, Narendra_Raj_Pandey,
Pradhumna_Lal_Rajbhandari, Satyendra_Pyara_Shrestha,
Tilak_Bahadur_Rawal, Yadav_Prasad_Pant, Yubaraj_Khatiwada
import timm
import torch
from huggingface_hub import hf_hub_download
model_path = hf_hub_download("Imbatmann/nepali-banknote-models", "classifier.pth")
model = timm.create_model("swin_base_patch4_window7_224", pretrained=False, num_classes=20)
model.load_state_dict(torch.load(model_path, map_location="cpu"))
model.eval()
Model 5: Year Detector + Classifier (year/best.pt, year/best_classifier.pt)
Stage 1c: Detects the year region (YOLO) and classifies the Nepali year (e.g. "BS 2077").
| Detector | YOLO (year/best.pt) |
| Classifier | MobileNetV3-Small (year/best_classifier.pt) |
from ultralytics import YOLO
from huggingface_hub import hf_hub_download
det = hf_hub_download("Imbatmann/nepali-banknote-models", "year/best.pt")
model = YOLO(str(det))
File Inventory
| File | Stage | Architecture | Precision | Status |
|---|---|---|---|---|
best_model_convnext_tiny_20260810_1038.pth |
0 β banknote | ConvNeXt-Tiny | FP32 (~334 MB) | CURRENT (2026-08-10) |
best_model.pth |
0 β banknote (legacy) | ResNet101 | FP32 (~177 MB) | legacy fallback |
best_model_fp16.pth |
0 β banknote (legacy) | ResNet101 | FP16 (~86 MB) | legacy fallback |
best_model_quantized.pth |
0 β banknote (legacy) | ResNet101 (quantized) | int8 | legacy |
best.pt |
1a β denomination | YOLO | FP32 (~113 MB) | current |
detector.pth |
1b β signature detect | RFDETR-Large | FP32 (~128 MB) | current |
classifier.pth |
1b β signature classify | Swin-Base | FP32 (~331 MB) | current |
year/best.pt |
1c β year detect | YOLO | FP32 | current |
year/best_classifier.pt |
1c β year classify | MobileNetV3-Small | FP32 | current |
year_best.pt |
1c β year (legacy) | YOLO | β | legacy duplicate of year/best.pt |
The app code (
src/services/banknote_classifier_service.py) loads the ConvNeXt-Tiny file first, then falls back to the legacy ResNet101 files if the download fails. Old files are kept for rollback β do not delete.
Additional Model (not in this repo)
| Model | Source | Purpose |
|---|---|---|
| DinoV2-Base | facebook/dinov2-base |
Stage 2 β patch-level embeddings for visual similarity search |
License
MIT