pulsatrix
Loading...
Searching...
No Matches
pdp.hpp
Go to the documentation of this file.
1
7#pragma once
8
9#include <functional>
10#include <stdexcept>
11#include <string>
12#include <vector>
13
14#include "pulsatrix/assert.hpp"
17#include "pulsatrix/tensor.hpp"
18
19namespace pulsatrix {
20
37class PDP {
38public:
58 [[nodiscard]] Attribution explain(const std::function<Tensor(const Tensor&)>& predict,
59 const std::vector<Tensor>& background, int64_t feature_index,
60 int64_t target_index, float grid_min, float grid_max, int64_t grid_size,
61 DeviceBackend* backend) const {
62 if (background.empty()) {
63 throw std::invalid_argument("PDP::explain: background must not be empty");
64 }
65 PULSATRIX_ASSERT(grid_size >= 1);
66 PULSATRIX_ASSERT(feature_index >= 0 && feature_index < background[0].numel());
67
68 std::vector<std::vector<float>> background_values;
69 background_values.reserve(background.size());
70 for (const Tensor& instance : background) {
71 background_values.push_back(instance.to_host_vector());
72 }
73 std::vector<float> curve(static_cast<size_t>(grid_size));
74
75 for (int64_t k = 0; k < grid_size; ++k) {
76 float v = (grid_size == 1) ? grid_min : grid_min + static_cast<float>(k) * (grid_max - grid_min) /
77 static_cast<float>(grid_size - 1);
78
79 float sum = 0.0f;
80 for (size_t b = 0; b < background.size(); ++b) {
81 const Tensor& instance = background[b];
82 std::vector<float> perturbed_values = background_values[b];
83 perturbed_values[static_cast<size_t>(feature_index)] = v;
84 Tensor perturbed(instance.shape(), instance.backend(), perturbed_values, instance.device());
85 Tensor output = predict(perturbed);
86 sum += output.read_element(target_index);
87 }
88 curve[static_cast<size_t>(k)] = sum / static_cast<float>(background.size());
89 }
90
91 Tensor curve_tensor(Shape({grid_size}), explainer_detail::backend_beside(background[0], backend), curve,
92 background[0].device());
93 return Attribution{"pdp", std::move(curve_tensor),
94 {{"feature_index", std::to_string(feature_index)},
95 {"target_index", std::to_string(target_index)},
96 {"grid_size", std::to_string(grid_size)}}};
97 }
98};
99
100} // namespace pulsatrix
PULSATRIX_ASSERT – debug-only invariant check for programmer errors, distinct from throw (used for ca...
#define PULSATRIX_ASSERT(cond)
Aborts with a diagnostic message if cond is false. Debug-only – use for conditions that indicate a bu...
Definition assert.hpp:22
First-class explanation result type – values, method, and metadata together.
Vendor-agnostic compute/memory backend. CPUBackend, CUDABackend (Phase 1.5), and HIPBackend (Phase 1....
Definition device_backend.hpp:219
PDP_j(v) = (1/|B|) * sum_{b in B} f(x_j=v, x_{-j}=b_{-j}) – for each grid value v,...
Definition pdp.hpp:37
Attribution explain(const std::function< Tensor(const Tensor &)> &predict, const std::vector< Tensor > &background, int64_t feature_index, int64_t target_index, float grid_min, float grid_max, int64_t grid_size, DeviceBackend *backend) const
Computes the PDP curve for one feature.
Definition pdp.hpp:58
An N-dimensional shape. A plain aggregate of dimensions with no invariant beyond "non-negative dimens...
Definition shape.hpp:24
N-dimensional tensor. Owns its data buffer exclusively; a DeviceBackend* is injected (not owned) – th...
Definition tensor.hpp:29
DeviceType device() const
Which device this tensor's buffer conceptually resides on.
Definition tensor.hpp:122
DeviceBackend * backend() const
The backend that owns this tensor's buffer. Not owned by the Tensor.
Definition tensor.hpp:130
const Shape & shape() const
This tensor's shape.
Definition tensor.hpp:113
float read_element(int64_t flat_index) const
Reads one element to the host through the owning backend, on any device.
Abstract interface isolating vendor-specific memory/compute operations from Tensor/ComputationGraph.
DeviceBackend * backend_beside(const Tensor &like, DeviceBackend *backend)
The backend to allocate a tensor through that must live beside like.
Definition attribution.hpp:49
Definition acquisition_functions.hpp:16
An explanation result: the raw attribution values, the method that produced them, and any relevant me...
Definition attribution.hpp:23
N-dimensional tensor – owns a buffer via DeviceBackend*, RAII (Rule of Five).