hiranumn / IntegratedGradients

Python/Keras implementation of integrated gradients presented in "Axiomatic Attribution for Deep Networks" for explaining any model defined in Keras framework.
MIT License
216 stars 51 forks source link

Problem of calculating gradient from embedding to word #9

Open pl8787 opened 6 years ago

pl8787 commented 6 years ago

The model can only get gradient for embedding layer. If the input of the model is word id and use Embedding Layer, the Integrated-Gradients return an error.

ValueError                                Traceback (most recent call last)
<ipython-input-8-223e71b35bf0> in <module>()
----> 1 ig = integrated_gradients(model)
      2 exp = ig.explain([X_val[0][1], X_val[1][1], X_val[2][1], X_val[3][1]] )

./IntegratedGradients/IntegratedGradients.py in __init__(self, model, outchannels, verbose)
     74             # Get tensor that calculates gradient
     75             if K.backend() == "tensorflow":
---> 76                 gradients = self.model.optimizer.get_gradients(self.model.output[:, c], self.model.input)
     77             if K.backend() == "theano":
     78                 gradients = self.model.optimizer.get_gradients(self.model.output[:, c].sum(), self.model.input)

~/.local/lib/python3.6/site-packages/keras/optimizers.py in get_gradients(self, loss, params)
     78         grads = K.gradients(loss, params)
     79         if None in grads:
---> 80             raise ValueError('An operation has `None` for gradient. '
     81                              'Please make sure that all of your ops have a '
     82                              'gradient defined (i.e. are differentiable). '

ValueError: An operation has `None` for gradient. Please make sure that all of your ops have a gradient defined (i.e. are differentiable). Common ops without gradient: K.argmax, K.round, K.eval.

However, I can get the gradient of embedding, how to determine the value of single words, for example in paper Section 6.3 Question Classification?

hiranumn commented 6 years ago

Embedding layers by definition do not pass gradient through it. The layer uses dictionally lookup from word index to whatever dimension embedding that you decide to use. There is no gradient going back to the indexes themselves.

However, there are gradients flowing back to the embedded vectors, so you can sum the attribution to the vectors to get the actual attribution values. At the end of the day, embedding layers are equivalent to fully connected layers with one-hot encoded inputs.

pl8787 commented 6 years ago

Thanks, I have modified code to set the start nodes of the network in https://github.com/pl8787/IntegratedGradients.

hiranumn commented 6 years ago

Sounds good!

inspirepassion commented 2 years ago

I also encounter this gradient value to be None issue, so after I check the code I solved by switching the default None option to Zero. Here, in this file /Users/username/opt/anaconda3/envs/ml/lib/python3.7/site-packages/tensorflow/python/ops/gradients_impl.py

there is this function signature:

iShot_2022-08-11_15 24 06

It actually lets you to choose default output for those unconnected node's gradient output. After I chose ZERO that issue solved.