1a5412caaSRahul use anyhow::{Context, Result};
2a5412caaSRahul use std::fs;
3a5412caaSRahul use test_programs::nn::{sort_results, wit};
4a5412caaSRahul
main() -> Result<()>5a5412caaSRahul pub fn main() -> Result<()> {
6a5412caaSRahul let model = fs::read("fixture/model.pt")
7a5412caaSRahul .context("the model file to be mapped to the fixture directory")?;
8a5412caaSRahul let graph = wit::load(
9a5412caaSRahul &[model],
10a5412caaSRahul wit::GraphEncoding::Pytorch,
11a5412caaSRahul wit::ExecutionTarget::Cpu,
12a5412caaSRahul )?;
13a5412caaSRahul let tensor = fs::read("fixture/kitten.tensor")
14a5412caaSRahul .context("the tensor file to be mapped to the fixture directory")?;
15*a7e11500SRahul let output_buffer = wit::classify(graph, ("input", tensor))?;
16a5412caaSRahul let result = softmax(output_buffer);
17a5412caaSRahul let top_five = &sort_results(&result)[..5];
18a5412caaSRahul assert_eq!(top_five[0].class_id(), 281);
19a5412caaSRahul println!("found results, sorted top 5: {top_five:?}");
20a5412caaSRahul Ok(())
21a5412caaSRahul }
22a5412caaSRahul
softmax(output_tensor: Vec<f32>) -> Vec<f32>23a5412caaSRahul fn softmax(output_tensor: Vec<f32>) -> Vec<f32> {
24a5412caaSRahul let max_val = output_tensor
25a5412caaSRahul .iter()
26a5412caaSRahul .cloned()
27a5412caaSRahul .fold(f32::NEG_INFINITY, f32::max);
28a5412caaSRahul
29a5412caaSRahul // Compute the exponential of each element subtracted by max_val for numerical stability.
30a5412caaSRahul let exps: Vec<f32> = output_tensor.iter().map(|&x| (x - max_val).exp()).collect();
31a5412caaSRahul
32a5412caaSRahul // Compute the sum of the exponentials.
33a5412caaSRahul let sum_exps: f32 = exps.iter().sum();
34a5412caaSRahul
35a5412caaSRahul // Normalize each element to get the probabilities.
36a5412caaSRahul exps.iter().map(|&exp| exp / sum_exps).collect()
37a5412caaSRahul }
38