dl-backtrace 0.0.14__py3-none-any.whl → 0.0.16.dev4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dl-backtrace might be problematic. Click here for more details.
- dl_backtrace/pytorch_backtrace/backtrace/backtrace.py +173 -44
- dl_backtrace/pytorch_backtrace/backtrace/utils/__init__.py +3 -0
- dl_backtrace/pytorch_backtrace/backtrace/utils/encoder.py +183 -0
- dl_backtrace/pytorch_backtrace/backtrace/utils/encoder_decoder.py +489 -0
- dl_backtrace/pytorch_backtrace/backtrace/utils/helper.py +95 -0
- dl_backtrace/pytorch_backtrace/backtrace/utils/prop.py +481 -0
- dl_backtrace/tf_backtrace/backtrace/__init__.py +1 -2
- dl_backtrace/tf_backtrace/backtrace/activation_info.py +33 -0
- dl_backtrace/tf_backtrace/backtrace/backtrace.py +506 -279
- dl_backtrace/tf_backtrace/backtrace/models.py +25 -0
- dl_backtrace/tf_backtrace/backtrace/server.py +27 -0
- dl_backtrace/tf_backtrace/backtrace/utils/__init__.py +5 -2
- dl_backtrace/tf_backtrace/backtrace/utils/encoder.py +206 -0
- dl_backtrace/tf_backtrace/backtrace/utils/encoder_decoder.py +501 -0
- dl_backtrace/tf_backtrace/backtrace/utils/helper.py +99 -0
- dl_backtrace/tf_backtrace/backtrace/utils/utils_contrast.py +1132 -0
- dl_backtrace/tf_backtrace/backtrace/utils/utils_prop.py +1582 -0
- dl_backtrace/version.py +2 -2
- {dl_backtrace-0.0.14.dist-info → dl_backtrace-0.0.16.dev4.dist-info}/METADATA +2 -2
- dl_backtrace-0.0.16.dev4.dist-info/RECORD +29 -0
- {dl_backtrace-0.0.14.dist-info → dl_backtrace-0.0.16.dev4.dist-info}/WHEEL +1 -1
- dl_backtrace/tf_backtrace/backtrace/config.py +0 -41
- dl_backtrace/tf_backtrace/backtrace/utils/contrast.py +0 -834
- dl_backtrace/tf_backtrace/backtrace/utils/prop.py +0 -725
- dl_backtrace-0.0.14.dist-info/RECORD +0 -21
- {dl_backtrace-0.0.14.dist-info → dl_backtrace-0.0.16.dev4.dist-info}/LICENSE +0 -0
- {dl_backtrace-0.0.14.dist-info → dl_backtrace-0.0.16.dev4.dist-info}/top_level.txt +0 -0
|
@@ -1,84 +1,111 @@
|
|
|
1
|
-
import
|
|
2
|
-
from
|
|
1
|
+
import gc
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from tqdm import tqdm
|
|
4
|
+
import tensorflow.keras as keras
|
|
5
|
+
import numpy as np
|
|
6
|
+
import tensorflow as tf
|
|
7
|
+
from dl_backtrace.tf_backtrace.backtrace.utils import utils_prop as UP
|
|
8
|
+
from dl_backtrace.tf_backtrace.backtrace.utils import utils_contrast as UC
|
|
9
|
+
from dl_backtrace.tf_backtrace.backtrace.activation_info import activation_master
|
|
10
|
+
from dl_backtrace.tf_backtrace.backtrace.utils import encoder as EN
|
|
11
|
+
from dl_backtrace.tf_backtrace.backtrace.utils import encoder_decoder as ED
|
|
12
|
+
from dl_backtrace.tf_backtrace.backtrace.utils import helper as HP
|
|
3
13
|
|
|
4
|
-
from
|
|
5
|
-
from
|
|
6
|
-
from
|
|
14
|
+
from tensorflow.keras import backend as K
|
|
15
|
+
from tensorflow.keras import losses
|
|
16
|
+
from tensorflow.keras.backend import sigmoid
|
|
17
|
+
from tensorflow.keras.layers import (
|
|
18
|
+
LSTM,
|
|
19
|
+
Activation,
|
|
20
|
+
Add,
|
|
21
|
+
AveragePooling2D,
|
|
22
|
+
BatchNormalization,
|
|
23
|
+
Concatenate,
|
|
24
|
+
Conv2D,
|
|
25
|
+
Dense,
|
|
26
|
+
Dropout,
|
|
27
|
+
Flatten,
|
|
28
|
+
GlobalAveragePooling2D,
|
|
29
|
+
GlobalMaxPooling2D,
|
|
30
|
+
Input,
|
|
31
|
+
MaxPooling2D,
|
|
32
|
+
Reshape,
|
|
33
|
+
)
|
|
34
|
+
from tensorflow.keras.models import Model, Sequential
|
|
35
|
+
from tensorflow.keras.optimizers import SGD, Adadelta, Adagrad, Adam, Adamax, Nadam, RMSprop
|
|
36
|
+
from tensorflow.keras.regularizers import l2
|
|
37
|
+
from tensorflow.keras.utils import get_custom_objects
|
|
38
|
+
from numpy.lib.stride_tricks import as_strided
|
|
7
39
|
|
|
8
40
|
|
|
9
41
|
class Backtrace(object):
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
inp_name = model.input.name
|
|
31
|
-
self.layer_stack.append(inp_name)
|
|
32
|
-
self.model_resource[1][inp_name] = {}
|
|
33
|
-
self.model_resource[1][inp_name]["name"] = inp_name
|
|
34
|
-
self.model_resource[1][inp_name]["type"] = "input"
|
|
35
|
-
self.model_resource[1][inp_name]["parent"] = []
|
|
36
|
-
self.model_resource[1][inp_name]["child"] = None
|
|
37
|
-
self.model_resource[3].append(inp_name)
|
|
38
|
-
self.sequential = True
|
|
42
|
+
def __init__(self, model=None, activation_dict={}, model_type=None):
|
|
43
|
+
self.model = model
|
|
44
|
+
self.model_type = model_type
|
|
45
|
+
if model_type == 'encoder':
|
|
46
|
+
# create a tree-like structure for encoder model
|
|
47
|
+
self.model_resource = EN.build_encoder_tree(model)
|
|
48
|
+
# create a layer stack for encoder model
|
|
49
|
+
self.create_layer_stack()
|
|
50
|
+
# extract the encoder model weights
|
|
51
|
+
self.model_weights = EN.extract_encoder_weights(model)
|
|
52
|
+
# # calculate the output of each submodule of the encoder model
|
|
53
|
+
# self.all_out_model = EN.create_encoder_output(model)
|
|
54
|
+
elif model_type == 'encoder_decoder':
|
|
55
|
+
# create a tree-like structure and layer_stack for encoder-decoder model
|
|
56
|
+
self.model_resource, self.layer_stack = ED.build_enc_dec_tree(model)
|
|
57
|
+
# extract the encoder-decoder model weights
|
|
58
|
+
self.model_weights = ED.extract_encoder_decoder_weights(model)
|
|
59
|
+
# # calculate the output of each submodule of the encoder-decoder model
|
|
60
|
+
# self.all_out_model = ED.calculate_encoder_decoder_output(model)
|
|
61
|
+
|
|
39
62
|
else:
|
|
40
|
-
self.
|
|
41
|
-
|
|
63
|
+
self.create_tree(model.layers)
|
|
64
|
+
self.create_model_output(model)
|
|
65
|
+
self.create_layer_stack()
|
|
42
66
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
self.
|
|
67
|
+
if len(self.model_resource["inputs"])==0 or model.__module__.split(".")[-1]=='sequential':
|
|
68
|
+
inp_name = model.input.name
|
|
69
|
+
self.layer_stack.append(inp_name)
|
|
70
|
+
self.model_resource["graph"][inp_name] = {}
|
|
71
|
+
self.model_resource["graph"][inp_name]["name"] = inp_name
|
|
72
|
+
self.model_resource["graph"][inp_name]["type"] = "input"
|
|
73
|
+
self.model_resource["graph"][inp_name]["parent"] = []
|
|
74
|
+
self.model_resource["graph"][inp_name]["child"] = None
|
|
75
|
+
self.model_resource["inputs"].append(inp_name)
|
|
76
|
+
self.sequential = True
|
|
47
77
|
else:
|
|
48
|
-
self.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
78
|
+
self.sequential = False
|
|
79
|
+
try:
|
|
80
|
+
if len(activation_dict) == 0:
|
|
81
|
+
self.build_activation_dict(model)
|
|
82
|
+
else:
|
|
83
|
+
self.activation_dict = activation_dict
|
|
84
|
+
except Exception as e:
|
|
85
|
+
print(e)
|
|
86
|
+
temp_dict = {}
|
|
87
|
+
for l in model.layers:
|
|
88
|
+
temp_dict[l.name] = activation_master["None"]
|
|
89
|
+
self.activation_dict = temp_dict
|
|
56
90
|
|
|
57
|
-
def build_activation_dict(self,
|
|
58
|
-
# Builds an activation dictionary by inspecting the activation functions of the layers in the model.
|
|
91
|
+
def build_activation_dict(self,model):
|
|
59
92
|
activation_dict = {}
|
|
60
93
|
for l in model.layers:
|
|
61
|
-
if not hasattr(l,
|
|
94
|
+
if not hasattr(l,"activation"):
|
|
62
95
|
activation_dict[l.name] = activation_master["None"]
|
|
63
96
|
continue
|
|
64
97
|
a1 = l.activation
|
|
65
98
|
func_name = str(a1).split(" ")
|
|
66
99
|
if func_name[0] == "<function":
|
|
67
|
-
activation_dict[l.name] = activation_master.get(
|
|
68
|
-
func_name[1], activation_master["None"]
|
|
69
|
-
)
|
|
100
|
+
activation_dict[l.name] = activation_master.get(func_name[1],activation_master["None"])
|
|
70
101
|
else:
|
|
71
102
|
a2 = a1.activation
|
|
72
103
|
func_name = str(a2).split(" ")
|
|
73
104
|
if func_name[0] == "<function":
|
|
74
|
-
activation_dict[l.name] = activation_master.get(
|
|
75
|
-
func_name[1], activation_master["None"]
|
|
76
|
-
)
|
|
105
|
+
activation_dict[l.name] = activation_master.get(func_name[1],activation_master["None"])
|
|
77
106
|
self.activation_dict = activation_dict
|
|
78
107
|
|
|
79
108
|
def create_tree(self, layers):
|
|
80
|
-
#Creates a tree structure representing the layers of the model.
|
|
81
|
-
#categorizes layers as input, output, or intermediate layers and establishes parent-child relationships between layers.
|
|
82
109
|
ltree = {}
|
|
83
110
|
layer_tree = {}
|
|
84
111
|
inputs = []
|
|
@@ -120,21 +147,20 @@ class Backtrace(object):
|
|
|
120
147
|
intermediates.append(i.name)
|
|
121
148
|
|
|
122
149
|
outputs = list(set(outputs) - set(intermediates))
|
|
123
|
-
self.model_resource =
|
|
150
|
+
self.model_resource = {"layers":layer_tree, "graph":ltree, "outputs":outputs, "inputs":inputs}
|
|
124
151
|
|
|
125
152
|
def create_layer_stack(self):
|
|
126
|
-
#Creates a layer stack that defines the order in which layers should be processed during backpropagation.
|
|
127
153
|
model_resource = self.model_resource
|
|
128
|
-
start_layer = model_resource[
|
|
154
|
+
start_layer = model_resource["outputs"][0]
|
|
129
155
|
layer_stack = [start_layer]
|
|
130
156
|
temp_stack = [start_layer]
|
|
131
|
-
while len(layer_stack) < len(model_resource[
|
|
157
|
+
while len(layer_stack) < len(model_resource["layers"]):
|
|
132
158
|
start_layer = temp_stack.pop(0)
|
|
133
|
-
if model_resource[
|
|
134
|
-
child_nodes = model_resource[
|
|
159
|
+
if model_resource["graph"][start_layer]["child"]:
|
|
160
|
+
child_nodes = model_resource["graph"][start_layer]["child"]
|
|
135
161
|
for ch in child_nodes:
|
|
136
162
|
node_check = True
|
|
137
|
-
for pa in model_resource[
|
|
163
|
+
for pa in model_resource["graph"][ch]["parent"]:
|
|
138
164
|
if pa not in layer_stack:
|
|
139
165
|
node_check = False
|
|
140
166
|
break
|
|
@@ -145,20 +171,16 @@ class Backtrace(object):
|
|
|
145
171
|
self.layer_stack = layer_stack
|
|
146
172
|
|
|
147
173
|
def create_model_output(self, model):
|
|
148
|
-
#Creates a new model that produces the output of each layer in the neural network.
|
|
149
174
|
self.layers = [[], []]
|
|
150
|
-
for l in self.model_resource[
|
|
151
|
-
# if l not in model_resource[3]:
|
|
175
|
+
for l in self.model_resource["layers"]:
|
|
152
176
|
self.layers[0].append(l)
|
|
153
|
-
self.layers[1].append(self.model_resource[
|
|
177
|
+
self.layers[1].append(self.model_resource["layers"][l])
|
|
154
178
|
|
|
155
179
|
self.all_out_model = Model(
|
|
156
180
|
inputs=model.input, outputs=[layer.output for layer in self.layers[1]]
|
|
157
181
|
)
|
|
158
182
|
|
|
159
183
|
def predict(self, inputs):
|
|
160
|
-
#takes input data inputs and performs a forward pass through the neural network model to compute the output of each layer.
|
|
161
|
-
#returns a dictionary that maps layer names to their corresponding outputs.
|
|
162
184
|
all_out = self.all_out_model(inputs, training=False)
|
|
163
185
|
temp_out = {}
|
|
164
186
|
for i, v in enumerate(self.layers[0]):
|
|
@@ -166,28 +188,27 @@ class Backtrace(object):
|
|
|
166
188
|
if self.sequential:
|
|
167
189
|
temp_out[self.layer_stack[-1]] = inputs
|
|
168
190
|
return temp_out
|
|
191
|
+
|
|
192
|
+
def eval(self, all_out, start_wt=[], mode="default",multiplier=100.0,
|
|
193
|
+
scaler=None, max_unit=0,thresholding=0.5,
|
|
194
|
+
task="binary-classification",predicted_token=None):
|
|
169
195
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
#This method is used for evaluating layer-wise relevance based on different modes.
|
|
180
|
-
if mode == "default":
|
|
181
|
-
output = self.proportional_eval(
|
|
182
|
-
all_out=all_out,
|
|
183
|
-
start_wt=start_wt,
|
|
184
|
-
multiplier=multiplier,
|
|
185
|
-
scaler=0,
|
|
186
|
-
max_unit=0,
|
|
187
|
-
)
|
|
196
|
+
if mode=="default":
|
|
197
|
+
output = self.proportional_eval(all_out=all_out,
|
|
198
|
+
start_wt=start_wt ,
|
|
199
|
+
multiplier=multiplier,
|
|
200
|
+
scaler=scaler,
|
|
201
|
+
max_unit=max_unit,
|
|
202
|
+
thresholding=thresholding,
|
|
203
|
+
task=task,
|
|
204
|
+
predicted_token=predicted_token)
|
|
188
205
|
return output
|
|
189
|
-
elif mode
|
|
190
|
-
temp_output = self.contrast_eval(all_out=all_out,
|
|
206
|
+
elif mode=="contrast":
|
|
207
|
+
temp_output = self.contrast_eval(all_out=all_out,
|
|
208
|
+
multiplier=multiplier,
|
|
209
|
+
scaler=scaler,
|
|
210
|
+
thresholding=thresholding,
|
|
211
|
+
task=task)
|
|
191
212
|
output = {}
|
|
192
213
|
for k in temp_output[0].keys():
|
|
193
214
|
output[k] = {}
|
|
@@ -195,34 +216,41 @@ class Backtrace(object):
|
|
|
195
216
|
output[k]["Negative"] = temp_output[1][k]
|
|
196
217
|
return output
|
|
197
218
|
|
|
198
|
-
def proportional_eval(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
#iteratively calculates relevance for each layer based on the layer's type (e.g., Dense, Conv2D, LSTM) and activation function.
|
|
203
|
-
#returns a dictionary mapping layer names to their relevance scores.
|
|
219
|
+
def proportional_eval(self, all_out, start_wt=[] ,
|
|
220
|
+
multiplier=100.0, scaler=None, max_unit=0,
|
|
221
|
+
predicted_token=None, thresholding=0.5,
|
|
222
|
+
task="binary-classification"):
|
|
204
223
|
model_resource = self.model_resource
|
|
205
224
|
activation_dict = self.activation_dict
|
|
206
225
|
inputcheck = False
|
|
207
|
-
out_layer = model_resource[
|
|
226
|
+
out_layer = model_resource["outputs"][0]
|
|
208
227
|
all_wt = {}
|
|
209
228
|
if len(start_wt) == 0:
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
229
|
+
if self.model_type == 'encoder':
|
|
230
|
+
start_wt = UP.calculate_start_wt_UP(all_out[out_layer])
|
|
231
|
+
all_wt[out_layer] = start_wt * multiplier
|
|
232
|
+
layer_stack = self.layer_stack
|
|
233
|
+
all_wts = self.model_weights
|
|
213
234
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
235
|
+
elif self.model_type == 'encoder_decoder':
|
|
236
|
+
start_wt = UP.calculate_enc_dec_start_wt(all_out[out_layer][0], predicted_token)
|
|
237
|
+
all_wt[out_layer] = start_wt * multiplier
|
|
238
|
+
layer_stack = self.layer_stack
|
|
239
|
+
all_wts = self.model_weights
|
|
240
|
+
|
|
241
|
+
else:
|
|
242
|
+
start_wt = UP.calculate_start_wt(all_out[out_layer],scaler,thresholding,task=task)
|
|
243
|
+
all_wt[out_layer] = start_wt * multiplier
|
|
244
|
+
layer_stack = self.layer_stack
|
|
245
|
+
|
|
246
|
+
for start_layer in tqdm(layer_stack):
|
|
247
|
+
if model_resource["graph"][start_layer]["child"]:
|
|
248
|
+
child_nodes = model_resource["graph"][start_layer]["child"]
|
|
219
249
|
for ch in child_nodes:
|
|
220
250
|
if ch not in all_wt:
|
|
221
251
|
all_wt[ch] = np.zeros_like(all_out[ch][0])
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
print('dense')
|
|
225
|
-
l1 = model_resource[0][start_layer]
|
|
252
|
+
if model_resource["graph"][start_layer]["class"] == "Dense":
|
|
253
|
+
l1 = model_resource["layers"][start_layer]
|
|
226
254
|
w1 = l1.weights[0]
|
|
227
255
|
b1 = l1.weights[1]
|
|
228
256
|
temp_wt = UP.calculate_wt_fc(
|
|
@@ -230,68 +258,158 @@ class Backtrace(object):
|
|
|
230
258
|
all_out[child_nodes[0]][0],
|
|
231
259
|
w1,
|
|
232
260
|
b1,
|
|
233
|
-
activation_dict[model_resource[
|
|
261
|
+
activation_dict[model_resource["graph"][start_layer]["name"]],
|
|
234
262
|
)
|
|
235
263
|
all_wt[child_nodes[0]] += temp_wt
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
l1 = model_resource[0][start_layer]
|
|
264
|
+
elif model_resource["graph"][start_layer]["class"] == "Conv2D":
|
|
265
|
+
l1 = model_resource["layers"][start_layer]
|
|
239
266
|
w1 = l1.weights[0]
|
|
240
267
|
b1 = l1.weights[1]
|
|
268
|
+
pad1 = l1.padding
|
|
269
|
+
strides1 = l1.strides
|
|
241
270
|
temp_wt = UP.calculate_wt_conv(
|
|
242
271
|
all_wt[start_layer],
|
|
243
272
|
all_out[child_nodes[0]][0],
|
|
244
273
|
w1,
|
|
245
274
|
b1,
|
|
246
|
-
|
|
275
|
+
pad1,
|
|
276
|
+
strides1,
|
|
277
|
+
activation_dict[model_resource["graph"][start_layer]["name"]],
|
|
278
|
+
)
|
|
279
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
280
|
+
elif model_resource["graph"][start_layer]["class"] == "Conv2DTranspose":
|
|
281
|
+
l1 = model_resource["layers"][start_layer]
|
|
282
|
+
w1 = l1.weights[0]
|
|
283
|
+
b1 = l1.weights[1]
|
|
284
|
+
pad1 = l1.padding
|
|
285
|
+
strides1 = l1.strides
|
|
286
|
+
temp_wt = UP.calculate_wt_conv2d_transpose(
|
|
287
|
+
all_wt[start_layer],
|
|
288
|
+
all_out[child_nodes[0]][0],
|
|
289
|
+
w1,
|
|
290
|
+
b1,
|
|
291
|
+
pad1,
|
|
292
|
+
strides1,
|
|
293
|
+
activation_dict[model_resource["graph"][start_layer]["name"]],
|
|
247
294
|
)
|
|
248
295
|
all_wt[child_nodes[0]] += temp_wt
|
|
249
|
-
elif model_resource[
|
|
296
|
+
elif model_resource["graph"][start_layer]["class"] == "Conv1D":
|
|
297
|
+
l1 = model_resource["layers"][start_layer]
|
|
298
|
+
w1 = l1.weights[0]
|
|
299
|
+
b1 = l1.weights[1]
|
|
300
|
+
pad1 = l1.padding
|
|
301
|
+
strides1 = l1.strides[0]
|
|
302
|
+
temp_wt = UP.calculate_wt_conv_1d(
|
|
303
|
+
all_wt[start_layer],
|
|
304
|
+
all_out[child_nodes[0]][0],
|
|
305
|
+
w1,
|
|
306
|
+
b1,
|
|
307
|
+
pad1,
|
|
308
|
+
strides1,
|
|
309
|
+
activation_dict[model_resource["graph"][start_layer]["name"]],
|
|
310
|
+
)
|
|
311
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
312
|
+
elif model_resource["graph"][start_layer]["class"] == "Conv1DTranspose":
|
|
313
|
+
l1 = model_resource["layers"][start_layer]
|
|
314
|
+
w1 = l1.weights[0]
|
|
315
|
+
b1 = l1.weights[1]
|
|
316
|
+
pad1 = l1.padding
|
|
317
|
+
strides1 = l1.strides[0]
|
|
318
|
+
temp_wt = UP.calculate_wt_conv1d_transpose(
|
|
319
|
+
all_wt[start_layer],
|
|
320
|
+
all_out[child_nodes[0]][0],
|
|
321
|
+
w1,
|
|
322
|
+
b1,
|
|
323
|
+
pad1,
|
|
324
|
+
strides1,
|
|
325
|
+
activation_dict[model_resource["graph"][start_layer]["name"]],
|
|
326
|
+
)
|
|
327
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
328
|
+
elif model_resource["graph"][start_layer]["class"] == "Reshape":
|
|
250
329
|
temp_wt = UP.calculate_wt_rshp(
|
|
251
330
|
all_wt[start_layer], all_out[child_nodes[0]][0]
|
|
252
331
|
)
|
|
253
332
|
all_wt[child_nodes[0]] += temp_wt
|
|
254
|
-
elif model_resource[
|
|
333
|
+
elif model_resource["graph"][start_layer]["class"] == "Flatten":
|
|
255
334
|
temp_wt = UP.calculate_wt_rshp(
|
|
256
335
|
all_wt[start_layer], all_out[child_nodes[0]][0]
|
|
257
336
|
)
|
|
258
337
|
all_wt[child_nodes[0]] += temp_wt
|
|
259
|
-
elif
|
|
260
|
-
model_resource[1][start_layer]["class"] == "GlobalAveragePooling2D"
|
|
261
|
-
):
|
|
338
|
+
elif model_resource["graph"][start_layer]["class"] == "GlobalAveragePooling2D":
|
|
262
339
|
temp_wt = UP.calculate_wt_gavgpool(
|
|
263
340
|
all_wt[start_layer], all_out[child_nodes[0]][0]
|
|
264
341
|
)
|
|
265
342
|
all_wt[child_nodes[0]] += temp_wt
|
|
266
|
-
elif model_resource[
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
all_wt[start_layer], all_out[child_nodes[0]][0], l1.pool_size
|
|
343
|
+
elif model_resource["graph"][start_layer]["class"] == "GlobalAveragePooling1D":
|
|
344
|
+
temp_wt = UP.calculate_wt_gavgpool_1d(
|
|
345
|
+
all_wt[start_layer], all_out[child_nodes[0]][0]
|
|
270
346
|
)
|
|
271
347
|
all_wt[child_nodes[0]] += temp_wt
|
|
272
|
-
elif model_resource[
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
all_wt[start_layer], all_out[child_nodes[0]][0], l1.pool_size
|
|
348
|
+
elif model_resource["graph"][start_layer]["class"] == "GlobalMaxPooling2D":
|
|
349
|
+
temp_wt = UP.calculate_wt_gmaxpool_2d(
|
|
350
|
+
all_wt[start_layer], all_out[child_nodes[0]][0]
|
|
276
351
|
)
|
|
277
352
|
all_wt[child_nodes[0]] += temp_wt
|
|
278
|
-
elif model_resource[
|
|
353
|
+
elif model_resource["graph"][start_layer]["class"] == "GlobalMaxPooling1D":
|
|
354
|
+
temp_wt = UP.calculate_wt_gmaxpool_1d(
|
|
355
|
+
all_wt[start_layer], all_out[child_nodes[0]][0]
|
|
356
|
+
)
|
|
357
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
358
|
+
elif model_resource["graph"][start_layer]["class"] == 'ZeroPadding2D':
|
|
359
|
+
l1 = model_resource["layers"][start_layer]
|
|
360
|
+
pad1 = l1.padding
|
|
361
|
+
temp_wt = UP.calculate_wt_zero_pad(all_wt[start_layer],
|
|
362
|
+
all_out[child_nodes[0]][0],
|
|
363
|
+
pad1)
|
|
364
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
365
|
+
elif model_resource["graph"][start_layer]["class"] == 'MaxPooling2D':
|
|
366
|
+
l1 = model_resource["layers"][start_layer]
|
|
367
|
+
pad1 = l1.padding
|
|
368
|
+
strides1 = l1.strides
|
|
369
|
+
temp_wt = UP.calculate_wt_maxpool(all_wt[start_layer],
|
|
370
|
+
all_out[child_nodes[0]][0],
|
|
371
|
+
l1.pool_size, pad1, strides1)
|
|
372
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
373
|
+
elif model_resource["graph"][start_layer]["class"] == 'MaxPooling1D':
|
|
374
|
+
l1 = model_resource["layers"][start_layer]
|
|
375
|
+
pad1 = l1.padding
|
|
376
|
+
strides1 = l1.strides
|
|
377
|
+
temp_wt = UP.calculate_wt_maxpool_1d(all_wt[start_layer],
|
|
378
|
+
all_out[child_nodes[0]][0],
|
|
379
|
+
l1.pool_size, pad1, strides1)
|
|
380
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
381
|
+
elif model_resource["graph"][start_layer]["class"] == 'AveragePooling2D':
|
|
382
|
+
l1 = model_resource["layers"][start_layer]
|
|
383
|
+
pad1 = l1.padding
|
|
384
|
+
strides1 = l1.strides
|
|
385
|
+
temp_wt = UP.calculate_wt_avgpool(all_wt[start_layer],
|
|
386
|
+
all_out[child_nodes[0]][0],
|
|
387
|
+
l1.pool_size, pad1, strides1)
|
|
388
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
389
|
+
elif model_resource["graph"][start_layer]["class"] == 'AveragePooling1D':
|
|
390
|
+
l1 = model_resource["layers"][start_layer]
|
|
391
|
+
pad1 = l1.padding
|
|
392
|
+
strides1 = l1.strides
|
|
393
|
+
temp_wt = UP.calculate_wt_avgpool_1d(all_wt[start_layer],
|
|
394
|
+
all_out[child_nodes[0]][0],
|
|
395
|
+
l1.pool_size, pad1, strides1)
|
|
396
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
397
|
+
elif model_resource["graph"][start_layer]["class"] == "Concatenate":
|
|
279
398
|
temp_wt = UP.calculate_wt_concat(
|
|
280
399
|
all_wt[start_layer],
|
|
281
400
|
[all_out[ch] for ch in child_nodes],
|
|
282
|
-
model_resource[
|
|
401
|
+
model_resource["layers"][start_layer].axis,
|
|
283
402
|
)
|
|
284
403
|
for ind, ch in enumerate(child_nodes):
|
|
285
404
|
all_wt[ch] += temp_wt[ind]
|
|
286
|
-
elif model_resource[
|
|
405
|
+
elif model_resource["graph"][start_layer]["class"] == "Add":
|
|
287
406
|
temp_wt = UP.calculate_wt_add(
|
|
288
407
|
all_wt[start_layer], [all_out[ch] for ch in child_nodes]
|
|
289
408
|
)
|
|
290
409
|
for ind, ch in enumerate(child_nodes):
|
|
291
410
|
all_wt[ch] += temp_wt[ind]
|
|
292
|
-
elif model_resource[
|
|
293
|
-
|
|
294
|
-
l1 = model_resource[0][start_layer]
|
|
411
|
+
elif model_resource["graph"][start_layer]["class"] == "LSTM":
|
|
412
|
+
l1 = model_resource["layers"][start_layer]
|
|
295
413
|
return_sequence = l1.return_sequences
|
|
296
414
|
units = l1.units
|
|
297
415
|
num_of_cells = l1.input_shape[1]
|
|
@@ -312,199 +430,307 @@ class Backtrace(object):
|
|
|
312
430
|
all_wt[start_layer], lstm_obj_f.compute_log
|
|
313
431
|
)
|
|
314
432
|
all_wt[child_nodes[0]] += temp_wt
|
|
315
|
-
|
|
316
|
-
elif model_resource[1][start_layer]["class"] == "Embedding":
|
|
317
|
-
print('embedding')
|
|
433
|
+
elif model_resource["graph"][start_layer]["class"] == "Embedding":
|
|
318
434
|
temp_wt = all_wt[start_layer]
|
|
319
435
|
temp_wt = np.mean(temp_wt,axis=1)
|
|
320
|
-
|
|
321
436
|
all_wt[child_nodes[0]] = all_wt[child_nodes[0]] + temp_wt
|
|
437
|
+
elif model_resource["graph"][start_layer]["class"] == "TextVectorization":
|
|
438
|
+
temp_wt = all_wt[start_layer]
|
|
439
|
+
all_wt[child_nodes[0]] = all_wt[child_nodes[0]] + temp_wt.sum()
|
|
440
|
+
elif model_resource["graph"][start_layer]["class"] == "Self_Attention":
|
|
441
|
+
weights = all_wts[start_layer]
|
|
442
|
+
self_attention_weights = HP.rename_attention_keys(weights)
|
|
443
|
+
temp_wt = UP.calculate_wt_self_attention(
|
|
444
|
+
all_wt[start_layer],
|
|
445
|
+
all_out[child_nodes[0]][0],
|
|
446
|
+
self_attention_weights,
|
|
447
|
+
)
|
|
448
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
449
|
+
elif model_resource["graph"][start_layer]["class"] == 'Residual':
|
|
450
|
+
temp_wt = UP.calculate_wt_add(
|
|
451
|
+
all_wt[start_layer],
|
|
452
|
+
[all_out[ch] for ch in child_nodes],
|
|
453
|
+
)
|
|
454
|
+
for ind, ch in enumerate(child_nodes):
|
|
455
|
+
all_wt[ch] += temp_wt[ind]
|
|
456
|
+
elif model_resource["graph"][start_layer]["class"] == 'Feed_Forward':
|
|
457
|
+
weights = all_wts[start_layer]
|
|
458
|
+
feed_forward_weights = HP.rename_feed_forward_keys(weights)
|
|
459
|
+
temp_wt = UP.calculate_wt_feed_forward(
|
|
460
|
+
all_wt[start_layer],
|
|
461
|
+
all_out[child_nodes[0]][0],
|
|
462
|
+
feed_forward_weights
|
|
463
|
+
)
|
|
464
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
465
|
+
elif model_resource["graph"][start_layer]["class"] == "Pooler":
|
|
466
|
+
weights = all_wts[start_layer]
|
|
467
|
+
pooler_weights = HP.rename_pooler_keys(weights)
|
|
468
|
+
temp_wt = UP.calculate_wt_pooler(
|
|
469
|
+
all_wt[start_layer],
|
|
470
|
+
all_out[child_nodes[0]][0],
|
|
471
|
+
pooler_weights
|
|
472
|
+
)
|
|
473
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
474
|
+
elif model_resource["graph"][start_layer]["class"] == "Classifier":
|
|
475
|
+
weights = all_wts[start_layer]
|
|
476
|
+
classifier_weights = HP.rename_classifier_keys(weights)
|
|
477
|
+
temp_wt = UP.calculate_wt_classifier(
|
|
478
|
+
all_wt[start_layer],
|
|
479
|
+
all_out[child_nodes[0]][0],
|
|
480
|
+
classifier_weights
|
|
481
|
+
)
|
|
482
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
483
|
+
elif model_resource["graph"][start_layer]["class"] == "LM_Head":
|
|
484
|
+
weights = all_wts[start_layer]
|
|
485
|
+
lm_head_weights = HP.rename_decoder_lm_head(weights)
|
|
322
486
|
|
|
487
|
+
temp_wt = UP.calculate_wt_lm_head(
|
|
488
|
+
all_wt[start_layer],
|
|
489
|
+
all_out[child_nodes[0]][0], #.detach().numpy(),
|
|
490
|
+
lm_head_weights
|
|
491
|
+
)
|
|
492
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
493
|
+
elif model_resource["graph"][start_layer]["class"] == 'Layer_Norm':
|
|
494
|
+
temp_wt = all_wt[start_layer]
|
|
495
|
+
child_shape = all_wt[child_nodes[0]].shape
|
|
496
|
+
# Ensure temp_wt has the same shape as all_wt[child_nodes[0]]
|
|
497
|
+
if all_wt[child_nodes[0]].shape != temp_wt.shape:
|
|
498
|
+
temp_wt = np.squeeze(temp_wt, axis=0) if len(temp_wt.shape) == 3 else temp_wt
|
|
499
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
500
|
+
elif model_resource["graph"][start_layer]["class"] == 'Cross_Attention':
|
|
501
|
+
weights = all_wts[start_layer]
|
|
502
|
+
cross_attention_weights = HP.rename_cross_attention_keys(weights)
|
|
503
|
+
temp_wt = UP.calculate_wt_cross_attention(
|
|
504
|
+
all_wt[start_layer],
|
|
505
|
+
[all_out[ch][0] for ch in child_nodes],
|
|
506
|
+
cross_attention_weights,
|
|
507
|
+
)
|
|
508
|
+
for ind, ch in enumerate(child_nodes):
|
|
509
|
+
all_wt[ch] += temp_wt[ind]
|
|
323
510
|
else:
|
|
324
|
-
print('else')
|
|
325
511
|
temp_wt = all_wt[start_layer]
|
|
326
|
-
all_wt[child_nodes[0]] += temp_wt
|
|
327
|
-
|
|
328
|
-
if max_unit > 0 and scaler == 0:
|
|
329
|
-
temp_dict = {}
|
|
330
|
-
for k in all_wt.keys():
|
|
331
|
-
temp_dict[k] = UC.weight_normalize(all_wt[k], max_val=max_unit)
|
|
332
|
-
all_wt = temp_dict
|
|
333
|
-
elif scaler > 0:
|
|
512
|
+
all_wt[child_nodes[0]] += temp_wt
|
|
513
|
+
if max_unit>0:
|
|
334
514
|
temp_dict = {}
|
|
335
515
|
for k in all_wt.keys():
|
|
336
|
-
temp_dict[k] = UC.
|
|
516
|
+
temp_dict[k] = UC.weight_normalize(all_wt[k],max_val=max_unit)
|
|
337
517
|
all_wt = temp_dict
|
|
338
518
|
return all_wt
|
|
339
519
|
|
|
340
|
-
def contrast_eval(self, all_out,
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
#returns a dictionary that maps layer names to dictionaries containing positive and negative relevance values.
|
|
520
|
+
def contrast_eval(self, all_out ,
|
|
521
|
+
multiplier=100.0, scaler=None,
|
|
522
|
+
thresholding=0.5,task="binary-classification"):
|
|
344
523
|
model_resource = self.model_resource
|
|
345
|
-
print(model_resource)
|
|
346
524
|
activation_dict = self.activation_dict
|
|
347
525
|
inputcheck = False
|
|
348
|
-
out_layer = model_resource[
|
|
526
|
+
out_layer = model_resource["outputs"][0]
|
|
349
527
|
all_wt_pos = {}
|
|
350
528
|
all_wt_neg = {}
|
|
351
|
-
start_wt_pos,
|
|
352
|
-
all_wt_pos[out_layer] = start_wt_pos
|
|
353
|
-
all_wt_neg[out_layer] = start_wt_neg
|
|
354
|
-
layer_stack =
|
|
355
|
-
|
|
356
|
-
start_layer
|
|
357
|
-
|
|
358
|
-
child_nodes = model_resource[1][start_layer]["child"]
|
|
529
|
+
start_wt_pos,start_wt_neg = UC.calculate_start_wt(all_out[out_layer], scaler,thresholding,task)
|
|
530
|
+
all_wt_pos[out_layer] = start_wt_pos*multiplier
|
|
531
|
+
all_wt_neg[out_layer] = start_wt_neg*multiplier
|
|
532
|
+
layer_stack = self.layer_stack
|
|
533
|
+
for start_layer in tqdm(layer_stack):
|
|
534
|
+
if model_resource["graph"][start_layer]["child"]:
|
|
535
|
+
child_nodes = model_resource["graph"][start_layer]["child"]
|
|
359
536
|
for ch in child_nodes:
|
|
360
537
|
if ch not in all_wt_pos:
|
|
361
538
|
all_wt_pos[ch] = np.zeros_like(all_out[ch][0])
|
|
362
539
|
all_wt_neg[ch] = np.zeros_like(all_out[ch][0])
|
|
363
|
-
if model_resource[
|
|
364
|
-
|
|
365
|
-
l1 = model_resource[0][start_layer]
|
|
540
|
+
if model_resource["graph"][start_layer]["class"] == 'Dense':
|
|
541
|
+
l1 = model_resource["layers"][start_layer]
|
|
366
542
|
w1 = l1.weights[0]
|
|
367
543
|
b1 = l1.weights[1]
|
|
368
|
-
temp_wt_pos,
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
b1,
|
|
374
|
-
activation_dict[model_resource[1][start_layer]["name"]],
|
|
375
|
-
)
|
|
544
|
+
temp_wt_pos,temp_wt_neg = UC.calculate_wt_fc(all_wt_pos[start_layer],
|
|
545
|
+
all_wt_neg[start_layer],
|
|
546
|
+
all_out[child_nodes[0]][0],
|
|
547
|
+
w1,b1,
|
|
548
|
+
activation_dict[model_resource["graph"][start_layer]['name']])
|
|
376
549
|
all_wt_pos[child_nodes[0]] += temp_wt_pos
|
|
377
550
|
all_wt_neg[child_nodes[0]] += temp_wt_neg
|
|
378
|
-
elif model_resource[
|
|
379
|
-
l1 = model_resource[
|
|
551
|
+
elif model_resource["graph"][start_layer]["class"] == 'Conv2D':
|
|
552
|
+
l1 = model_resource["layers"][start_layer]
|
|
380
553
|
w1 = l1.weights[0]
|
|
381
554
|
b1 = l1.weights[1]
|
|
382
|
-
|
|
555
|
+
pad1 = l1.padding
|
|
556
|
+
strides1 = l1.strides
|
|
557
|
+
temp_wt_pos,temp_wt_neg = UC.calculate_wt_conv(all_wt_pos[start_layer],
|
|
558
|
+
all_wt_neg[start_layer],
|
|
559
|
+
all_out[child_nodes[0]][0],
|
|
560
|
+
w1,b1, pad1, strides1,
|
|
561
|
+
activation_dict[model_resource["graph"][start_layer]['name']])
|
|
562
|
+
all_wt_pos[child_nodes[0]] += temp_wt_pos
|
|
563
|
+
all_wt_neg[child_nodes[0]] += temp_wt_neg
|
|
564
|
+
elif model_resource["graph"][start_layer]["class"] == "Conv2DTranspose":
|
|
565
|
+
l1 = model_resource["layers"][start_layer]
|
|
566
|
+
w1 = l1.weights[0]
|
|
567
|
+
b1 = l1.weights[1]
|
|
568
|
+
pad1 = l1.padding
|
|
569
|
+
strides1 = l1.strides
|
|
570
|
+
temp_wt_pos,temp_wt_neg = UC.calculate_wt_conv2d_transpose(
|
|
383
571
|
all_wt_pos[start_layer],
|
|
384
572
|
all_wt_neg[start_layer],
|
|
385
573
|
all_out[child_nodes[0]][0],
|
|
386
574
|
w1,
|
|
387
575
|
b1,
|
|
388
|
-
|
|
576
|
+
pad1,
|
|
577
|
+
strides1,
|
|
578
|
+
activation_dict[model_resource["graph"][start_layer]["name"]],
|
|
389
579
|
)
|
|
390
580
|
all_wt_pos[child_nodes[0]] += temp_wt_pos
|
|
391
581
|
all_wt_neg[child_nodes[0]] += temp_wt_neg
|
|
392
|
-
elif model_resource[
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
582
|
+
elif model_resource["graph"][start_layer]["class"] == 'Conv1D':
|
|
583
|
+
l1 = model_resource["layers"][start_layer]
|
|
584
|
+
w1 = l1.weights[0]
|
|
585
|
+
b1 = l1.weights[1]
|
|
586
|
+
pad1 = l1.padding
|
|
587
|
+
strides1 = l1.strides[0]
|
|
588
|
+
temp_wt_pos,temp_wt_neg = UC.calculate_wt_conv_1d(all_wt_pos[start_layer],
|
|
589
|
+
all_wt_neg[start_layer],
|
|
590
|
+
all_out[child_nodes[0]][0],
|
|
591
|
+
w1,b1, pad1, strides1,
|
|
592
|
+
activation_dict[model_resource["graph"][start_layer]['name']])
|
|
399
593
|
all_wt_pos[child_nodes[0]] += temp_wt_pos
|
|
400
594
|
all_wt_neg[child_nodes[0]] += temp_wt_neg
|
|
401
|
-
elif
|
|
402
|
-
model_resource[
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
595
|
+
elif model_resource["graph"][start_layer]["class"] == "Conv1DTranspose":
|
|
596
|
+
l1 = model_resource["layers"][start_layer]
|
|
597
|
+
w1 = l1.weights[0]
|
|
598
|
+
b1 = l1.weights[1]
|
|
599
|
+
pad1 = l1.padding
|
|
600
|
+
strides1 = l1.strides[0]
|
|
601
|
+
temp_wt_pos,temp_wt_neg = UC.calculate_wt_conv1d_transpose(all_wt_pos[start_layer],
|
|
602
|
+
all_wt_neg[start_layer],
|
|
603
|
+
all_out[child_nodes[0]][0],
|
|
604
|
+
w1,b1, pad1, strides1,
|
|
605
|
+
activation_dict[model_resource["graph"][start_layer]['name']])
|
|
409
606
|
all_wt_pos[child_nodes[0]] += temp_wt_pos
|
|
410
607
|
all_wt_neg[child_nodes[0]] += temp_wt_neg
|
|
411
|
-
elif model_resource[
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
608
|
+
elif model_resource["graph"][start_layer]["class"] == 'Reshape':
|
|
609
|
+
temp_wt_pos = UC.calculate_wt_rshp(all_wt_pos[start_layer],
|
|
610
|
+
all_out[child_nodes[0]][0])
|
|
611
|
+
temp_wt_neg = UC.calculate_wt_rshp(all_wt_neg[start_layer],
|
|
612
|
+
all_out[child_nodes[0]][0])
|
|
613
|
+
all_wt_pos[child_nodes[0]] += temp_wt_pos
|
|
614
|
+
all_wt_neg[child_nodes[0]] += temp_wt_neg
|
|
615
|
+
elif model_resource["graph"][start_layer]["class"] == 'GlobalAveragePooling2D':
|
|
616
|
+
temp_wt_pos,temp_wt_neg = UC.calculate_wt_gavgpool(all_wt_pos[start_layer],
|
|
617
|
+
all_wt_neg[start_layer],
|
|
618
|
+
all_out[child_nodes[0]][0])
|
|
619
|
+
all_wt_pos[child_nodes[0]] += temp_wt_pos
|
|
620
|
+
all_wt_neg[child_nodes[0]] += temp_wt_neg
|
|
621
|
+
elif model_resource["graph"][start_layer]["class"] == 'GlobalAveragePooling1D':
|
|
622
|
+
temp_wt_pos,temp_wt_neg = UC.calculate_wt_gavgpool_1d(all_wt_pos[start_layer],
|
|
623
|
+
all_wt_neg[start_layer],
|
|
624
|
+
all_out[child_nodes[0]][0])
|
|
625
|
+
all_wt_pos[child_nodes[0]] += temp_wt_pos
|
|
626
|
+
all_wt_neg[child_nodes[0]] += temp_wt_neg
|
|
627
|
+
elif model_resource["graph"][start_layer]["class"] == 'Flatten':
|
|
628
|
+
temp_wt = UC.calculate_wt_rshp(all_wt_pos[start_layer],
|
|
629
|
+
all_out[child_nodes[0]][0])
|
|
415
630
|
all_wt_pos[child_nodes[0]] += temp_wt
|
|
416
|
-
temp_wt = UC.calculate_wt_rshp(
|
|
417
|
-
|
|
418
|
-
)
|
|
631
|
+
temp_wt = UC.calculate_wt_rshp(all_wt_neg[start_layer],
|
|
632
|
+
all_out[child_nodes[0]][0])
|
|
419
633
|
all_wt_neg[child_nodes[0]] += temp_wt
|
|
420
|
-
elif
|
|
421
|
-
model_resource[
|
|
422
|
-
|
|
423
|
-
temp_wt_pos,
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
)
|
|
634
|
+
elif model_resource["graph"][start_layer]["class"] == 'ZeroPadding2D':
|
|
635
|
+
l1 = model_resource["layers"][start_layer]
|
|
636
|
+
pad1 = l1.padding
|
|
637
|
+
temp_wt_pos,temp_wt_neg = UC.calculate_wt_zero_pad(all_wt_pos[start_layer],
|
|
638
|
+
all_wt_neg[start_layer],
|
|
639
|
+
all_out[child_nodes[0]][0],
|
|
640
|
+
pad1)
|
|
428
641
|
all_wt_pos[child_nodes[0]] += temp_wt_pos
|
|
429
642
|
all_wt_neg[child_nodes[0]] += temp_wt_neg
|
|
430
|
-
elif model_resource[
|
|
431
|
-
l1 = model_resource[
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
643
|
+
elif model_resource["graph"][start_layer]["class"] == 'MaxPooling2D':
|
|
644
|
+
l1 = model_resource["layers"][start_layer]
|
|
645
|
+
pad1 = l1.padding
|
|
646
|
+
strides1 = l1.strides
|
|
647
|
+
temp_wt = UC.calculate_wt_maxpool(all_wt_pos[start_layer],
|
|
648
|
+
all_out[child_nodes[0]][0],
|
|
649
|
+
l1.pool_size, pad1, strides1)
|
|
437
650
|
all_wt_pos[child_nodes[0]] += temp_wt
|
|
438
|
-
temp_wt = UC.calculate_wt_maxpool(
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
l1.pool_size,
|
|
442
|
-
)
|
|
651
|
+
temp_wt = UC.calculate_wt_maxpool(all_wt_neg[start_layer],
|
|
652
|
+
all_out[child_nodes[0]][0],
|
|
653
|
+
l1.pool_size, pad1, strides1)
|
|
443
654
|
all_wt_neg[child_nodes[0]] += temp_wt
|
|
444
|
-
elif model_resource[
|
|
445
|
-
l1 = model_resource[
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
655
|
+
elif model_resource["graph"][start_layer]["class"] == 'MaxPooling1D':
|
|
656
|
+
l1 = model_resource["layers"][start_layer]
|
|
657
|
+
pad1 = l1.padding
|
|
658
|
+
strides1 = l1.strides
|
|
659
|
+
temp_wt = UC.calculate_wt_maxpool_1d(all_wt_pos[start_layer],
|
|
660
|
+
all_out[child_nodes[0]][0],
|
|
661
|
+
l1.pool_size, pad1, strides1)
|
|
662
|
+
all_wt_pos[child_nodes[0]] += temp_wt
|
|
663
|
+
temp_wt = UC.calculate_wt_maxpool_1d(all_wt_neg[start_layer],
|
|
664
|
+
all_out[child_nodes[0]][0],
|
|
665
|
+
l1.pool_size, pad1, strides1)
|
|
666
|
+
all_wt_neg[child_nodes[0]] += temp_wt
|
|
667
|
+
elif model_resource["graph"][start_layer]["class"] == 'GlobalMaxPooling2D':
|
|
668
|
+
temp_wt = UC.calculate_wt_gmaxpool_2d(all_wt_pos[start_layer],
|
|
669
|
+
all_out[child_nodes[0]][0])
|
|
670
|
+
all_wt_pos[child_nodes[0]] += temp_wt
|
|
671
|
+
temp_wt = UC.calculate_wt_gmaxpool_2d(all_wt_neg[start_layer],
|
|
672
|
+
all_out[child_nodes[0]][0])
|
|
673
|
+
all_wt_neg[child_nodes[0]] += temp_wt
|
|
674
|
+
elif model_resource["graph"][start_layer]["class"] == 'GlobalMaxPooling1D':
|
|
675
|
+
temp_wt = UC.calculate_wt_gmaxpool_1d(all_wt_pos[start_layer],
|
|
676
|
+
all_out[child_nodes[0]][0])
|
|
677
|
+
all_wt_pos[child_nodes[0]] += temp_wt
|
|
678
|
+
temp_wt = UC.calculate_wt_gmaxpool_1d(all_wt_neg[start_layer],
|
|
679
|
+
all_out[child_nodes[0]][0])
|
|
680
|
+
all_wt_neg[child_nodes[0]] += temp_wt
|
|
681
|
+
elif model_resource["graph"][start_layer]["class"] == 'AveragePooling2D':
|
|
682
|
+
l1 = model_resource["layers"][start_layer]
|
|
683
|
+
pad1 = l1.padding
|
|
684
|
+
strides1 = l1.strides
|
|
685
|
+
temp_wt_pos,temp_wt_neg = UC.calculate_wt_avgpool(all_wt_pos[start_layer],
|
|
686
|
+
all_wt_neg[start_layer],
|
|
687
|
+
all_out[child_nodes[0]][0],
|
|
688
|
+
l1.pool_size, pad1, strides1)
|
|
452
689
|
all_wt_pos[child_nodes[0]] += temp_wt_pos
|
|
453
690
|
all_wt_neg[child_nodes[0]] += temp_wt_neg
|
|
454
|
-
elif model_resource[
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
691
|
+
elif model_resource["graph"][start_layer]["class"] == 'AveragePooling1D':
|
|
692
|
+
l1 = model_resource["layers"][start_layer]
|
|
693
|
+
pad1 = l1.padding
|
|
694
|
+
strides1 = l1.strides
|
|
695
|
+
temp_wt_pos,temp_wt_neg = UC.calculate_wt_avgpool_1d(all_wt_pos[start_layer],
|
|
696
|
+
all_wt_neg[start_layer],
|
|
697
|
+
all_out[child_nodes[0]][0],
|
|
698
|
+
l1.pool_size, pad1, strides1)
|
|
699
|
+
all_wt_pos[child_nodes[0]] += temp_wt_pos
|
|
700
|
+
all_wt_neg[child_nodes[0]] += temp_wt_neg
|
|
701
|
+
elif model_resource["graph"][start_layer]["class"] == "Concatenate":
|
|
702
|
+
temp_wt = UC.calculate_wt_concat(all_wt_pos[start_layer],
|
|
703
|
+
[all_out[ch] for ch in child_nodes],
|
|
704
|
+
model_resource["layers"][start_layer].axis)
|
|
460
705
|
for ind, ch in enumerate(child_nodes):
|
|
461
|
-
all_wt_pos[ch]
|
|
462
|
-
temp_wt = UC.calculate_wt_concat(
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
model_resource[0][start_layer].axis,
|
|
466
|
-
)
|
|
706
|
+
all_wt_pos[ch]+=temp_wt[ind]
|
|
707
|
+
temp_wt = UC.calculate_wt_concat(all_wt_neg[start_layer],
|
|
708
|
+
[all_out[ch] for ch in child_nodes],
|
|
709
|
+
model_resource["layers"][start_layer].axis)
|
|
467
710
|
for ind, ch in enumerate(child_nodes):
|
|
468
|
-
all_wt_neg[ch]
|
|
711
|
+
all_wt_neg[ch]+=temp_wt[ind]
|
|
469
712
|
|
|
470
|
-
elif model_resource[
|
|
471
|
-
temp_wt = UC.calculate_wt_add(
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
[all_out[ch] for ch in child_nodes],
|
|
475
|
-
)
|
|
713
|
+
elif model_resource["graph"][start_layer]["class"] == "Add":
|
|
714
|
+
temp_wt = UC.calculate_wt_add(all_wt_pos[start_layer],
|
|
715
|
+
all_wt_neg[start_layer],
|
|
716
|
+
[all_out[ch] for ch in child_nodes])
|
|
476
717
|
for ind, ch in enumerate(child_nodes):
|
|
477
|
-
all_wt_pos[ch]
|
|
478
|
-
all_wt_neg[ch]
|
|
479
|
-
elif model_resource[
|
|
480
|
-
|
|
481
|
-
l1 = model_resource[0][start_layer]
|
|
718
|
+
all_wt_pos[ch]+=temp_wt[ind][0]
|
|
719
|
+
all_wt_neg[ch]+=temp_wt[ind][1]
|
|
720
|
+
elif model_resource["graph"][start_layer]["class"] == "LSTM":
|
|
721
|
+
l1 = model_resource["layers"][start_layer]
|
|
482
722
|
return_sequence = l1.return_sequences
|
|
483
723
|
units = l1.units
|
|
484
724
|
num_of_cells = l1.input_shape[1]
|
|
485
|
-
lstm_obj_f = UC.LSTM_forward(
|
|
486
|
-
|
|
487
|
-
)
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
[i.numpy() for i in l1.weights],
|
|
492
|
-
return_sequence,
|
|
493
|
-
False,
|
|
494
|
-
)
|
|
495
|
-
temp_out_f = lstm_obj_f.calculate_lstm_wt(
|
|
496
|
-
all_out[child_nodes[0]][0]
|
|
497
|
-
)
|
|
498
|
-
temp_wt_pos, temp_wt_neg = lstm_obj_b.calculate_lstm_wt(
|
|
499
|
-
all_wt_pos[start_layer],
|
|
500
|
-
all_wt_neg[start_layer],
|
|
501
|
-
lstm_obj_f.compute_log,
|
|
502
|
-
)
|
|
725
|
+
lstm_obj_f = UC.LSTM_forward(num_of_cells, units, l1.weights, return_sequence, False)
|
|
726
|
+
lstm_obj_b = UC.LSTM_backtrace(num_of_cells, units, [i.numpy() for i in l1.weights], return_sequence, False)
|
|
727
|
+
temp_out_f = lstm_obj_f.calculate_lstm_wt(all_out[child_nodes[0]][0])
|
|
728
|
+
temp_wt_pos,temp_wt_neg = lstm_obj_b.calculate_lstm_wt(all_wt_pos[start_layer],
|
|
729
|
+
all_wt_neg[start_layer],
|
|
730
|
+
lstm_obj_f.compute_log)
|
|
503
731
|
all_wt_pos[child_nodes[0]] = temp_wt_pos
|
|
504
732
|
all_wt_neg[child_nodes[0]] = temp_wt_neg
|
|
505
|
-
|
|
506
|
-
elif model_resource[1][start_layer]["class"] == "Embedding":
|
|
507
|
-
print('embedding layer')
|
|
733
|
+
elif model_resource["graph"][start_layer]["class"] == "Embedding":
|
|
508
734
|
temp_wt_pos = all_wt_pos[start_layer]
|
|
509
735
|
temp_wt_neg = all_wt_neg[start_layer]
|
|
510
736
|
|
|
@@ -513,15 +739,16 @@ class Backtrace(object):
|
|
|
513
739
|
|
|
514
740
|
all_wt_pos[child_nodes[0]] = all_wt_pos[child_nodes[0]] + temp_wt_pos
|
|
515
741
|
all_wt_neg[child_nodes[0]] = all_wt_neg[child_nodes[0]] + temp_wt_neg
|
|
742
|
+
elif model_resource["graph"][start_layer]["class"] == "TextVectorization":
|
|
743
|
+
temp_wt_pos = all_wt_pos[start_layer]
|
|
744
|
+
temp_wt_neg = all_wt_neg[start_layer]
|
|
516
745
|
|
|
517
|
-
|
|
746
|
+
all_wt_pos[child_nodes[0]] = all_wt_pos[child_nodes[0]] + temp_wt_pos.sum()
|
|
747
|
+
all_wt_neg[child_nodes[0]] = all_wt_neg[child_nodes[0]] + temp_wt_neg.sum()
|
|
518
748
|
else:
|
|
519
|
-
print('else')
|
|
520
749
|
temp_wt_pos = all_wt_pos[start_layer]
|
|
521
750
|
temp_wt_neg = all_wt_neg[start_layer]
|
|
522
751
|
all_wt_pos[child_nodes[0]] += temp_wt_pos
|
|
523
752
|
all_wt_neg[child_nodes[0]] += temp_wt_neg
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
layer_stack.append(ch)
|
|
527
|
-
return all_wt_pos, all_wt_neg
|
|
753
|
+
|
|
754
|
+
return all_wt_pos,all_wt_neg
|