Instructions to use krishBSSPL/lipiocr-classifier with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- timm
How to use krishBSSPL/lipiocr-classifier with timm:
import timm model = timm.create_model("hf-hub:krishBSSPL/lipiocr-classifier", pretrained=True) - Notebooks
- Google Colab
- Kaggle
Upload folder using huggingface_hub
Browse files- README.md +101 -0
- config.json +63 -0
- model.safetensors +3 -0
README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
tags:
|
| 4 |
+
- image-classification
|
| 5 |
+
- document-classification
|
| 6 |
+
- timm
|
| 7 |
+
- efficientnet
|
| 8 |
+
library_name: timm
|
| 9 |
+
pipeline_tag: image-classification
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
# LipiOCR Document Classifier
|
| 13 |
+
|
| 14 |
+
A lightweight document-type classifier — the classification stage of
|
| 15 |
+
**LipiOCR**, a fast document intelligence pipeline (classify → OCR →
|
| 16 |
+
QR/barcode decode → normalize) built as a speed-focused complement to
|
| 17 |
+
[ZuraAI-VL](https://ollama.com/bsspl/zuraai-vl-v3), a larger VLM used for
|
| 18 |
+
full structured extraction.
|
| 19 |
+
|
| 20 |
+
This model does one job well: given a photographed or scanned document,
|
| 21 |
+
tell you what type of document it is, in milliseconds, on CPU or GPU.
|
| 22 |
+
It does not read text — pair it with an OCR stage (LipiOCR uses
|
| 23 |
+
[glm-ocr](https://ollama.com/bsspl/glm-ocr)) for full extraction.
|
| 24 |
+
|
| 25 |
+
## Model details
|
| 26 |
+
|
| 27 |
+
- **Architecture:** EfficientNet-B0 (via `timm`), ImageNet-pretrained, fine-tuned end-to-end
|
| 28 |
+
- **Input:** 224×224 RGB image
|
| 29 |
+
- **Output:** 1 of 42 document type labels
|
| 30 |
+
- **Parameters:** ~5.3M
|
| 31 |
+
|
| 32 |
+
## Categories (42)
|
| 33 |
+
|
| 34 |
+
Identity: `aadhaar_card`, `cid`, `driving_license`, `nic`, `pan_card`, `passport`, `visa`, `voter_id`
|
| 35 |
+
Financial: `bank_cheque`, `bank_statement`, `invoice`, `pos_payment_slip`, `purchase_order`, `quotation`, `receipt`, `telegraphic_transfer`, `payment_voucher`, `credit_card`
|
| 36 |
+
Travel: `airway_bill`, `boarding_pass`, `courier_waybill`
|
| 37 |
+
Certificates: `birth_certificate`, `certificate`, `marriage_certificate`, `medical_certificate`, `vaccination_certificate`
|
| 38 |
+
Business/other: `business_card`, `employment_offer_letter`, `general_letter`, `income_tax_return`, `insurance_policy`, `marksheet`, `medical_prescription`, `menu_card`, `noc`, `product_catalog`, `reference_letter`, `rental_agreement`, `resume`, `salary_slip`, `utility_bill`, `vehicle_registration`
|
| 39 |
+
|
| 40 |
+
## Training data
|
| 41 |
+
|
| 42 |
+
- 7,227 training images across 42 categories, mostly synthetic (Faker-generated documents rendered with realistic layouts, colors, and — for the financial categories — real decodable QR/barcodes)
|
| 43 |
+
- A small set of real (non-synthetic) photographed/scanned documents, oversampled 15x during training to avoid being drowned out by the synthetic majority
|
| 44 |
+
- Training augmentation includes perspective warp, paper texture, directional lighting gradients, JPEG artifacts, and axis-aligned rotation — added specifically because a first version trained only on clean synthetic renders scored **0/11 on real photographed documents** despite 98%+ synthetic validation accuracy. These fixes brought real-document accuracy to roughly 90%+ on most categories (see Limitations).
|
| 45 |
+
|
| 46 |
+
## Performance
|
| 47 |
+
|
| 48 |
+
- **99.66%** validation accuracy on a held-out synthetic split (1,167 examples)
|
| 49 |
+
- **11/12** real photographed documents correctly classified in a spot validation across categories with real examples available
|
| 50 |
+
|
| 51 |
+
## Usage
|
| 52 |
+
|
| 53 |
+
```python
|
| 54 |
+
import json
|
| 55 |
+
import torch
|
| 56 |
+
import timm
|
| 57 |
+
from PIL import Image
|
| 58 |
+
from torchvision import transforms
|
| 59 |
+
from safetensors.torch import load_file
|
| 60 |
+
|
| 61 |
+
config = json.load(open("config.json"))
|
| 62 |
+
model = timm.create_model(config["architecture"], pretrained=False, num_classes=config["num_classes"])
|
| 63 |
+
model.load_state_dict(load_file("model.safetensors"))
|
| 64 |
+
model.eval()
|
| 65 |
+
|
| 66 |
+
preprocess = transforms.Compose([
|
| 67 |
+
transforms.Resize((224, 224)),
|
| 68 |
+
transforms.ToTensor(),
|
| 69 |
+
transforms.Normalize(config["normalize_mean"], config["normalize_std"]),
|
| 70 |
+
])
|
| 71 |
+
|
| 72 |
+
img = Image.open("document.jpg").convert("RGB")
|
| 73 |
+
# Recommended: run CLAHE contrast normalization + deskew on `img` before
|
| 74 |
+
# this step for best real-world accuracy - see preprocess.py in the
|
| 75 |
+
# LipiOCR repo. A plain resize works but skips that robustness step.
|
| 76 |
+
x = preprocess(img).unsqueeze(0)
|
| 77 |
+
|
| 78 |
+
with torch.no_grad():
|
| 79 |
+
probs = torch.softmax(model(x), dim=1)[0]
|
| 80 |
+
top = torch.argmax(probs).item()
|
| 81 |
+
print(config["labels"][top], probs[top].item())
|
| 82 |
+
```
|
| 83 |
+
|
| 84 |
+
## Limitations
|
| 85 |
+
|
| 86 |
+
- **Marksheet vs. resume confusion**: both render as structured line-item
|
| 87 |
+
lists (subjects/grades vs. job history/skills), and this remains the
|
| 88 |
+
weakest confusion pair in testing.
|
| 89 |
+
- **Real-world academic transcripts** (marksheets specifically) are the
|
| 90 |
+
hardest category — real institutions' transcript layouts vary far more
|
| 91 |
+
than any other document type, and the training set has limited real
|
| 92 |
+
examples for this category specifically (~40% real-world accuracy vs.
|
| 93 |
+
~90%+ for most other categories).
|
| 94 |
+
- Trained primarily on English-language, Latin-script documents.
|
| 95 |
+
- No language identification or OCR capability — classification only.
|
| 96 |
+
|
| 97 |
+
## Part of LipiOCR
|
| 98 |
+
|
| 99 |
+
This model is one stage of a larger pipeline. The full system (OCR
|
| 100 |
+
extraction, QR/barcode decoding, digit-swap correction, and field
|
| 101 |
+
normalization) lives in the LipiOCR project alongside this classifier.
|
config.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architecture": "efficientnet_b0",
|
| 3 |
+
"framework": "timm",
|
| 4 |
+
"num_classes": 42,
|
| 5 |
+
"labels": [
|
| 6 |
+
"aadhaar_card",
|
| 7 |
+
"airway_bill",
|
| 8 |
+
"bank_cheque",
|
| 9 |
+
"bank_statement",
|
| 10 |
+
"birth_certificate",
|
| 11 |
+
"boarding_pass",
|
| 12 |
+
"business_card",
|
| 13 |
+
"certificate",
|
| 14 |
+
"cid",
|
| 15 |
+
"courier_waybill",
|
| 16 |
+
"credit_card",
|
| 17 |
+
"driving_license",
|
| 18 |
+
"employment_offer_letter",
|
| 19 |
+
"general_letter",
|
| 20 |
+
"income_tax_return",
|
| 21 |
+
"insurance_policy",
|
| 22 |
+
"invoice",
|
| 23 |
+
"marksheet",
|
| 24 |
+
"marriage_certificate",
|
| 25 |
+
"medical_certificate",
|
| 26 |
+
"medical_prescription",
|
| 27 |
+
"menu_card",
|
| 28 |
+
"nic",
|
| 29 |
+
"noc",
|
| 30 |
+
"pan_card",
|
| 31 |
+
"passport",
|
| 32 |
+
"payment_voucher",
|
| 33 |
+
"pos_payment_slip",
|
| 34 |
+
"product_catalog",
|
| 35 |
+
"purchase_order",
|
| 36 |
+
"quotation",
|
| 37 |
+
"receipt",
|
| 38 |
+
"reference_letter",
|
| 39 |
+
"rental_agreement",
|
| 40 |
+
"resume",
|
| 41 |
+
"salary_slip",
|
| 42 |
+
"telegraphic_transfer",
|
| 43 |
+
"utility_bill",
|
| 44 |
+
"vaccination_certificate",
|
| 45 |
+
"vehicle_registration",
|
| 46 |
+
"visa",
|
| 47 |
+
"voter_id"
|
| 48 |
+
],
|
| 49 |
+
"input_size": [
|
| 50 |
+
224,
|
| 51 |
+
224
|
| 52 |
+
],
|
| 53 |
+
"normalize_mean": [
|
| 54 |
+
0.485,
|
| 55 |
+
0.456,
|
| 56 |
+
0.406
|
| 57 |
+
],
|
| 58 |
+
"normalize_std": [
|
| 59 |
+
0.229,
|
| 60 |
+
0.224,
|
| 61 |
+
0.225
|
| 62 |
+
]
|
| 63 |
+
}
|
model.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:03f49b561cb7932f0ce14bfaafa58a5009004551f0594d8dc4c6e98317d6ff47
|
| 3 |
+
size 16446552
|