rice-disease-net

DINOv2-large fine-tuned to classify 15 paddy disease and stress conditions from field photographs. Trained on a deduplicated multi-source dataset of 9,376 images spanning Tamil Nadu, Bangladesh, and laboratory conditions.

Test accuracy: 92.96% · Weighted F1: 0.9288 · 15 classes · 304M parameters

Model Details

Property Value
Backbone facebook/dinov2-large (304M params)
Head Linear(1024→512, GELU) → Dropout(0.3) → Linear(512→15)
Training Linear probe (5 epochs) → Full fine-tune (24 epochs, early stopping)
Optimizer AdamW, head LR 1e-4, backbone LR 1e-5
Schedule Cosine decay with 5-epoch linear warmup
Hardware 2× RTX 3090, BF16 mixed precision, accelerate
Input size 224×224 RGB
Normalization DINOv2 standard (mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225])

Input / Output

Input

A single RGB paddy leaf or plant photograph. The model works best on:

  • Clear images of individual leaves or panicles
  • Field or laboratory lighting (not heavily shadowed)
  • Paddy/rice plants (Oryza sativa) only — not validated on other crops
from PIL import Image
from transformers import AutoImageProcessor

processor = AutoImageProcessor.from_pretrained("harinpurumandla/rice-disease-net")
image = Image.open("paddy_leaf.jpg").convert("RGB")

# Returns dict with "pixel_values" tensor of shape (1, 3, 224, 224)
inputs = processor(images=image, return_tensors="pt")

Output

Raw logits tensor of shape (batch_size, 15). Higher logit = higher confidence for that class. Apply softmax for probabilities.

import torch, json

config = json.load(open("config.json"))
idx_to_class = config["idx_to_class"]

with torch.no_grad():
    logits = model(inputs["pixel_values"])   # (1, 15)
    probs = torch.softmax(logits, dim=1)     # (1, 15)
    pred_idx = probs.argmax(dim=1).item()
    confidence = probs[0, pred_idx].item()

print(f"Predicted: {idx_to_class[str(pred_idx)]}  ({confidence:.1%} confidence)")
# Example: "Predicted: blast  (87.3% confidence)"

Full inference example

import json, torch
from PIL import Image
from transformers import AutoImageProcessor

# --- load once at startup ---
import sys
sys.path.insert(0, "path/to/rice-disease-net")
sys.path.insert(0, "path/to/rice-disease-net/train")
from train.model import PaddyClassifier

config = json.load(open("config.json"))
processor = AutoImageProcessor.from_pretrained("harinpurumandla/rice-disease-net")

model = PaddyClassifier(num_classes=15, hidden_dim=512, dropout=0.3)
from safetensors.torch import load_file
model.load_state_dict(load_file("model.safetensors"))
model.eval()

# --- per-image inference ---
def predict(image_path: str) -> dict:
    image = Image.open(image_path).convert("RGB")
    pixel_values = processor(images=image, return_tensors="pt")["pixel_values"]
    with torch.no_grad():
        probs = torch.softmax(model(pixel_values), dim=1)[0]
    idx = probs.argmax().item()
    return {
        "class": config["idx_to_class"][str(idx)],
        "confidence": round(probs[idx].item(), 4),
        "all_probs": {config["idx_to_class"][str(i)]: round(p.item(), 4)
                      for i, p in enumerate(probs)},
    }

result = predict("paddy_leaf.jpg")
print(result)
# {'class': 'blast', 'confidence': 0.8731, 'all_probs': {...}}

Classes

Index Class Disease / Condition Causal Agent
0 bacterial_leaf_blight Bacterial leaf blight Xanthomonas oryzae pv. oryzae
1 bacterial_leaf_streak Bacterial leaf streak Xanthomonas oryzae pv. oryzicola
2 bacterial_panicle_blight Bacterial panicle blight Burkholderia glumae
3 blast Blast (leaf + neck) Magnaporthe oryzae
4 brown_spot Brown spot Bipolaris oryzae
5 downy_mildew Downy mildew Sclerophthora macrospora
6 hispa Rice hispa Dicladispa armigera
7 leaf_roller Rice leaf roller Cnaphalocrocis medinalis
8 leaf_scald Leaf scald Monographella albescens
9 sheath_blight Sheath blight Rhizoctonia solani
10 stem_rot Stem rot Sclerotium oryzae
11 tungro Tungro Rice tungro spherical + bacilliform virus
12 yellow_stem_borer Yellow stem borer Scirpophaga incertulas
13 normal Healthy plant —
14 potassium_deficiency Potassium deficiency (abiotic) Nutrient stress

Evaluation — In-Domain Test Set (n=938)

Summary Metrics

