Instructions to use phyloforfun/lm3_ruler_classifier_ensemble__dinov2_frozen_mlp with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use phyloforfun/lm3_ruler_classifier_ensemble__dinov2_frozen_mlp with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-classification", model="phyloforfun/lm3_ruler_classifier_ensemble__dinov2_frozen_mlp") pipe("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/parrots.png")# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("phyloforfun/lm3_ruler_classifier_ensemble__dinov2_frozen_mlp", device_map="auto") - Notebooks
- Google Colab
- Kaggle
lm3_ruler_classifier_ensemble__dinov2_frozen_mlp
Frozen DINOv2-base backbone with a trained MLP head, classifying ruler unit type (18 classes) on squarified ruler crops from herbarium specimen sheets. One of the three members of the default LeafMachine3 ruler_classifier ensemble (>= 3.0.0).
LM3 metadata
| Field | Value |
|---|---|
| LM3 action | ruler_classifier |
| LM3_default_model | true (as a member of the default 3-model ensemble) |
| LM3_version | 3.0.0 (minimum supported; later releases remain compatible) |
| Model key | dinov2_frozen_mlp |
| Ensemble | lm3_ruler_classifier_ensemble: yolo26x_cls_224, yolo26n_cls_224, dinov2_frozen_mlp; majority vote; 3-way ties fall back to yolo26x_cls_224 |
| Architecture | facebook/dinov2-base (ViT-B/14, frozen) CLS token -> MLP head (768 -> 512, GELU, dropout 0.2 -> 18) |
| Base weights | facebook/dinov2-base (Meta, Apache-2.0); only the head is trained |
| Input | squarified crop (see below), resize shortest side to 256 (bicubic), center crop 224 x 224, RGB in [0,1], ImageNet mean/std normalization |
| Output | raw logits over 18 classes (apply softmax), order in label_map.json |
| Classes (18) | FP, GRID_CM, METRIC_CM, METRIC_CM2, METRIC_CM4, METRIC_CM_BLOCK, METRIC_CM_STAGGER, METRIC_MM, METRIC_MM2, METRIC_MM_CM, METRIC_MM_CM_BLOCK, METRIC_MM_IN16, STD_IN16, STD_IN16_IN8_IN2, STD_IN32_IN16, STD_IN8, STD_IN8_CM, messy |
| Trained | 2026-10-07 |
| Iteration | 2: retrained on corrected labels; METRIC_MM_CM2 merged into METRIC_MM |
Files
| Folder | File | Use |
|---|---|---|
pytorch/ |
ckpt_best.pt |
backbone + head state (torch), retraining |
onnx/ |
model.onnx |
LM3 runtime (onnxruntime); backbone + head in one graph |
label_map.json |
class order shared by all ensemble members | |
docs/ |
example_{cm_tick,block,mm_tick}_{crop,squarified}.jpg |
before/after preprocessing examples |
SHA-256 of every file is in manifest.json.
Input preprocessing (what the model sees)
The model is never run on the raw ruler crop. Every Ruler crop from archival_detector is first squarified: rotated to landscape, converted to grayscale, and tiled into a 1440 x 1440 collage of four views of the same strip (LM2 tile_four: stacked / max-height / quartiles / nine). The collage is the prediction input (resized to 224 x 224 at inference). The classifier was trained only on such collages; feeding it a raw strip is unsupported.
Examples. Left: raw crop from the archival detector. Right: the squarified prediction input (1440 x 1440).
Training data
Dataset LM3_RulerCrops-h-squarify: 13,886 grayscale crops of every Ruler detection in the 67 LM3_Archival projects, rotated to landscape and squarified (LM2 tile_four, 1440 x 1440). Labels from the LM3 ruler cluster explorer (DB signature 8a11eecfc8e12bc1, 2026-10-07; class folders reviewed by hand); 13,707 labeled crops used. Stratified 70/15/15 split, seed 0. Train is tail-oversampled to 11,784 (cap 8x per class); val and test are not. Images and labels are not distributed.
| Class | train | val | test |
|---|---|---|---|
| FP | 2,231 | 478 | 478 |
| GRID_CM | 53 | 11 | 11 |
| METRIC_CM | 30 | 6 | 6 |
| METRIC_CM2 | 35 | 7 | 7 |
| METRIC_CM4 | 10 | 2 | 2 |
| METRIC_CM_BLOCK | 6 | 1 | 1 |
| METRIC_CM_STAGGER | 12 | 3 | 3 |
| METRIC_MM | 2,602 | 558 | 558 |
| METRIC_MM2 | 27 | 6 | 6 |
| METRIC_MM_CM | 2,418 | 518 | 518 |
| METRIC_MM_CM_BLOCK | 62 | 14 | 14 |
| METRIC_MM_IN16 | 15 | 3 | 3 |
| STD_IN16 | 595 | 127 | 127 |
| STD_IN16_IN8_IN2 | 6 | 1 | 1 |
| STD_IN32_IN16 | 3 | 1 | 1 |
| STD_IN8 | 1,067 | 228 | 228 |
| STD_IN8_CM | 399 | 86 | 86 |
| messy | 26 | 5 | 5 |
| total | 9,597 | 2,055 | 2,055 |
Training
Backbone frozen (0 trainable blocks); head trained on cached CLS embeddings of the training set. 40 epochs, batch 256, lr 1e-3, cross-entropy with effective-number class weights and a weighted random sampler, seed 0, no augmentation. Best val macro F1 0.954
Evaluation (test, 2,055 crops)
| Accuracy | Balanced accuracy | Macro F1 | Weighted F1 | ms / image (CUDA) |
|---|---|---|---|---|
| 0.989 | 0.978 | 0.918 | 0.990 | 22.6 |
Per-class F1 (support): FP 0.999 (478), GRID_CM 0.957 (11), METRIC_CM 1.000 (6), METRIC_CM2 1.000 (7), METRIC_CM4 1.000 (2), METRIC_CM_BLOCK 1.000 (1), METRIC_CM_STAGGER 1.000 (3), METRIC_MM 0.985 (558), METRIC_MM2 1.000 (6), METRIC_MM_CM 0.994 (518), METRIC_MM_CM_BLOCK 1.000 (14), METRIC_MM_IN16 0.800 (3), STD_IN16 0.953 (127), STD_IN16_IN8_IN2 0.500 (1), STD_IN32_IN16 0.667 (1), STD_IN8 1.000 (228), STD_IN8_CM 1.000 (86), messy 0.667 (5). Tail classes have 1 to 3 test images.
Use in LeafMachine3
Stage ruler_classifier (depends on archival_detector). Each Ruler crop is squarified (tile_four, sz=720, 1440 x 1440) exactly as in training, then each of the three ONNX members classifies it; the ensemble label is the class with >= 2 votes, falling back to the yolo26x_cls_224 vote on a 3-way disagreement. min_conf=0.35. Per-crop unit type and a per-specimen consensus are stored and consumed by ruler_cf (conversion factor). Feeding un-squarified strips to the model is not supported.
from huggingface_hub import hf_hub_download
path = hf_hub_download("phyloforfun/lm3_ruler_classifier_ensemble__dinov2_frozen_mlp", "onnx/model.onnx")
Citation
Weaver, W. N. (2026) LeafMachine3. https://leafmachine.org





