if Code.ensure_loaded?(Nx) do defmodule CixP1.Examples do @moduledoc """ Worked examples tying the API together. Requires `:nx`. These are meant to be read and copied, not called as a stable API. They run on the Orange Pi 6 target (real NPU) only. """ alias CixP1.{Context, Graph} @doc """ Loads an image-classifier `.cix` model, runs one inference on `input_binary`, and returns the top-`k` `{class_index, score}` pairs. Assumes a single input tensor and a single 1-D output of class scores. ## Example iex> CixP1.Examples.classify("/data/models/mobilenet.cix", jpeg_pixels, 5) {:ok, [{285, 0.71}, {283, 0.10}, ...]} """ @spec classify(Path.t(), binary(), pos_integer()) :: {:ok, [{non_neg_integer(), float()}]} | {:error, String.t()} def classify(model_path, input_binary, k \\ 5) do with {:ok, ctx} <- Context.new(), {:ok, graph} <- Graph.load(ctx, model_path), {:ok, [scores_bin]} <- CixP1.run(graph, [input_binary]), {:ok, desc} <- Graph.output_descriptor(graph, 0) do scores = scores_bin |> CixP1.Nx.to_nx(desc) |> CixP1.Nx.dequantize(desc) n = min(k, Nx.size(scores)) {top_scores, top_idx} = Nx.top_k(scores, k: n) pairs = Enum.zip( Nx.to_flat_list(top_idx), Nx.to_flat_list(top_scores) ) {:ok, pairs} end end end end