Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Utilities to compute SaliencyMasks."""
import numpy as np
import tensorflow as tf
from .base import SaliencyMask
class GradCam(SaliencyMask):
"""A SaliencyMask class that computes saliency masks with Grad-CAM.
https://arxiv.org/abs/1610.02391
Example usage (based on Examples.ipynb):
grad_cam = GradCam(graph, sess, y, images, conv_layer = end_points['Mixed_7c'])
grad_mask_2d = grad_cam.GetMask(im, feed_dict = {neuron_selector: prediction_class},
should_resize = False,
three_dims = False)
The Grad-CAM paper suggests using the last convolutional layer, which would
be 'Mixed_5c' in inception_v2 and 'Mixed_7c' in inception_v3.
"""
def __init__(self, graph, session, y, x, conv_layer):
stdev = stdev_spread * (np.max(x_value) - np.min(x_value))
def single_mask(i):
noise = np.random.normal(0, stdev, x_value.shape)
x_plus_noise = x_value + noise
return self.GetMask(x_plus_noise, feed_dict, **kwargs)
pool = multiprocessing.Pool(num_threads)
grads = np.array(pool.map(single_mask, range(nsamples)))
if magnitude:
grads = grads * grads
total_gradients = np.sum(grads, axis=0)
return total_gradients / nsamples
class GradientSaliency(SaliencyMask):
r"""A SaliencyMask class that computes saliency masks with a gradient."""
def __init__(self, graph, session, y, x):
super(GradientSaliency, self).__init__(graph, session, y, x)
self.gradients_node = tf.gradients(y, x)[0]
def GetMask(self, x_value, feed_dict={}):
"""Returns a vanilla gradient mask.
Args:
x_value: Input value, not batched.
feed_dict: (Optional) feed dictionary to pass to the session.run call.
"""
feed_dict[self.x] = [x_value]
return self.session.run(self.gradients_node, feed_dict=feed_dict)[0]
# TODO(tolgab) add return baseline predictions functionality from XRAI API
# Predictions for the baselines that were used for the calculation of IG
# attributions. The value is set only when
# XraiParameters.return_baseline_predictions is set to True.
# self.baseline_predictions = None
# IG attributions for individual baselines. The value is set only when
# XraiParameters.ig_attributions is set to True. For the dimensions of the
# output see XraiParameters.return_ig_for_every _step.
self.ig_attribution = None
# The result of the XRAI segmentation. The value is set only when
# XraiParameters.return_xrai_segments is set to True. For the dimensions of
# the output see XraiParameters.flatten_xrai_segments.
self.segments = None
class XRAI(SaliencyMask):
def __init__(self, graph, session, y, x):
super(XRAI, self).__init__(graph, session, y, x)
# Initialize integrated gradients.
self._integrated_gradients = IntegratedGradients(graph, session, y, x)
def _get_integrated_gradients(self, im, feed_dict, baselines, steps):
""" Takes mean of attributions from all baselines
"""
grads = []
for baseline in baselines:
grads.append(
self._integrated_gradients.GetMask(im,
feed_dict=feed_dict,
x_baseline=baseline,
x_steps=steps))