dl-backtrace 0.0.16.dev4__py3-none-any.whl → 0.0.17__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.

Files changed (25) hide show
  1. dl_backtrace/old_backtrace/__init__.py +1 -0
  2. dl_backtrace/old_backtrace/pytorch_backtrace/__init__.py +1 -0
  3. dl_backtrace/old_backtrace/pytorch_backtrace/backtrace/__init__.py +4 -0
  4. dl_backtrace/old_backtrace/pytorch_backtrace/backtrace/backtrace.py +639 -0
  5. dl_backtrace/old_backtrace/pytorch_backtrace/backtrace/config.py +41 -0
  6. dl_backtrace/old_backtrace/pytorch_backtrace/backtrace/utils/__init__.py +2 -0
  7. dl_backtrace/old_backtrace/pytorch_backtrace/backtrace/utils/contrast.py +840 -0
  8. dl_backtrace/old_backtrace/pytorch_backtrace/backtrace/utils/prop.py +746 -0
  9. dl_backtrace/old_backtrace/tf_backtrace/__init__.py +1 -0
  10. dl_backtrace/old_backtrace/tf_backtrace/backtrace/__init__.py +4 -0
  11. dl_backtrace/old_backtrace/tf_backtrace/backtrace/backtrace.py +527 -0
  12. dl_backtrace/old_backtrace/tf_backtrace/backtrace/config.py +41 -0
  13. dl_backtrace/old_backtrace/tf_backtrace/backtrace/utils/__init__.py +2 -0
  14. dl_backtrace/old_backtrace/tf_backtrace/backtrace/utils/contrast.py +834 -0
  15. dl_backtrace/old_backtrace/tf_backtrace/backtrace/utils/prop.py +725 -0
  16. dl_backtrace/tf_backtrace/backtrace/backtrace.py +5 -3
  17. dl_backtrace/tf_backtrace/backtrace/utils/utils_prop.py +53 -0
  18. dl_backtrace/version.py +2 -2
  19. dl_backtrace-0.0.17.dist-info/METADATA +164 -0
  20. dl_backtrace-0.0.17.dist-info/RECORD +44 -0
  21. dl_backtrace-0.0.16.dev4.dist-info/METADATA +0 -102
  22. dl_backtrace-0.0.16.dev4.dist-info/RECORD +0 -29
  23. {dl_backtrace-0.0.16.dev4.dist-info → dl_backtrace-0.0.17.dist-info}/LICENSE +0 -0
  24. {dl_backtrace-0.0.16.dev4.dist-info → dl_backtrace-0.0.17.dist-info}/WHEEL +0 -0
  25. {dl_backtrace-0.0.16.dev4.dist-info → dl_backtrace-0.0.17.dist-info}/top_level.txt +0 -0
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+ from .backtrace import *
@@ -0,0 +1,4 @@
1
+ from .backtrace import Backtrace
2
+
3
+ from .utils import *
4
+ from .config import *
@@ -0,0 +1,639 @@
1
+ import numpy as np
2
+ import torch
3
+ import torch.nn as nn
4
+ from dl_backtrace.pytorch_backtrace.backtrace.utils import contrast as UC
5
+ from dl_backtrace.pytorch_backtrace.backtrace.utils import prop as UP
6
+ from dl_backtrace.pytorch_backtrace.backtrace.config import activation_master
7
+
8
+ class Backtrace(object):
9
+ """
10
+ This is the constructor method for the Backtrace class. It initializes an instance of the class.
11
+ It takes two optional parameters: model (a neural network model) and activation_dict (a dictionary that maps layer names to activation functions).
12
+ """
13
+
14
+ def __init__(self, model=None, activation_dict={}):
15
+
16
+ # create a tree-like structure that represents the layers of the neural network model
17
+ self.create_tree(model)
18
+
19
+ # create a new model (an instance of tf.keras.Model) that produces the output of each layer in the neural network.
20
+ self.create_model_output(model)
21
+
22
+ # create a new model (an instance of tf.keras.Model) that produces the output of each layer in the neural network.
23
+ self.create_every_model_output(model)
24
+
25
+ # create a layer stack that defines the order in which layers should be processed during backpropagation.
26
+ self.create_layer_stack()
27
+
28
+ # checks if the model is sequential or not. If it's sequential, it adds the input layer to the layer stack.
29
+ # identity
30
+
31
+ inp_name = 'identity'
32
+ self.layer_stack.append(inp_name)
33
+ self.model_resource[1][inp_name] = {}
34
+ self.model_resource[1][inp_name]["name"] = inp_name
35
+ self.model_resource[1][inp_name]["type"] = "input"
36
+ self.model_resource[1][inp_name]["parent"] = []
37
+ self.model_resource[1][inp_name]["child"] = None
38
+ self.model_resource[3].append(inp_name)
39
+ self.sequential = True
40
+ try:
41
+
42
+ # calls the build_activation_dict method to build a dictionary that maps layer names to activation functions.
43
+ # If that fails, it creates a temporary dictionary with default activation functions.
44
+ if len(activation_dict) == 0:
45
+ self.build_activation_dict(model)
46
+ else:
47
+ self.activation_dict = activation_dict
48
+
49
+ except Exception as e:
50
+ print(e)
51
+ temp_dict = {}
52
+ for l in model.layers:
53
+ temp_dict[l.name] = activation_master["None"]
54
+ self.activation_dict = temp_dict
55
+
56
+ def build_activation_dict(self, model):
57
+ model_resource = self.model_resource
58
+ layer_list = list(model_resource[0].keys())
59
+ activation_dict = {}
60
+ activation_functions = ['relu', 'sigmoid', 'tanh', 'softmax'] # You can add more activation functions
61
+
62
+ for l in layer_list:
63
+ activation_found = False
64
+
65
+ try: # could be activation for that layer
66
+ for activation in activation_functions:
67
+ if activation in l.split('/')[1]:
68
+ activation_dict[l.split('/')[0]] = activation
69
+ activation_found = True
70
+ except:
71
+ activation_dict[l] = 'None'
72
+
73
+ # activation_master :
74
+ for key, value in activation_dict.items():
75
+ activation_dict[key] = activation_master.get(value)
76
+ self.activation_dict = activation_dict
77
+
78
+ def create_tree(self, model):
79
+ # create new layers same as tf version
80
+ layers = list(model.named_children())
81
+
82
+ activation_functions = ['relu', 'sigmoid', 'tanh', 'softmax']
83
+ layer_sequence = []
84
+
85
+ for i in range(len(layers) - 1):
86
+ current_layer, current_layer_obj = layers[i]
87
+ next_layer, next_layer_obj = layers[i + 1]
88
+ current_layer_name = current_layer
89
+ next_layer_name = next_layer
90
+
91
+ next_layer_type = next_layer_name.lower()
92
+ if any(af in next_layer_type for af in activation_functions):
93
+ layer_sequence.append((f"{current_layer_name}/{next_layer_name}", current_layer_obj))
94
+ i += 1
95
+ else:
96
+ if any(af in current_layer_name for af in activation_functions) is False:
97
+ layer_sequence.append((current_layer_name, current_layer_obj))
98
+
99
+ # creating model_resource variable
100
+ layer_sequence
101
+ ltree = {}
102
+ layer_tree = {}
103
+ inputs = []
104
+ outputs = []
105
+ intermediates = []
106
+
107
+ prev_layer_id = None
108
+
109
+ num_layers = len(layer_sequence)
110
+
111
+ for i, (layer_name, layer) in enumerate(layer_sequence):
112
+ layer_id = layer_name
113
+ ltree[layer_id] = {}
114
+ layer_tree[layer_id] = layer
115
+
116
+ layer_type = layer.__class__.__name__
117
+ ltree[layer_id]["name"] = layer_id.split("/")[0]
118
+ ltree[layer_id]["class"] = layer_type
119
+
120
+ if i < num_layers - 1:
121
+ ltree[layer_id]["type"] = "intermediate"
122
+ intermediates.append(layer_id)
123
+ else:
124
+ ltree[layer_id]["type"] = "output"
125
+ outputs.append(layer_id)
126
+
127
+ if prev_layer_id is not None:
128
+ ltree[layer_id]["child"] = [prev_layer_id]
129
+ ltree[prev_layer_id]["parent"] = [layer_id]
130
+
131
+ prev_layer_id = layer_id
132
+
133
+ # Set child of the last layer as an empty list
134
+ if prev_layer_id is not None:
135
+ ltree[prev_layer_id]["parent"] = []
136
+
137
+ layer_tree.pop('identity')
138
+ ltree.pop('identity')
139
+ self.model_resource = (layer_tree, ltree, outputs, inputs)
140
+
141
+ def create_layer_stack(self):
142
+ model_resource = self.model_resource
143
+ start_layer = model_resource[2][0]
144
+ layer_stack = [start_layer]
145
+ temp_stack = [start_layer]
146
+ while len(layer_stack) < len(model_resource[0]):
147
+ start_layer = temp_stack.pop(0)
148
+ if model_resource[1][start_layer]["child"]:
149
+ child_nodes = model_resource[1][start_layer]["child"]
150
+ for ch in child_nodes:
151
+ node_check = True
152
+ for pa in model_resource[1][ch]["parent"]:
153
+ if pa not in layer_stack:
154
+ node_check = False
155
+ break
156
+ if node_check:
157
+ if ch not in layer_stack:
158
+ layer_stack.append(ch)
159
+ temp_stack.append(ch)
160
+ self.layer_stack = layer_stack
161
+
162
+ def create_every_model_output(self, model):
163
+ class ModelWithEveryOutputs(nn.Module):
164
+ def __init__(self, base_model):
165
+ super(ModelWithEveryOutputs, self).__init__()
166
+ self.base_model = base_model
167
+
168
+ def forward(self, x):
169
+ outputs = []
170
+ for layer_name, layer in self.base_model._modules.items():
171
+ if isinstance(x, tuple):
172
+ if isinstance(layer, nn.LSTM):
173
+ # Assuming you want to take the last LSTM output
174
+ x, _ = layer(x[0]) # Pass the first element of the tuple (assumes one LSTM layer)
175
+ else:
176
+ x = layer(x[0]) # Pass the first element of the tuple
177
+ else:
178
+ x = layer(x)
179
+ outputs.append((layer_name, x))
180
+ return outputs
181
+
182
+ self.every_out_model = ModelWithEveryOutputs(model)
183
+
184
+ def create_model_output(self, model):
185
+ class ModelWithOutputs(nn.Module):
186
+ def __init__(self, base_model):
187
+ super(ModelWithOutputs, self).__init__()
188
+ self.base_model = base_model
189
+
190
+ def forward(self, x):
191
+ outputs = []
192
+ for layer_name, layer in self.base_model._modules.items():
193
+ if isinstance(layer, nn.LSTM):
194
+ lstm_output, _ = layer(x)
195
+ if lstm_output.dim() == 3:
196
+ x = lstm_output[:, -1, :] # Take the output of the last time step
197
+ else:
198
+ x = lstm_output
199
+ else:
200
+ x = layer(x)
201
+ outputs.append((layer_name, x))
202
+ return outputs
203
+
204
+ # all_out_model = ModelWithOutputs(model)
205
+ self.all_out_model = ModelWithOutputs(model)
206
+ model.eval()
207
+ model_resource = self.model_resource
208
+ self.layers = [[], []]
209
+ for l in model_resource[0]:
210
+ self.layers[0].append(l)
211
+ self.layers[1].append(model_resource[0][l])
212
+
213
+ def predict_every(self, inputs):
214
+ every_out = self.every_out_model(inputs)
215
+ activation_functions = ['relu', 'sigmoid', 'tanh', 'softmax']
216
+ every_temp_out = {}
217
+
218
+ for i in range(len(every_out)):
219
+
220
+ current_layer, current_layer_obj = every_out[i]
221
+ try:
222
+ next_layer, next_layer_obj = every_out[i + 1]
223
+
224
+ current_layer_name = current_layer
225
+ next_layer_name = next_layer
226
+
227
+ next_layer_type = next_layer_name.lower()
228
+ if any(af in next_layer_type for af in activation_functions):
229
+ if isinstance(next_layer_obj, tuple):
230
+ # Assuming you want the first tensor from the tuple
231
+ next_layer_tensor = next_layer_obj[0]
232
+ else:
233
+ next_layer_tensor = next_layer_obj
234
+
235
+ every_temp_out[
236
+ f"{current_layer_name}/{next_layer_name}"] = next_layer_tensor.detach().numpy().astype(
237
+ np.float32)
238
+ i += 1
239
+
240
+ else:
241
+ if any(af in current_layer_name for af in activation_functions) is False:
242
+ if isinstance(current_layer_obj, tuple):
243
+ # Assuming you want the first tensor from the tuple
244
+ current_layer_tensor = current_layer_obj[0]
245
+ else:
246
+ current_layer_tensor = current_layer_obj
247
+
248
+ every_temp_out[current_layer_name] = current_layer_tensor.detach().numpy().astype(np.float32)
249
+ except:
250
+ if any(af in next_layer_type for af in activation_functions):
251
+ pass
252
+
253
+ else:
254
+ if any(af in current_layer for af in activation_functions) is False:
255
+ if isinstance(current_layer_obj, tuple):
256
+ # Assuming you want the first tensor from the tuple
257
+ current_layer_tensor = current_layer_obj[0]
258
+ else:
259
+ current_layer_tensor = current_layer_obj
260
+
261
+ every_temp_out[current_layer] = current_layer_tensor.detach().cpu().numpy().astype(np.float32)
262
+ return every_temp_out
263
+
264
+ def predict(self, inputs):
265
+ all_out = self.all_out_model(inputs)
266
+ activation_functions = ['relu', 'sigmoid', 'tanh', 'softmax']
267
+ temp_out = {}
268
+
269
+ for i in range(len(all_out)):
270
+
271
+ current_layer, current_layer_obj = all_out[i]
272
+ try:
273
+ next_layer, next_layer_obj = all_out[i + 1]
274
+
275
+ current_layer_name = current_layer
276
+ next_layer_name = next_layer
277
+
278
+ next_layer_type = next_layer_name.lower()
279
+ if any(af in next_layer_type for af in activation_functions):
280
+ if isinstance(next_layer_obj, tuple):
281
+ # Assuming you want the first tensor from the tuple
282
+ next_layer_tensor = next_layer_obj[0]
283
+ else:
284
+ next_layer_tensor = next_layer_obj
285
+
286
+ temp_out[
287
+ f"{current_layer_name}/{next_layer_name}"] = next_layer_tensor.detach().cpu().numpy().astype(
288
+ np.float32)
289
+ i += 1
290
+
291
+ else:
292
+ if any(af in current_layer_name for af in activation_functions) is False:
293
+ if isinstance(current_layer_obj, tuple):
294
+ # Assuming you want the first tensor from the tuple
295
+ current_layer_tensor = current_layer_obj[0]
296
+ else:
297
+ current_layer_tensor = current_layer_obj
298
+
299
+ temp_out[current_layer_name] = current_layer_tensor.detach().numpy().astype(np.float32)
300
+ except:
301
+ if any(af in next_layer_type for af in activation_functions):
302
+ pass
303
+
304
+ else:
305
+ if any(af in current_layer for af in activation_functions) is False:
306
+ if isinstance(current_layer_obj, tuple):
307
+ # Assuming you want the first tensor from the tuple
308
+ current_layer_tensor = current_layer_obj[0]
309
+ else:
310
+ current_layer_tensor = current_layer_obj
311
+
312
+ temp_out[current_layer] = current_layer_tensor.detach().cpu().numpy().astype(np.float32)
313
+
314
+ return temp_out
315
+
316
+ def eval(
317
+ self,
318
+ all_out,
319
+ mode,
320
+ start_wt=[],
321
+ multiplier=100.0,
322
+ scaler=0,
323
+ max_unit=0,
324
+ ):
325
+ # This method is used for evaluating layer-wise relevance based on different modes.
326
+ if mode == "default":
327
+ output = self.proportional_eval(
328
+ all_out=all_out,
329
+ start_wt=start_wt,
330
+ multiplier=multiplier,
331
+ scaler=0,
332
+ max_unit=0,
333
+ )
334
+ return output
335
+ elif mode == "contrast":
336
+ temp_output = self.contrast_eval(all_out=all_out, multiplier=multiplier)
337
+ output = {}
338
+ for k in temp_output[0].keys():
339
+ output[k] = {}
340
+ output[k]["Positive"] = temp_output[0][k]
341
+ output[k]["Negative"] = temp_output[1][k]
342
+ return output
343
+
344
+ def proportional_eval(
345
+ self, all_out, start_wt=[], multiplier=100.0, scaler=0, max_unit=0
346
+ ):
347
+ model_resource = self.model_resource
348
+ activation_dict = self.activation_dict
349
+ inputcheck = False
350
+ out_layer = model_resource[2][0]
351
+ all_wt = {}
352
+ if len(start_wt) == 0:
353
+ start_wt = UP.calculate_start_wt(all_out[out_layer])
354
+ all_wt[out_layer] = start_wt * multiplier
355
+ layer_stack = self.layer_stack
356
+
357
+ for start_layer in layer_stack:
358
+ if model_resource[1][start_layer]["child"]:
359
+ child_nodes = model_resource[1][start_layer]["child"]
360
+ for ch in child_nodes:
361
+ if ch not in all_wt:
362
+ if model_resource[1][start_layer]["class"] == 'LSTM':
363
+ all_wt[ch] = np.zeros_like(every_temp_out[ch][0])
364
+ else:
365
+ all_wt[ch] = np.zeros_like(all_out[ch][0])
366
+
367
+ if model_resource[1][start_layer]["class"] == "Linear":
368
+ l1 = model_resource[0][start_layer]
369
+ w1 = l1.state_dict()['weight']
370
+ b1 = l1.state_dict()['bias']
371
+ temp_wt = UP.calculate_wt_fc(
372
+ all_wt[start_layer],
373
+ all_out[child_nodes[0]][0],
374
+ w1,
375
+ b1,
376
+ activation_dict[model_resource[1][start_layer]["name"]],
377
+ )
378
+ all_wt[child_nodes[0]] += temp_wt
379
+ elif model_resource[1][start_layer]["class"] == "Conv2d":
380
+ l1 = model_resource[0][start_layer]
381
+ w1 = l1.state_dict()['weight']
382
+ b1 = l1.state_dict()['bias']
383
+ temp_wt = UP.calculate_wt_conv(
384
+ all_wt[start_layer],
385
+ all_out[child_nodes[0]][0],
386
+ w1,
387
+ b1,
388
+ activation_dict[model_resource[1][start_layer]["name"]],
389
+ )
390
+ all_wt[child_nodes[0]] += temp_wt.T
391
+ elif model_resource[1][start_layer]["class"] == "Reshape":
392
+ temp_wt = UP.calculate_wt_rshp(
393
+ all_wt[start_layer], all_out[child_nodes[0]][0]
394
+ )
395
+ all_wt[child_nodes[0]] += temp_wt
396
+ elif model_resource[1][start_layer]["class"] == "Flatten":
397
+ temp_wt = UP.calculate_wt_rshp(
398
+ all_wt[start_layer], all_out[child_nodes[0]][0]
399
+ )
400
+ all_wt[child_nodes[0]] += temp_wt
401
+ elif (
402
+ model_resource[1][start_layer]["class"] == "AdaptiveAvgPool2d"
403
+ ):
404
+ temp_wt = UP.calculate_wt_gavgpool(
405
+ all_wt[start_layer], all_out[child_nodes[0]][0]
406
+ )
407
+ all_wt[child_nodes[0]] += temp_wt.T
408
+ elif model_resource[1][start_layer]["class"] == "MaxPool2d":
409
+ l1 = model_resource[0][start_layer]
410
+ temp_wt = UP.calculate_wt_maxpool(
411
+ all_wt[start_layer], all_out[child_nodes[0]][0], (l1.kernel_size, l1.kernel_size)
412
+ )
413
+ all_wt[child_nodes[0]] += temp_wt.T
414
+ elif model_resource[1][start_layer]["class"] == "AvgPool2d":
415
+ l1 = model_resource[0][start_layer]
416
+ temp_wt = UP.calculate_wt_avgpool(
417
+ all_wt[start_layer], all_out[child_nodes[0]][0], (l1.kernel_size, l1.kernel_size)
418
+ )
419
+ all_wt[child_nodes[0]] += temp_wt.T
420
+ elif model_resource[1][start_layer]["class"] == "Concatenate":
421
+ temp_wt = UP.calculate_wt_concat(
422
+ all_wt[start_layer],
423
+ [all_out[ch] for ch in child_nodes],
424
+ model_resource[0][start_layer].axis,
425
+ )
426
+ for ind, ch in enumerate(child_nodes):
427
+ all_wt[ch] += temp_wt[ind]
428
+ elif model_resource[1][start_layer]["class"] == "Add":
429
+ temp_wt = UP.calculate_wt_add(
430
+ all_wt[start_layer], [all_out[ch] for ch in child_nodes]
431
+ )
432
+ for ind, ch in enumerate(child_nodes):
433
+ all_wt[ch] += temp_wt[ind]
434
+ elif model_resource[1][start_layer]["class"] == "LSTM":
435
+ l1 = model_resource[0][start_layer]
436
+ return_sequence = l1.return_sequences
437
+ units = l1.units
438
+ num_of_cells = l1.input_shape[1]
439
+ lstm_obj_f = UP.LSTM_forward(
440
+ num_of_cells, units, l1.weights, return_sequence, False
441
+ )
442
+ lstm_obj_b = UP.LSTM_backtrace(
443
+ num_of_cells,
444
+ units,
445
+ [i.numpy() for i in l1.weights],
446
+ return_sequence,
447
+ False,
448
+ )
449
+ temp_out_f = lstm_obj_f.calculate_lstm_wt(
450
+ every_temp_out[child_nodes[0]][0]
451
+ )
452
+ temp_wt = lstm_obj_b.calculate_lstm_wt(
453
+ all_wt[start_layer], lstm_obj_f.compute_log
454
+ )
455
+ all_wt[child_nodes[0]] += temp_wt
456
+ else:
457
+ temp_wt = all_wt[start_layer]
458
+ all_wt[child_nodes[0]] += temp_wt
459
+ if max_unit > 0 and scaler == 0:
460
+ temp_dict = {}
461
+ for k in all_wt.keys():
462
+ temp_dict[k] = UC.weight_normalize(all_wt[k], max_val=max_unit)
463
+ all_wt = temp_dict
464
+ elif scaler > 0:
465
+ temp_dict = {}
466
+ for k in all_wt.keys():
467
+ temp_dict[k] = UC.weight_scaler(all_wt[k], scaler=scaler)
468
+ all_wt = temp_dict
469
+
470
+ return all_wt
471
+
472
+ def contrast_eval(self, all_out, multiplier=100.0):
473
+ model_resource = self.model_resource
474
+ activation_dict = self.activation_dict
475
+ inputcheck = False
476
+ out_layer = model_resource[2][0]
477
+ all_wt_pos = {}
478
+ all_wt_neg = {}
479
+ start_wt_pos, start_wt_neg = UC.calculate_start_wt(all_out[out_layer])
480
+ all_wt_pos[out_layer] = start_wt_pos * multiplier
481
+ all_wt_neg[out_layer] = start_wt_neg * multiplier
482
+ layer_stack = [out_layer]
483
+
484
+ while len(layer_stack) > 0:
485
+ start_layer = layer_stack.pop(0)
486
+ if model_resource[1][start_layer]["child"]:
487
+ child_nodes = model_resource[1][start_layer]["child"]
488
+ for ch in child_nodes:
489
+ if ch not in all_wt_pos:
490
+ all_wt_pos[ch] = np.zeros_like(all_out[ch][0])
491
+ all_wt_neg[ch] = np.zeros_like(all_out[ch][0])
492
+ if model_resource[1][start_layer]["class"] == "Linear":
493
+ l1 = model_resource[0][start_layer]
494
+ w1 = l1.state_dict()['weight']
495
+ b1 = l1.state_dict()['bias']
496
+ temp_wt_pos, temp_wt_neg = UC.calculate_wt_fc(
497
+ all_wt_pos[start_layer],
498
+ all_wt_neg[start_layer],
499
+ all_out[child_nodes[0]][0],
500
+ w1,
501
+ b1,
502
+ activation_dict[model_resource[1][start_layer]["name"]],
503
+ )
504
+ all_wt_pos[child_nodes[0]] += temp_wt_pos
505
+ all_wt_neg[child_nodes[0]] += temp_wt_neg
506
+ elif model_resource[1][start_layer]["class"] == "Conv2d":
507
+ l1 = model_resource[0][start_layer]
508
+ w1 = l1.state_dict()['weight']
509
+ b1 = l1.state_dict()['bias']
510
+ temp_wt_pos, temp_wt_neg = UC.calculate_wt_conv(
511
+ all_wt_pos[start_layer],
512
+ all_wt_neg[start_layer],
513
+ all_out[child_nodes[0]][0],
514
+ w1,
515
+ b1,
516
+ activation_dict[model_resource[1][start_layer]["name"]],
517
+ )
518
+ all_wt_pos[child_nodes[0]] += temp_wt_pos.T
519
+ all_wt_neg[child_nodes[0]] += temp_wt_neg.T
520
+ elif model_resource[1][start_layer]["class"] == "Reshape":
521
+ temp_wt_pos = UC.calculate_wt_rshp(
522
+ all_wt_pos[start_layer], all_out[child_nodes[0]][0]
523
+ )
524
+ temp_wt_neg = UC.calculate_wt_rshp(
525
+ all_wt_neg[start_layer], all_out[child_nodes[0]][0]
526
+ )
527
+ all_wt_pos[child_nodes[0]] += temp_wt_pos
528
+ all_wt_neg[child_nodes[0]] += temp_wt_neg
529
+ elif (
530
+ model_resource[1][start_layer]["class"] == "AdaptiveAvgPool2d"
531
+ ):
532
+ temp_wt_pos, temp_wt_neg = UC.calculate_wt_gavgpool(
533
+ all_wt_pos[start_layer],
534
+ all_wt_neg[start_layer],
535
+ all_out[child_nodes[0]][0],
536
+ )
537
+ all_wt_pos[child_nodes[0]] += temp_wt_pos.T
538
+ all_wt_neg[child_nodes[0]] += temp_wt_neg.T
539
+ elif model_resource[1][start_layer]["class"] == "Flatten":
540
+ temp_wt = UC.calculate_wt_rshp(
541
+ all_wt_pos[start_layer], all_out[child_nodes[0]][0]
542
+ )
543
+ all_wt_pos[child_nodes[0]] += temp_wt
544
+ temp_wt = UC.calculate_wt_rshp(
545
+ all_wt_neg[start_layer], all_out[child_nodes[0]][0]
546
+ )
547
+ all_wt_neg[child_nodes[0]] += temp_wt
548
+ elif (
549
+ model_resource[1][start_layer]["class"] == "AdaptiveAvgPool2d"
550
+ ):
551
+ temp_wt_pos, temp_wt_neg = UC.calculate_wt_gavgpool(
552
+ all_wt_pos[start_layer],
553
+ all_wt_neg[start_layer],
554
+ all_out[child_nodes[0]][0],
555
+ )
556
+ all_wt_pos[child_nodes[0]] += temp_wt_pos.T
557
+ all_wt_neg[child_nodes[0]] += temp_wt_neg.T
558
+ elif model_resource[1][start_layer]["class"] == "MaxPool2d":
559
+ l1 = model_resource[0][start_layer]
560
+ temp_wt = UC.calculate_wt_maxpool(
561
+ all_wt_pos[start_layer],
562
+ all_out[child_nodes[0]][0],
563
+ (l1.kernel_size, l1.kernel_size),
564
+ )
565
+ all_wt_pos[child_nodes[0]] += temp_wt.T
566
+ temp_wt = UC.calculate_wt_maxpool(
567
+ all_wt_neg[start_layer],
568
+ all_out[child_nodes[0]][0],
569
+ (l1.kernel_size, l1.kernel_size),
570
+ )
571
+ all_wt_neg[child_nodes[0]] += temp_wt.T
572
+ elif model_resource[1][start_layer]["class"] == "AvgPool2d":
573
+ l1 = model_resource[0][start_layer]
574
+ temp_wt_pos, temp_wt_neg = UC.calculate_wt_avgpool(
575
+ all_wt_pos[start_layer],
576
+ all_wt_neg[start_layer],
577
+ all_out[child_nodes[0]][0],
578
+ (l1.kernel_size, l1.kernel_size),
579
+ )
580
+ all_wt_pos[child_nodes[0]] += temp_wt_pos.T
581
+ all_wt_neg[child_nodes[0]] += temp_wt_neg.T
582
+ elif model_resource[1][start_layer]["class"] == "Concatenate":
583
+ temp_wt = UC.calculate_wt_concat(
584
+ all_wt_pos[start_layer],
585
+ [all_out[ch] for ch in child_nodes],
586
+ model_resource[0][start_layer].axis,
587
+ )
588
+ for ind, ch in enumerate(child_nodes):
589
+ all_wt_pos[ch] += temp_wt[ind]
590
+ temp_wt = UC.calculate_wt_concat(
591
+ all_wt_neg[start_layer],
592
+ [all_out[ch] for ch in child_nodes],
593
+ model_resource[0][start_layer].axis,
594
+ )
595
+ for ind, ch in enumerate(child_nodes):
596
+ all_wt_neg[ch] += temp_wt[ind]
597
+ elif model_resource[1][start_layer]["class"] == "Add":
598
+ temp_wt = UC.calculate_wt_add(
599
+ all_wt_pos[start_layer],
600
+ all_wt_neg[start_layer],
601
+ [all_out[ch] for ch in child_nodes],
602
+ )
603
+ for ind, ch in enumerate(child_nodes):
604
+ all_wt_pos[ch] += temp_wt[ind][0]
605
+ all_wt_neg[ch] += temp_wt[ind][1]
606
+ elif model_resource[1][start_layer]["class"] == "LSTM":
607
+ l1 = model_resource[0][start_layer]
608
+ return_sequence = l1.return_sequences
609
+ units = l1.units
610
+ num_of_cells = l1.input_shape[1]
611
+ lstm_obj_f = UC.LSTM_forward(
612
+ num_of_cells, units, l1.weights, return_sequence, False
613
+ )
614
+ lstm_obj_b = UC.LSTM_backtrace(
615
+ num_of_cells,
616
+ units,
617
+ [i.numpy() for i in l1.weights],
618
+ return_sequence,
619
+ False,
620
+ )
621
+ temp_out_f = lstm_obj_f.calculate_lstm_wt(
622
+ all_out[child_nodes[0]][0]
623
+ )
624
+ temp_wt_pos, temp_wt_neg = lstm_obj_b.calculate_lstm_wt(
625
+ all_wt_pos[start_layer],
626
+ all_wt_neg[start_layer],
627
+ lstm_obj_f.compute_log,
628
+ )
629
+ all_wt_pos[child_nodes[0]] = temp_wt_pos
630
+ all_wt_neg[child_nodes[0]] = temp_wt_neg
631
+ else:
632
+ temp_wt_pos = all_wt_pos[start_layer]
633
+ temp_wt_neg = all_wt_neg[start_layer]
634
+ all_wt_pos[child_nodes[0]] += temp_wt_pos
635
+ all_wt_neg[child_nodes[0]] += temp_wt_neg
636
+ for ch in child_nodes:
637
+ if not (ch in layer_stack):
638
+ layer_stack.append(ch)
639
+ return all_wt_pos, all_wt_neg
@@ -0,0 +1,41 @@
1
+ from dl_backtrace.pytorch_backtrace.backtrace.utils.prop import np_swish
2
+
3
+ activation_master = {
4
+ "None": {
5
+ "name": None,
6
+ "range": {"l": None, "u": None},
7
+ "type": "null",
8
+ "func": None,
9
+ },
10
+ "linear": {
11
+ "name": None,
12
+ "range": {"l": None, "u": None},
13
+ "type": "mono",
14
+ "func": None,
15
+ },
16
+ "tanh": {"name": "tanh", "range": {"l": -2, "u": 2}, "type": "mono", "func": None},
17
+ "sigmoid": {
18
+ "name": "sigmoid",
19
+ "range": {"l": -4, "u": 4},
20
+ "type": "mono",
21
+ "func": None,
22
+ },
23
+ "relu": {
24
+ "name": "relu",
25
+ "range": {"l": 0, "u": None},
26
+ "type": "mono",
27
+ "func": None,
28
+ },
29
+ "swish": {
30
+ "name": "swish",
31
+ "range": {"l": -6, "u": None},
32
+ "type": "non_mono",
33
+ "func": np_swish,
34
+ },
35
+ "softmax": {
36
+ "name": "softmax",
37
+ "range": {"l": -1, "u": 2},
38
+ "type": "mono",
39
+ "func": None,
40
+ },
41
+ }