beyondnn 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- beyondnn/__init__.py +82 -0
- beyondnn/_testing/__init__.py +7 -0
- beyondnn/_testing/attribution_models.py +84 -0
- beyondnn/_testing/audit_scenarios.py +679 -0
- beyondnn/_testing/causal_models.py +77 -0
- beyondnn/_testing/concept_models.py +84 -0
- beyondnn/_testing/faithfulness_models.py +97 -0
- beyondnn/_testing/models.py +236 -0
- beyondnn/attribution/__init__.py +70 -0
- beyondnn/attribution/captum.py +203 -0
- beyondnn/attribution/claims.py +171 -0
- beyondnn/attribution/native.py +299 -0
- beyondnn/attribution/runner.py +567 -0
- beyondnn/attribution/spec.py +246 -0
- beyondnn/audits/__init__.py +184 -0
- beyondnn/audits/engine.py +1860 -0
- beyondnn/audits/evidence.py +761 -0
- beyondnn/audits/plan.py +212 -0
- beyondnn/audits/render.py +183 -0
- beyondnn/audits/report.py +538 -0
- beyondnn/audits/uncertainty.py +175 -0
- beyondnn/concepts/__init__.py +108 -0
- beyondnn/concepts/_core.py +270 -0
- beyondnn/concepts/data.py +209 -0
- beyondnn/concepts/encoding.py +519 -0
- beyondnn/concepts/features.py +442 -0
- beyondnn/concepts/use.py +537 -0
- beyondnn/concepts/validate.py +430 -0
- beyondnn/concepts/verify.py +588 -0
- beyondnn/core/__init__.py +6 -0
- beyondnn/core/hooks.py +403 -0
- beyondnn/core/persistence.py +255 -0
- beyondnn/core/samples.py +61 -0
- beyondnn/core/sites.py +208 -0
- beyondnn/core/tensors.py +125 -0
- beyondnn/core/trace.py +896 -0
- beyondnn/core/units.py +101 -0
- beyondnn/explain/__init__.py +42 -0
- beyondnn/explain/bundle.py +644 -0
- beyondnn/explain/handle.py +125 -0
- beyondnn/explain/response.py +1157 -0
- beyondnn/explain/views.py +244 -0
- beyondnn/faithfulness/__init__.py +96 -0
- beyondnn/faithfulness/claims.py +167 -0
- beyondnn/faithfulness/runner.py +978 -0
- beyondnn/faithfulness/spec.py +494 -0
- beyondnn/faithfulness/stability.py +574 -0
- beyondnn/faithfulness/stats.py +180 -0
- beyondnn/faithfulness/verify.py +313 -0
- beyondnn/interventions/__init__.py +62 -0
- beyondnn/interventions/claims.py +123 -0
- beyondnn/interventions/metrics.py +211 -0
- beyondnn/interventions/runner.py +850 -0
- beyondnn/interventions/spec.py +282 -0
- beyondnn/protocols.py +98 -0
- beyondnn/provenance/__init__.py +18 -0
- beyondnn/provenance/collect.py +106 -0
- beyondnn/provenance/fingerprint.py +234 -0
- beyondnn/py.typed +0 -0
- beyondnn/schema/__init__.py +231 -0
- beyondnn/schema/_canonical.py +121 -0
- beyondnn/schema/_types.py +298 -0
- beyondnn/schema/attribution.py +272 -0
- beyondnn/schema/audit.py +410 -0
- beyondnn/schema/base.py +276 -0
- beyondnn/schema/claims.py +439 -0
- beyondnn/schema/codec.py +187 -0
- beyondnn/schema/concepts.py +491 -0
- beyondnn/schema/errors.py +55 -0
- beyondnn/schema/faithfulness.py +253 -0
- beyondnn/schema/interventions.py +347 -0
- beyondnn/schema/limitations.py +304 -0
- beyondnn/schema/provenance.py +302 -0
- beyondnn/schema/records.py +114 -0
- beyondnn/schema/status.py +205 -0
- beyondnn/schema/values.py +304 -0
- beyondnn-0.1.0.dist-info/METADATA +560 -0
- beyondnn-0.1.0.dist-info/RECORD +80 -0
- beyondnn-0.1.0.dist-info/WHEEL +4 -0
- beyondnn-0.1.0.dist-info/licenses/LICENSE +202 -0
beyondnn/__init__.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""BeyondNN: an interpretability evidence framework for PyTorch.
|
|
2
|
+
|
|
3
|
+
Implemented: the trace schema (:mod:`beyondnn.schema`), provenance
|
|
4
|
+
(:mod:`beyondnn.provenance`), trace recording (:func:`trace`,
|
|
5
|
+
:func:`recording`, :class:`TraceResult`), persistence (``TraceResult.save``,
|
|
6
|
+
:func:`load_trace`), and :func:`instrument` (``handle.explain`` returns
|
|
7
|
+
INPUT -> WHY -> OUTPUT, where Phase-1 WHY is measured internal evidence, not a
|
|
8
|
+
causal or attributed explanation).
|
|
9
|
+
|
|
10
|
+
``import beyondnn`` does not import torch; the tracing names are loaded lazily on
|
|
11
|
+
first use, so :mod:`beyondnn.schema` stays usable without torch.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from typing import TYPE_CHECKING, Any
|
|
17
|
+
|
|
18
|
+
from . import schema
|
|
19
|
+
from .schema import EstimandScope, EvidenceStatus, Outcome, Relation, Verdict
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from .attribution import attribute
|
|
23
|
+
from .audits import audit
|
|
24
|
+
from .core.persistence import load_trace
|
|
25
|
+
from .core.trace import TraceResult, recording, trace
|
|
26
|
+
from .explain import compose, instrument
|
|
27
|
+
from .interventions import intervene
|
|
28
|
+
|
|
29
|
+
__version__ = "0.1.0"
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
"EstimandScope",
|
|
33
|
+
"EvidenceStatus",
|
|
34
|
+
"Outcome",
|
|
35
|
+
"Relation",
|
|
36
|
+
"TraceResult",
|
|
37
|
+
"Verdict",
|
|
38
|
+
"__version__",
|
|
39
|
+
"attribute",
|
|
40
|
+
"attribution",
|
|
41
|
+
"audit",
|
|
42
|
+
"audits",
|
|
43
|
+
"compose",
|
|
44
|
+
"concepts",
|
|
45
|
+
"faithfulness",
|
|
46
|
+
"instrument",
|
|
47
|
+
"intervene",
|
|
48
|
+
"interventions",
|
|
49
|
+
"load_trace",
|
|
50
|
+
"recording",
|
|
51
|
+
"schema",
|
|
52
|
+
"trace",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
_LAZY = {
|
|
56
|
+
"trace": "beyondnn.core.trace",
|
|
57
|
+
"recording": "beyondnn.core.trace",
|
|
58
|
+
"TraceResult": "beyondnn.core.trace",
|
|
59
|
+
"load_trace": "beyondnn.core.persistence",
|
|
60
|
+
"instrument": "beyondnn.explain",
|
|
61
|
+
"compose": "beyondnn.explain",
|
|
62
|
+
"intervene": "beyondnn.interventions",
|
|
63
|
+
"attribute": "beyondnn.attribution",
|
|
64
|
+
"audit": "beyondnn.audits",
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def __getattr__(name: str) -> Any:
|
|
69
|
+
if name in ("interventions", "attribution", "faithfulness", "concepts", "audits"):
|
|
70
|
+
import importlib
|
|
71
|
+
|
|
72
|
+
module = importlib.import_module(f"beyondnn.{name}")
|
|
73
|
+
globals()[name] = module
|
|
74
|
+
return module
|
|
75
|
+
module_name = _LAZY.get(name)
|
|
76
|
+
if module_name is None:
|
|
77
|
+
raise AttributeError(f"module 'beyondnn' has no attribute {name!r}")
|
|
78
|
+
import importlib
|
|
79
|
+
|
|
80
|
+
value = getattr(importlib.import_module(module_name), name)
|
|
81
|
+
globals()[name] = value
|
|
82
|
+
return value
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"""Internal, unstable testing utilities. NOT public BeyondNN API.
|
|
2
|
+
|
|
3
|
+
Contents may change or disappear without notice. Nothing here is exported from
|
|
4
|
+
``beyondnn``. The reference models in :mod:`beyondnn._testing.models` are
|
|
5
|
+
deliberately ordinary networks for testing BeyondNN's evidence machinery; they
|
|
6
|
+
are not BeyondNN model architectures.
|
|
7
|
+
"""
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""Fixed-weight ground-truth models for Phase-3 attribution tests (internal, unstable).
|
|
2
|
+
|
|
3
|
+
Input ``x = (x0, x1)`` of shape (1, 2); target ``y[0, 0]``. Expected attributions are
|
|
4
|
+
derived analytically in docs/PHASE_3_PLAN.md (before any experiment ran).
|
|
5
|
+
|
|
6
|
+
========== =================== ============== ============== =====================
|
|
7
|
+
Model F gradient input x grad IG, zero baseline
|
|
8
|
+
========== =================== ============== ============== =====================
|
|
9
|
+
Linear 2 x0 + 3 x1 [2, 3] [2 x0, 3 x1] [2 x0, 3 x1]
|
|
10
|
+
Irrelevant 4 x0 [4, 0] [4 x0, 0] [4 x0, 0]
|
|
11
|
+
Product x0 x1 [x1, x0] [x0 x1, x0 x1] [x0 x1 / 2, x0 x1 / 2]
|
|
12
|
+
Saturating tanh(x0) + x1 [sech^2 x0, 1] [x0 sech^2 x0, [tanh x0, x1]
|
|
13
|
+
x1]
|
|
14
|
+
========== =================== ============== ============== =====================
|
|
15
|
+
|
|
16
|
+
``Twice`` applies one scalar linear map (weight 2) twice: ``y = lin(lin(x))``; the
|
|
17
|
+
gradient at call 0's output is 2 and at call 1's output is 1. ``Aliased`` registers
|
|
18
|
+
one module under two paths.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import torch
|
|
24
|
+
from torch import nn
|
|
25
|
+
|
|
26
|
+
__all__ = ["Aliased", "Irrelevant", "Linear", "Product", "Saturating", "Twice"]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _linear(weights: list[float]) -> nn.Linear:
|
|
30
|
+
layer = nn.Linear(len(weights), 1, bias=False)
|
|
31
|
+
with torch.no_grad():
|
|
32
|
+
layer.weight.copy_(torch.tensor([weights]))
|
|
33
|
+
return layer
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Linear(nn.Module):
|
|
37
|
+
def __init__(self) -> None:
|
|
38
|
+
super().__init__()
|
|
39
|
+
self.lin = _linear([2.0, 3.0])
|
|
40
|
+
|
|
41
|
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
|
42
|
+
out: torch.Tensor = self.lin(x)
|
|
43
|
+
return out
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class Irrelevant(nn.Module):
|
|
47
|
+
def __init__(self) -> None:
|
|
48
|
+
super().__init__()
|
|
49
|
+
self.lin = _linear([4.0, 0.0])
|
|
50
|
+
|
|
51
|
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
|
52
|
+
out: torch.Tensor = self.lin(x)
|
|
53
|
+
return out
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class Product(nn.Module):
|
|
57
|
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
|
58
|
+
return (x[:, 0] * x[:, 1]).unsqueeze(1)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class Saturating(nn.Module):
|
|
62
|
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
|
63
|
+
return (torch.tanh(x[:, 0]) + x[:, 1]).unsqueeze(1)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class Twice(nn.Module):
|
|
67
|
+
def __init__(self) -> None:
|
|
68
|
+
super().__init__()
|
|
69
|
+
self.lin = _linear([2.0])
|
|
70
|
+
|
|
71
|
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
|
72
|
+
out: torch.Tensor = self.lin(self.lin(x))
|
|
73
|
+
return out
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class Aliased(nn.Module):
|
|
77
|
+
def __init__(self) -> None:
|
|
78
|
+
super().__init__()
|
|
79
|
+
self.first = _linear([1.0, 1.0])
|
|
80
|
+
self.alias = self.first
|
|
81
|
+
|
|
82
|
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
|
83
|
+
out: torch.Tensor = self.first(x)
|
|
84
|
+
return out
|