Skip to main content

Distillation of piece-wise linear neural networks into decision trees

Project description

Welcome to Affinitree!

PyPi

Affinitree is an open-source library designed to generate faithful surrogate models (decision trees) from pre-trained piece-wise linear neural networks. The core part of the library is implemented in Rust for best performance.

The opaque nature of neural networks stands in the way of their widespread usage, especially in safety critical domains. To address this issue, it is important to access the semantics of neural networks in a structured manner. One promising field of Explainable AI (XAI) research is concerned with finding alternative models for a given neural network that are more transparent, interpretable, or easier to analyze. This approach is called model distillation and the resulting model is called surrogate model, proxy model or white-box model.

Affinitree enables the distillation of piece-wise linear neural networks into a specialized decision trees. In Explainable AI (XAI) literature, decision trees are widely regarded as one of the few model classes comprehensible by humans, making them prime candidates for surrogate models. Additionally, many neural network architectures, such as those using ReLU, LeakyReLU, residual connections, pooling, and convolutions, exhibit piece-wise linear behavior. These qualities make decision trees well-suited for representing such networks.

Commonly, surrogate models are only an approximation of the true nature of the neural network. In contrast, affinitree provides mathematically sound and correct surrogate models. This is achieved by an holistic symbolic execution of the network. The resulting decision structure is human-understandable, but size must be controlled.

Installation

affinitree requires Python 3.8 - 3.12.

pip install affinitree

Wheels are currently available for Linux (x86_64). For other architectures, see Build Wheels from Rust.

First Steps

Affinitree provides a high-level API to convert a pre-trained pytorch model into a decision tree (requires installation of torch).

from torch import nn
from affinitree import extract_pytorch_architecture, builder

model = nn.Sequential(nn.Linear(7, 5),
                      nn.ReLU(),
                      nn.Linear(5, 5),
                      nn.ReLU(),
                      nn.Linear(5, 4)
                     )

# Train your model here ...

arch = extract_pytorch_architecture(7, model)
dd = builder.from_layers(arch)

It may be noted that affinitree is independent of any specific neural network library. The function extract_pytorch_architecture is a helper that extracts numpy arrays from pytorch models for convenience. Any model expressed as a sequence of numpy matrices can be read (see also the provided examples).

After distilling the model, one can use the resulting AffTree to plot the decision tree in graphviz's DOT language:

dd.to_dot()

A simple AffTree may look like this (representing the xor function):

fig:afftree example (at github)

Affinitree provides a method to plot the decision boundaries of an AffTree using matplotlib

from affinitree import plot_preimage_partition, LedgerDiscrete

# Derive 10 colors from the tab10 color map and position legend at the top 
ledger = LedgerDiscrete(cmap='tab10', num=10, position='top')
# Map the terminals of dd to one of the 10 colors based on their class
ledger.fit(dd)
# Plot for each terminal of dd the polytope that is implied by the path from the root to the respective terminal
plot_preimage_partition(dd, ledger, intervals=[(-20., 15.), (-12., 12.)])

The ledger is used to control the coloring and legend of the plot. A resulting plot may look like this:

fig:mnist preimage partition (at github)

Composition and Schemas

Many operations on AffTrees can be implemented using composition. For example, here are a few common functions in the realm of neural networks expressed as AffTree.

ReLU (indim=4):

fig:relu

ReLU (indim=4) applied only to the first component (partial ReLU / step ReLU):

fig:partial-relu

Argmax (indim=4):

fig:argmax

Schemas are a collection of typical operations that are used in the context of neural networks. In code, one can apply these as follows:

from affinitree import AffTree
from affinitree import schema

dd = AffTree.identity(2)

relu = schema.ReLU(2)
dd = dd.compose(relu)

The following operations are already provided:

schema.ReLU(dim=n)
schema.partial_ReLU(dim=n, row=m)
schema.partial_leaky_ReLU(dim=n, row=m, alpha=0.1)
schema.partial_hard_tanh(dim=n, row=m)
schema.partial_hard_sigmoid(dim=n, row=m)
schema.argmax(dim=n)
schema.inf_norm(minimum=a, maximum=b)
schema.class_characterization(dim=n, clazz=c)

The interface is easily adaptable to additional needs, one just needs to define a function that returns an AffTree instance that expresses the required piece-wise linear function.

Build Wheels from Rust

For best performance, most of affinitree is written in the system language Rust. The corresponding sources can be found at affinitree (rust). To make the interaction with compiled languages easier, Python allows to provide pre-compiled binaries for each target architecture, called wheels.

After installing Rust and maturin, wheels for your current architecture can be build using:

maturin build --release

To build wheels optimized for your current system, include the following flag:

