base.ReverseAnalyzerBase is largely similar to the tf1.* version:
builds a "reverse model" in _create_analysis()
obtains an explanation using the analyze() method
conditional reverse mappings now map from layer --> reverse_map.ReplacementLayer subclass, but works the same as before otherwise
differences to tf1.* version include:
no neuron_selection_mode parameter; neuron_selection is instead done dynamically and only given to analyze()
"reverse model" is not a tf.keras model now, instead a graph of reverse_map.ReplacementLayer subclasses (defined via inputs and nodes)
the "reverse model" is built by calling reverse_map.reverse_map()
the analysis is computed by calling reverse_map.apply_reverse_map()
the "reverse model" is built from subclasses of reverse_map.ReplacementLayer. The core XAI functionality is implemented in this class, and any specific XAI method implementations are supposed to be subclasses of reverse_map.ReplacementLayer.
Wraps around a tf.keras layer (or block of layers); keeps track of next layers
Aggregates all inputs, then applies an extended forward pass, that
allows for wrapping around the application of the layer function (reverse_map.ReplacementLayer.wrap_hook()), e.g., GradientTapes
sends the output of that application to the next layers, together with a callback function to retrieve their explanations
performs neuron selction if required
Aggregates all explanations of the next layers, then computes own explanation, with
this computation being defined in reverse_map.ReplacementLayer.explain_hook()
the computed explanation being sent to previous layers via their callbacks
For new XAI methods, reverse_map.ReplacementLayer.apply(), reverse_map.ReplacementLayer.wrap_hook(), reverse_map.ReplacementLayer.explain_hook() should be implemented
"reverse model" is not a tf.keras model now, instead a graph of reverse_map.ReplacementLayer subclasses -> does this mean all the explain functions are applied each time?
what is the wrap_hook good for?
how would you implement "rewriting" of a graph/model? For example fusing the BN and conv layers?
Can you be a bit more specific? Since no tensorflow graph is built, this does mean the explain_hook function of each layer is applied for each sample. The Eager Execution does impact performance in favor of a lot more dynamic usage options, e.g., changing neuron_selection/ getting intermediate explanations / ... without having to define a completely new analyzer. Although, in my experience, the performance impact is not that terrible.
Mainly for calling the necessary forward pass(es) and defining GradientTapes around them
That would be a canonization issue in my opinion. I.e., I would rewrite the model before passing it to the analyzer. Specifically the BN/Conv fusion.