Skip to content

Commit e2e6249

Browse files
authored
Add documentation (#13)
1 parent d468e9e commit e2e6249

File tree

13 files changed

+188
-10
lines changed

13 files changed

+188
-10
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ ___
55
|:--------------------------------------------------------------------- |:----------------------------------------------------- |
66
| [![][docs-stab-img]][docs-stab-url] [![][docs-dev-img]][docs-dev-url] | [![][ci-img]][ci-url] [![][codecov-img]][codecov-url] |
77

8-
Explainable AI in Julia using Flux.
8+
Explainable AI in Julia using [Flux.jl](https://fluxml.ai).
99

1010
## Installation
1111
To install this package and its dependencies, open the Julia REPL and run
1212
```julia-repl
1313
julia> ]add https://github.com/adrhill/ExplainabilityMethods.jl
1414
```
1515

16-
⚠️ This package is in early development, so expect frequent breaking changes. ⚠️
16+
This package is in early development. Expect [breaking changes on minor version updates](https://semver.org/#spec-item-4) until version `1.0.0`.
1717

1818
## Example
1919
```julia

docs/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/src/generated

docs/Project.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
[deps]
22
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
33
ExplainabilityMethods = "cd722a4f-8d55-446b-8550-a4aabc9151ab"
4+
Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c"
5+
ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
6+
Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
7+
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
8+
Metalhead = "dbeba491-748d-5e0e-a39e-b530a07fa0cc"
9+
TestImages = "5e47fb64-e119-507b-a336-dd2b206d9990"

docs/literate/example.jl

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# # Getting started
2+
# ## Preparing the model
3+
# ExplainabilityMethods.jl can be used on any classifier.
4+
# In this tutorial we will be using a pretrained VGG-19 model from
5+
# [Metalhead.jl](https://github.com/FluxML/Metalhead.jl)
6+
using ExplainabilityMethods
7+
using Flux
8+
using Metalhead
9+
using Metalhead: weights
10+
11+
vgg = VGG19()
12+
Flux.loadparams!(vgg, Metalhead.weights("vgg19"))
13+
14+
#md # !!! note "Pretrained weights"
15+
#md # This doc page was generated using Metalhead `v0.6.0`.
16+
#md # At the time you read this, Metalhead might already have implemented weight loading
17+
#md # via `VGG19(; pretrain=true)`, in which case `loadparams!` is not necessary.
18+
19+
# In case they exist, we need to strip softmax activations from the output before analyzing:
20+
model = strip_softmax(vgg.layers)
21+
22+
# We also need to load an image
23+
using Images
24+
using TestImages
25+
26+
img_raw = testimage("chelsea")
27+
28+
# which we preprocess for VGG-19
29+
include("../utils/preprocessing.jl")
30+
img = preprocess(img_raw)
31+
size(img)
32+
33+
# ## Calling the analyzer
34+
# We can now select an analyzer of our choice
35+
# and call `analyze` to get an explaination `expl`:
36+
analyzer = LRPZero(model)
37+
expl, out = analyze(img, analyzer);
38+
39+
#md # !!! note "Neuron selection"
40+
#md # To get an explaination with respect to a specific output neuron (e.g. class 42) call
41+
#md # ```julia
42+
#md # expl, out = analyze(img, analyzer, 42)
43+
#md # ```
44+
#
45+
# Finally, we can visualize the explaination through heatmapping:
46+
heatmap(expl)
47+
48+
# Currently, the following analyzers are implemented:
49+
#
50+
# ```
51+
# ├── Gradient
52+
# ├── InputTimesGradient
53+
# └── LRP
54+
# ├── LRPZero
55+
# ├── LRPEpsilon
56+
# └── LRPGamma
57+
# ```
58+
59+
# ## Custom rules composites
60+
# If our model is a "flat" chain of Flux layers, we can assign LRP rules
61+
# to each layer individually. For this purpose,
62+
# ExplainabilityMethods exports the method `flatten_chain`:
63+
model = flatten_chain(model)
64+
65+
#md # !!! note "Flattening models"
66+
#md # Not all models can be flattened, e.g. those using
67+
#md # `Parallel` and `SkipConnection` layers.
68+
#
69+
# Now we set a rule for each layer
70+
rules = [
71+
ZBoxRule(), repeat([GammaRule()], 15)..., repeat([ZeroRule()], length(model) - 16)...
72+
]
73+
# to define a custom LRP analyzer:
74+
analyzer = LRP(model, rules)
75+
expl, out = analyze(img, analyzer)
76+
heatmap(expl)
77+
78+
# ## Custom rules
79+
# Let's define a rule that modifies the weights and biases of our layer on the forward pass.
80+
# The rule has to be of type `AbstractLRPRule`.
81+
struct MyCustomLRPRule <: AbstractLRPRule end
82+
83+
# It is then possible to dispatch on the utility functions `modify_layer`, `modify_params`
84+
# and `modify_denominator` with our rule type `MyCustomLRPRule`
85+
# to define custom rules without writing boilerplate code.
86+
function modify_params(::MyCustomLRPRule, W, b)
87+
ρW = W + 0.1 * relu.(W)
88+
return ρW, b
89+
end
90+
91+
# We can directly use this rule to make an analyzer!
92+
analyzer = LRP(model, MyCustomLRPRule())
93+
expl, out = analyze(img, analyzer)
94+
heatmap(expl)
95+
96+
#md # !!! note "PRs welcome"
97+
#md # If you implement a rule that's not included in ExplainabilityMethods, please make a PR to
98+
#md # [`src/lrp_rules.jl`](https://github.com/adrhill/ExplainabilityMethods.jl/blob/master/src/lrp_rules.jl)!

docs/make.jl

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
using ExplainabilityMethods
22
using Documenter
3+
using Literate
34

5+
EXAMPLE_DIR = joinpath(@__DIR__, "literate")
6+
OUT_DIR = joinpath(@__DIR__, "src/generated")
7+
8+
# Use Literate.jl to generate docs and notebooks of examples
9+
for example in readdir(EXAMPLE_DIR)
10+
EXAMPLE = joinpath(EXAMPLE_DIR, example)
11+
12+
Literate.markdown(EXAMPLE, OUT_DIR; documenter=true) # markdown for Documenter.jl
13+
Literate.notebook(EXAMPLE, OUT_DIR) # .ipynb notebook
14+
Literate.script(EXAMPLE, OUT_DIR) # .jl script
15+
end
16+
17+
DocMeta.setdocmeta!(
18+
ExplainabilityMethods, :DocTestSetup, :(using ExplainabilityMethods); recursive=true
19+
)
420
makedocs(;
521
modules=[ExplainabilityMethods],
622
authors="Adrian Hill",
@@ -11,7 +27,11 @@ makedocs(;
1127
canonical="https://adrhill.github.io/ExplainabilityMethods.jl",
1228
assets=String[],
1329
),
14-
pages=["Home" => "index.md"],
30+
pages=[
31+
"Home" => "index.md",
32+
"Getting started" => "generated/example.md",
33+
"API Reference" => "api.md",
34+
],
1535
)
1636

1737
deploydocs(; repo="github.com/adrhill/ExplainabilityMethods.jl")

docs/src/api.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# API Reference
2+
3+
All methods in ExplainabilityMethods.jl work by calling `analyze` on an input and an analyzer:
4+
```@docs
5+
analyze
6+
heatmap
7+
```
8+
9+
## Analyzers
10+
```@docs
11+
LRP
12+
Gradient
13+
InputTimesGradient
14+
```
15+
16+
# LRP
17+
## Rules
18+
```@docs
19+
ZeroRule
20+
GammaRule
21+
EpsilonRule
22+
ZBoxRule
23+
```
24+
25+
## Custom rules
26+
These utilities can be used to define custom rules without writing boilerplate code:
27+
```@docs
28+
modify_layer
29+
modify_params
30+
modify_denominator
31+
```
32+
33+
# Utilities
34+
```@docs
35+
strip_softmax
36+
flatten_chain
37+
```

docs/src/index.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
```@meta
22
CurrentModule = ExplainabilityMethods
33
```
4+
![ExplainabilityMethods.jl](https://raw.githubusercontent.com/adrhill/ExplainabilityMethods.jl/gh-pages/assets/banner.png)
45

5-
# ExplainabilityMethods
6+
Explainable AI in Julia using Flux.
67

78
```@index
89
```
9-
10-
```@autodocs
11-
Modules = [ExplainabilityMethods]
12-
```
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# Image preprocessing for ImageNet models.
12
# Code taken from Metalhead 0.5.3's utils.jl
23
using Images
34

src/ExplainabilityMethods.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const ANALYZERS = Dict(
3535
# LRP rules
3636
export AbstractLRPRule
3737
export ZeroRule, EpsilonRule, GammaRule, ZBoxRule
38+
export modify_layer, modify_params, modify_denominator
3839

3940
const RULES = Dict(
4041
"ZeroRule" => ZeroRule,

0 commit comments

Comments
 (0)