I made a custom Taylor
class for Deep Taylor Decomposition. If you are interested in the details, check out models_3_2.py
in the models directory.
import os
import re
from tensorflow.examples.tutorials.mnist import input_data
from tensorflow.python.ops import nn_ops, gen_nn_ops
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
from models.models_2_4 import MNIST_CNN, Taylor
%matplotlib inline
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
images = mnist.train.images
labels = mnist.train.labels
logdir = './tf_logs/2_4_DTD/'
ckptdir = logdir + 'model'
if not os.path.exists(logdir):
os.mkdir(logdir)
Extracting MNIST_data/train-images-idx3-ubyte.gz Extracting MNIST_data/train-labels-idx1-ubyte.gz Extracting MNIST_data/t10k-images-idx3-ubyte.gz Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
with tf.name_scope('Classifier'):
# Initialize neural network
DNN = MNIST_CNN('CNN')
# Setup training process
X = tf.placeholder(tf.float32, [None, 784], name='X')
Y = tf.placeholder(tf.float32, [None, 10], name='Y')
activations, logits = DNN(X)
tf.add_to_collection('DTD', X)
for activation in activations:
tf.add_to_collection('DTD', activation)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=Y))
optimizer = tf.train.AdamOptimizer().minimize(cost, var_list=DNN.vars)
correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
cost_summary = tf.summary.scalar('Cost', cost)
accuray_summary = tf.summary.scalar('Accuracy', accuracy)
summary = tf.summary.merge_all()
This is the step where the DNN is trained to classify the 10 digits of the MNIST images. Summaries are written into the logdir and you can visualize the statistics using tensorboard by typing this command: tensorboard --lodir=./tf_logs
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
saver = tf.train.Saver()
file_writer = tf.summary.FileWriter(logdir, tf.get_default_graph())
# Hyper parameters
training_epochs = 15
batch_size = 100
for epoch in range(training_epochs):
total_batch = int(mnist.train.num_examples / batch_size)
avg_cost = 0
avg_acc = 0
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
_, c, a, summary_str = sess.run([optimizer, cost, accuracy, summary], feed_dict={X: batch_xs, Y: batch_ys})
avg_cost += c / total_batch
avg_acc += a / total_batch
file_writer.add_summary(summary_str, epoch * total_batch + i)
print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost), 'accuracy =', '{:.9f}'.format(avg_acc))
saver.save(sess, ckptdir)
print('Accuracy:', sess.run(accuracy, feed_dict={X: mnist.test.images, Y: mnist.test.labels}))
sess.close()
Epoch: 0001 cost = 0.155111813 accuracy = 0.951527280 Epoch: 0002 cost = 0.044594308 accuracy = 0.985636373 Epoch: 0003 cost = 0.029799474 accuracy = 0.990345463 Epoch: 0004 cost = 0.021161627 accuracy = 0.992818188 Epoch: 0005 cost = 0.017527232 accuracy = 0.994145460 Epoch: 0006 cost = 0.014087625 accuracy = 0.995490913 Epoch: 0007 cost = 0.013123321 accuracy = 0.995472732 Epoch: 0008 cost = 0.009770884 accuracy = 0.996800003 Epoch: 0009 cost = 0.009048406 accuracy = 0.996981821 Epoch: 0010 cost = 0.009553186 accuracy = 0.996981821 Epoch: 0011 cost = 0.007268998 accuracy = 0.997509093 Epoch: 0012 cost = 0.007693169 accuracy = 0.997618184 Epoch: 0013 cost = 0.005034720 accuracy = 0.998527274 Epoch: 0014 cost = 0.006306725 accuracy = 0.997745457 Epoch: 0015 cost = 0.004300387 accuracy = 0.998581820 Accuracy: 0.9917
Here we first rebuild the DNN graph from metagraph, restore DNN parameters from the checkpoint and then gather the necessary weight and biases for Deep Taylor Decomposition using the tf.get_collection()
function.
tf.reset_default_graph()
sess = tf.InteractiveSession()
new_saver = tf.train.import_meta_graph(ckptdir + '.meta')
new_saver.restore(sess, tf.train.latest_checkpoint(logdir))
weights = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope='CNN')
activations = tf.get_collection('DTD')
X = activations[0]
INFO:tensorflow:Restoring parameters from ./tf_logs/3_2_DTD/model
conv_ksize = [1, 3, 3, 1]
pool_ksize = [1, 2, 2, 1]
conv_strides = [1, 1, 1, 1]
pool_strides = [1, 2, 2, 1]
weights.reverse()
activations.reverse()
taylor = Taylor(activations, weights, conv_ksize, pool_ksize, conv_strides, pool_strides, 'Taylor')
Rs = []
for i in range(10):
Rs.append(taylor(i))
sample_imgs = []
for i in range(10):
sample_imgs.append(images[np.argmax(labels, axis=1) == i][3])
imgs = []
for i in range(10):
imgs.append(sess.run(Rs[i], feed_dict={X: sample_imgs[i][None,:]}))
The relevance scores are visualized as heat maps. You can see which features/data points influenced the DNN most its decision making.
plt.figure(figsize=(15,15))
for i in range(5):
plt.subplot(5, 2, 2 * i + 1)
plt.imshow(np.reshape(imgs[2 * i], [28, 28]), cmap='hot_r')
plt.title('Digit: {}'.format(2 * i))
plt.colorbar()
plt.subplot(5, 2, 2 * i + 2)
plt.imshow(np.reshape(imgs[2 * i + 1], [28, 28]), cmap='hot_r')
plt.title('Digit: {}'.format(2 * i + 1))
plt.colorbar()
plt.tight_layout()