09. Agricultural AI
Agriculture represents the primary economic sector across most African countries, with smallholder farmers comprising the majority of the workforce. AI applications in this domain include crop disease identification, market price prediction, weather forecasting, and extension advisory services. Offline-first deployment proves essential given rural connectivity limitations.
Crop disease identification through image classification enables farmer self-diagnosis. Cassava bacterial blight, maize leaf blight, and tomato late blight represent common conditions requiring early intervention. Model architectures for mobile deployment typically use compressed CNNs or MobileNets rather than transformer-based vision models. Image collection must span disease stages, lighting conditions, and camera quality variation.
# Agricultural disease classifier with confidence-based referral
import numpy as np
from PIL import Image
import torchvision.transforms as transforms
class CropDiseaseClassifier:
"""Identify crop diseases with uncertainty-based referral."""
DISEASES = {
0: {'name': 'cassava_bacterial_blight', 'crop': 'cassava',
'severity': 'high', 'recommendation': 'Remove and burn infected plants'},
1: {'name': 'cassava_green_mite', 'crop': 'cassava',
'severity': 'medium', 'recommendation': 'Apply neem extract'},
2: {'name': 'cassava_mosaic', 'crop': 'cassava',
'severity': 'high', 'recommendation': 'Use virus-free planting material'},
3: {'name': 'maize_blight', 'crop': 'maize',
'severity': 'medium', 'recommendation': 'Apply fungicide'},
4: {'name': 'healthy', 'crop': None,
'severity': None, 'recommendation': 'No action required'},
}
# Threshold below which cases get referred to extension officer
REFERRAL_THRESHOLD = 0.75
def __init__(self, model, tokenizer):
self.model = model
self.tokenizer = tokenizer
self.transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
def classify(self, image_path: str) -> dict:
"""Classify disease with confidence scoring and referral."""
img = Image.open(image_path).convert('RGB')
tensor = self.transform(img).unsqueeze(0)
logits = self.model(tensor)
probs = self._softmax(logits.numpy()[0])
prediction = np.argmax(probs)
confidence = probs[prediction]
disease_info = self.DISEASES[prediction]
result = {
'prediction': disease_info['name'],
'confidence': float(confidence),
'crop': disease_info['crop'],
'severity': disease_info['severity'],
'recommendation': disease_info['recommendation'],
'requires_referral': confidence < self.REFERRAL_THRESHOLD
}
if result['requires_referral']:
result['message'] = (
f"Confidence too low ({confidence:.0%}) for confident diagnosis. "
"Image forwarded to extension officer for manual review."
)
# Add differential diagnosis for low confidence cases
if confidence < self.REFERRAL_THRESHOLD:
differentials = []
for idx, prob in enumerate(probs):
if prob > 0.15: # Significant probability
differentials.append({
'disease': self.DISEASES[idx]['name'],
'probability': float(prob)
})
result['differential_diagnoses'] = sorted(
differentials, key=lambda x: x['probability'], reverse=True
)
return result
# Training data augmentation for agricultural images
class AgriculturalAugmentation:
"""Domain-specific augmentation for farm imagery."""
def __init__(self, rotation_range: int = 15,
brightness_range: tuple = (0.8, 1.2)):
self.rotation = rotation_range
self.brightness = brightness_range
def augment(self, image: Image.Image) -> list[Image.Image]:
"""Generate augmented variants."""
import random
variants = [image] # Original
# Rotation (farms viewed from various angles)
for angle in [-self.rotation, 0, self.rotation]:
rotated = image.rotate(angle, expand=False)
variants.append(rotated)
# Brightness variation (sunny and cloudy conditions)
from PIL import ImageEnhance
for factor in self.brightness:
enhancer = ImageEnhance.Brightness(image)
variants.append(enhancer.enhance(factor))
# Color jitter (different camera sensors)
for color_factor in [0.9, 1.1]:
enhancer = ImageEnhance.Color(image)
variants.append(enhancer.enhance(color_factor))
# Random noise simulation (low-quality camera)
img_array = np.array(image)
noise = np.random.normal(0, 5, img_array.shape)
noisy = np.clip(img_array + noise, 0, 255).astype(np.uint8)
variants.append(Image.fromarray(noisy))
return variants
Price prediction systems require historical data that may not exist in digital form. Market price data collection through mobile applications enables dataset building while providing immediate value to users. Price prediction models must handle the high volatility introduced by seasonal production patterns, transport disruptions, and currency fluctuations.
Advisory system design balances automation against human oversight. Fully automated systems risk giving incorrect advice that farmers act upon to their detriment. Confidence-based referral to human extension officers provides safety rails. Audit trails enable post-hoc review of system recommendations. Regular model updates incorporating farmer feedback improve relevance over time.
Agricultural AI deployment benefits from integration with existing extension systems. Government agricultural ministries in Nigeria, Kenya, and Ghana maintain extension officer networks that can serve as human backstop for AI systems. Partnership with these networks provides distribution channels, local expertise, and sustainability pathways through public funding mechanisms.
Design an agricultural AI system that classifies cassava disease from photos, with referral to human extension officers for low-confidence predictions. Include confidence thresholds, data collection strategy, and model update pipeline.