# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# +
import tensorflow as tf
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.models import Model

import tempfile, sys, os
sys.path.insert(0, os.path.abspath('..'))
from deepexplain.tensorflow import DeepExplain
from keras import backend as K
# -

#toy model with based on Integrated Gradients paper (https://arxiv.org/pdf/1703.01365.pdf)
with DeepExplain(session=K.get_session()) as de:
    model = Sequential()
    model.add(Dense(2, activation=Activation('relu'), input_dim=2))
    model.add(Dense(1, activation=Activation('relu')))
    
    w1 = np.array([[1, 0], [0, 1]])
    b1 = np.array([0, 0])
    model.layers[0].set_weights([w1, b1]) #simple ReLU layer
    
    w2 = np.array([[1], [-1]])
    b2 = np.array([-1])
    model.layers[1].set_weights([w2, b2]) #z1 - 1 - z2 
    print(model.layers[0].get_weights())
    
    #alpha = .1
    #print(-15.75*alpha+9)
    #print(K.get_session().run(model.layers[-1].output, feed_dict={model.layers[0].input:np.array([[-2*alpha, 
                                         #                                                 3*alpha]])}))    
    baseline = np.array([0,0])
    xs = np.array([[3, 1]])
    input_tensor = model.layers[0].input
    target_tensor = model.layers[-1].output
    #fModel = Model(inputs=input_tensor, outputs = model.layers[-1].output)
    #target_tensor = fModel(input_tensor)
    print(target_tensor.shape)
    print(model.predict(xs)) #sanity check -
    

# +
ground_truth = np.array([1.5, -0.5]) #self-calculated
steps = [1, 5, 10, 20, 50]#, 100, 200, 300, 400, 500]
methods = ['intgrad', 'idl']
attribs = {}
diffs = {}

with DeepExplain(session=K.get_session()) as de:
    attrib_deeplift = de.explain('deeplift', target_tensor, input_tensor, xs)[0] #1 numpy array

    for method in methods:
        attribs[method] = []
        diffs[method] = []
        for step in steps:
            attrib = de.explain(method, target_tensor, input_tensor, xs, steps=step)[0] #1 numpy array
            attribs[method].append(attrib) 
            diffs[method].append(np.sum(np.abs(attrib - ground_truth))) #append 1 number
        
    #attribs['intgrad'] = de.explain('intgrad', target_tensor, input_tensor, xs, steps=steps)
    #attribs['integdeeplift'] = de.explain('integdeeplift', target_tensor, input_tensor, xs, steps=steps)
    print("Done!")
    
# -

print(attrib_deeplift)
print(attribs)
import matplotlib.pyplot as plt
# %matplotlib inline
plt.title("Integrated Gradients vs. Integrated DeepLIFT Proximity to Ground Truth (Log scale)")
plt.xlabel("Number of Steps")
plt.ylabel("Sum of Absolute Error") #absolute difference between attribution & ground truth
for method in methods:
    plt.plot(steps, diffs[method], 'o', label=method)
plt.legend(loc='upper right')


print(attribs['intgrad'])
print(attribs['idl'])

#toy model with based on Integrated Gradients paper (https://arxiv.org/pdf/1703.01365.pdf)
with DeepExplain(session=K.get_session()) as de:
    model_2 = Sequential()
    model_2.add(Dense(2, activation=Activation('relu'), input_dim=2))
    model_2.add(Dense(1, activation=Activation('relu')))
    
    w1 = np.array([[1, 0], [0, 1]])
    b1 = np.array([-1, 0])
    model_2.layers[0].set_weights([w1, b1]) #x1-1, x2
    
    w2 = np.array([[1], [-1]])
    b2 = np.array([0])
    model_2.layers[1].set_weights([w2, b2]) #z1 - 1 - z2 
    #print(model.layers[0].get_weights())
    
    #alpha = .1
    #print(-15.75*alpha+9)
    #print(K.get_session().run(model.layers[-1].output, feed_dict={model.layers[0].input:np.array([[-2*alpha, 
                                         #                                                 3*alpha]])}))    
    baseline = np.array([[0,0]])
    xs = np.array([[3, 1]])
    input_tensor = model_2.layers[0].input
    target_tensor = model_2.layers[-1].output
    #fModel = Model(inputs=input_tensor, outputs = model.layers[-1].output)
    #target_tensor = fModel(input_tensor)
    print(input_tensor.shape)
    print(target_tensor.shape)
    print(model_2.predict(baseline))
    print(model_2.predict(xs)) #sanity check -
    

# +
ground_truth = np.array([1.5, -0.5]) #self-calculated
steps = [1,5]#1, 5, 10, 20, 50, 100, 1000]# 200, 300, 400, 500]
methods = ['idl_true']
attribs_2 = {}
diffs_2 = {}
xs = np.array([[3, 1]])

with DeepExplain(session=K.get_session()) as de:
    #attrib_deeplift = de.explain('deeplift', target_tensor, input_tensor, xs)[0] #1 numpy array

    for method in methods:
        attribs_2[method] = []
        diffs_2[method] = []
        for step in steps:
            attrib = de.explain(method, target_tensor, input_tensor, xs, steps=step)[0] #1 numpy array
            attribs_2[method].append(attrib) 
            diffs_2[method].append(np.sum(np.abs(attrib - ground_truth))) #append 1 number
        
    #attribs['intgrad'] = de.explain('intgrad', target_tensor, input_tensor, xs, steps=steps)
    #attribs['integdeeplift'] = de.explain('integdeeplift', target_tensor, input_tensor, xs, steps=steps)
    print("Done!")

print(attribs_2)
#print(attrib_deeplift)
# -





StarcoderdataJupyterScriptsDedupFiltered