RUSTFLAGS="-C target-cpu=native" maturin build --release

An example for setting up a manylinux2014 compatible build environment can be found in the included Dockerfile.

License

Copyright 2022–2024 affinitree developers.

The code in this repository is licensed under the Apache License, Version 2.0. You may not use this project except in compliance with those terms.

Binary applications built from this repository (including wheels) contain dependencies with different license terms, see license.

Contributing

Please feel free to create issues, fork the project, or submit pull requests.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

affinitree-0.22.0.tar.gz (54.2 kB view details)

Uploaded Source

Built Distributions

affinitree-0.22.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

affinitree-0.22.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

affinitree-0.22.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

affinitree-0.22.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

affinitree-0.22.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

affinitree-0.22.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

affinitree-0.22.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

affinitree-0.22.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

File details

Details for the file affinitree-0.22.0.tar.gz.

File metadata

  • Download URL: affinitree-0.22.0.tar.gz
  • Upload date:
  • Size: 54.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.5.1

File hashes

Hashes for affinitree-0.22.0.tar.gz
Algorithm Hash digest
SHA256 e2885fd3d6f899937541c80aa9a60a01ae27f2be687c825201c8971735058ba7
MD5 eb80e456f061ae7f94d5ae218feae996
BLAKE2b-256 008eb4d189572c7b792292c65b2dbff9051ecfdcc2522a89aeb0428fc1bd233a

See more details on using hashes here.

File details

Details for the file affinitree-0.22.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for affinitree-0.22.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 705b71336fb30c3093deeeb2f8fb92365367be14b8f0c7fdcf9c02ddafaf95d5
MD5 c2067d0d64e69885861f1237a9a310ab
BLAKE2b-256 77231c0779e30f765d132d33ee174706e4b982ac8c9c59ea71301bd49fbe6623

See more details on using hashes here.

File details

Details for the file affinitree-0.22.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for affinitree-0.22.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 667db908f8907e05ab49e7cf0ccc64eae45b0c387e28a82b5e64381cdf94e123
MD5 80d110b559d8933440ef5f6d5bb5c6df
BLAKE2b-256 5291d6340326ed175aef705f9e87a2f54f7e4b2cb62b6cd134a5dfbc05b3dc1a

See more details on using hashes here.

File details

Details for the file affinitree-0.22.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for affinitree-0.22.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b2c9b155744028a2fc9b95f18884f642410d3014aa480eba7b8fcdb84908111f
MD5 9e24820929c4d7839f2eb242246775e2
BLAKE2b-256 91496e1419f0ba779d40d687be217c8d9fc5f23102f0092bfe94014b817a2738

See more details on using hashes here.

File details

Details for the file affinitree-0.22.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for affinitree-0.22.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8702b7766f6984a85a9187d3c4608c27a358b5dfd57ad6acf6a4d99a20300bfd
MD5 75b1993fa3aea59cff41104cca58470c
BLAKE2b-256 0e2b3ea9a4bc1d4fd0745e42c421567a82df3c2045423721b8e8dee48436d130

See more details on using hashes here.

File details

Details for the file affinitree-0.22.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for affinitree-0.22.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a3506e01f997a2d87d418b191fc700f5d120c329ac489c4ac6646a424627a84d
MD5 8cee03914a48d7ed757bd81692c465a5
BLAKE2b-256 11d4cac7dd38454f79fb9cdd77584b5e99510ccd27e907bc2b4b6fc8dc3466f3

See more details on using hashes here.

File details

Details for the file affinitree-0.22.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for affinitree-0.22.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 484d403422a6f40f2193554614a04a1eccda1ed9a7963168061c03b0033a826a
MD5 37d22de922e5da7823a64d94e9dc5338
BLAKE2b-256 b2bc6ef4289470f6deb98636ce5bc646412ac4a6c69d3d21d5a5c20e238835f9

See more details on using hashes here.

File details

Details for the file affinitree-0.22.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for affinitree-0.22.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c8c420aaa3a6bd726014c6f11f942bf849b6ecd4a4e78f48b751e7cc648b9d12
MD5 66f337cc86e4af27d8a8b27fd9906921
BLAKE2b-256 6c9d7d292ae1bcead1e72d8cd7e3f98b8ee4fef44ee861b907b438219d7164ac

See more details on using hashes here.

File details

Details for the file affinitree-0.22.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for affinitree-0.22.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0da345b7395c636901662d4ab213e13613108bf768cd02f12f8b6030f247f2eb
MD5 f150579a14f3aff33b2f91054e1a4c92
BLAKE2b-256 85fe038deea0f0030a01397f8f234dc3fc07abd151546e6422bbd7943a2bebca

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page