feat(ml): implement v3.0 architecture with CBAM and calibrated inference

- Integrate Convolutional Block Attention Module (CBAM) for improved feature focus
- Implement temperature scaling and confidence-based status reporting
- Automate dataset acquisition using kagglehub
- Update ONNX opset to 18 and refine preprocessing validation
This commit is contained in:
MythEclipse
2026-06-12 15:24:49 +00:00
parent 43307a15a5
commit f9bd991bdf
10 changed files with 1756 additions and 3506 deletions
+10 -7
View File
@@ -30,6 +30,7 @@ pub struct MetadataResponse {
#[derive(Debug, Serialize, Deserialize)]
pub struct PredictionResponse {
pub status: String,
pub label: String,
pub confidence: f32,
pub probabilities: std::collections::BTreeMap<String, f32>,
@@ -202,33 +203,35 @@ mod tests {
assert_eq!(response.labels.len(), 4);
assert_eq!(
response.labels,
vec!["Bercak Daun", "Daun Sehat", "Karat Daun", "Hawar Daun"]
vec!["Bercak Daun", "Daun Sehat", "Hawar Daun", "Karat Daun"]
);
}
#[test]
fn prediction_response_matches_prediction_contract() {
let prediction = Prediction {
label: "Karat Daun".to_string(),
status: "confident".to_string(),
label: "Hawar Daun".to_string(),
confidence: 0.6,
probabilities: {
let mut map = std::collections::BTreeMap::new();
map.insert("Bercak Daun".to_string(), 0.1);
map.insert("Daun Sehat".to_string(), 0.2);
map.insert("Karat Daun".to_string(), 0.6);
map.insert("Hawar Daun".to_string(), 0.1);
map.insert("Hawar Daun".to_string(), 0.6);
map.insert("Karat Daun".to_string(), 0.1);
map
},
};
let response = prediction_response(prediction);
assert_eq!(response.label, "Karat Daun");
assert_eq!(response.status, "confident");
assert_eq!(response.label, "Hawar Daun");
assert_eq!(response.confidence, 0.6);
assert_eq!(response.probabilities.len(), 4);
assert_eq!(response.probabilities.get("Bercak Daun"), Some(&0.1));
assert_eq!(response.probabilities.get("Daun Sehat"), Some(&0.2));
assert_eq!(response.probabilities.get("Karat Daun"), Some(&0.6));
assert_eq!(response.probabilities.get("Hawar Daun"), Some(&0.1));
assert_eq!(response.probabilities.get("Hawar Daun"), Some(&0.6));
assert_eq!(response.probabilities.get("Karat Daun"), Some(&0.1));
}
}