Metric Value
Top-1 Accuracy 92.96%
Weighted F1 0.9288
Weighted Precision 0.9326
Weighted Recall 0.9296
Macro F1 0.9192
Macro Precision 0.9361
Macro Recall 0.9138
Best class F1 1.000 (yellow_stem_borer)
Worst class F1 0.692 (bacterial_leaf_streak, n=17)

Weighted metrics weight each class by its test-set support count. Macro metrics treat all 15 classes equally regardless of support.

Per-Class Results

Class Precision Recall F1 Support
bacterial_leaf_streak 1.000 0.529 0.692 17
downy_mildew 0.727 0.828 0.774 29
blast 0.943 0.839 0.888 137
tungro 0.878 0.952 0.913 83
brown_spot 0.872 0.962 0.915 78
hispa 0.910 0.935 0.922 108
bacterial_panicle_blight 0.917 0.957 0.936 23
bacterial_leaf_blight 0.970 0.925 0.947 106
normal 0.924 0.965 0.944 113
leaf_scald 1.000 0.909 0.952 11
potassium_deficiency 0.952 0.976 0.964 41
leaf_roller 0.973 0.973 0.973 37
sheath_blight 1.000 0.958 0.979 24
stem_rot 0.976 1.000 0.988 41
yellow_stem_borer 1.000 1.000 1.000 90

Confusion Matrix

Limitations and Known Issues

Weak classes:

  • bacterial_leaf_streak (F1=0.692, support=17): Only 17 test samples; the model is precise when confident but misses ~47% of actual cases. More field data needed.
  • downy_mildew (F1=0.774): Visually similar to early blast and nutrient deficiency; low precision suggests over-prediction.
  • blast (F1=0.888, recall=0.839): Leaf blast and neck blast were merged. Some blast images are classified as brown_spot.

Geographic scope: Training data covers Tamil Nadu (Paddy Doctor) and Bangladesh (BRRI). Performance on Telangana, Andhra Pradesh, West Bengal, and Southeast Asian varieties has not been validated. Expect degraded accuracy on field conditions significantly different from the training distribution.

Not a diagnostic tool: Model output should be reviewed by an agronomist before treatment decisions. Abiotic stress (potassium_deficiency) shares visual symptoms with several diseases.

Training Data

Source Classes Used Images (kept after dedup)
Paddy Doctor (Kaggle 2022) All 13 original classes ~6,600
BRRI Kaggle (valid set) blast, bacterial_leaf_blight, brown_spot, hispa, leaf_scald, sheath_blight, tungro ~1,400
Mendeley Rice Disease V1 (2026) bacterial_leaf_blight, leaf_roller, stem_rot, potassium_deficiency ~1,400

Total after SHA-256 exact dedup + pHash near-dedup (Hamming ≤ 10): 9,376 images. Split: 80% train / 10% val / 10% test (stratified, frozen test set).

Citations

Backbone:

@misc{oquab2023dinov2,
    title={DINOv2: Learning Robust Visual Features without Supervision},
    author={Maxime Oquab and others},
    year={2023},
    eprint={2304.07193},
    archivePrefix={arXiv}
}

Paddy Doctor dataset:

@misc{paddy-disease-classification,
    author={Paddy Doctor and Pandarasamy Arjunan (Samy) and Petchiammal},
    title={Paddy Doctor: Paddy Disease Classification},
    year={2022},
    howpublished={\url{https://kaggle.com/competitions/paddy-disease-classification}},
    note={Kaggle}
}

Mendeley dataset: Raki, Nishat Sultana; Bakki, Md. Abdul; Sheikh, Foysal; Pria, Mosa. Nadia Sultana; Parvin, Shahnaj; Matin, Mafiul Hasan (2026), "Rice Disease Image Dataset", Mendeley Data, V1, doi: 10.17632/jw7hp6r5gj.1

BRRI dataset: Attributed to Bangladesh Rice Research Institute (https://brri.gov.bd/). No formal citation provided by dataset authors.

Downloads last month
-
Safetensors
Model size
0.3B params
Tensor type
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Paper for harinpurumandla/rice-disease-net

Evaluation results

  • Top-1 Accuracy on Paddy Doctor in-domain test set (n=938, 15 classes)
    self-reported
    0.930
  • Weighted F1 on Paddy Doctor in-domain test set (n=938, 15 classes)
    self-reported
    0.929
  • Macro F1 on Paddy Doctor in-domain test set (n=938, 15 classes)
    self-reported
    0.919
  • Weighted Precision on Paddy Doctor in-domain test set (n=938, 15 classes)
    self-reported
    0.933
  • Weighted Recall on Paddy Doctor in-domain test set (n=938, 15 classes)
    self-reported
    0.930
  • Best Class F1 (yellow_stem_borer) on Paddy Doctor in-domain test set (n=938, 15 classes)
    self-reported
    1.000
  • Worst Class F1 (bacterial_leaf_streak) on Paddy Doctor in-domain test set (n=938, 15 classes)
    self-reported
    0.692