5
5
from net import Net
6
6
7
7
8
- def do_plot (guided_backprops , indices , image , bounding_box , files_dict ):
9
- top_grads = [guided_backprops [i ] for i in indices ]
10
- folder = list (files_dict .keys ())[0 ]
11
- name = files_dict [folder ][0 ]
12
- get_full_plot (top_grads , image , bounding_box , folder , name )
8
+ def do_batch_plot (guided_backprops , indices , images , bounding_boxes , files_dict ):
9
+ folders_and_names = []
10
+ for key , values in files_dict .items ():
11
+ for val in values :
12
+ folders_and_names .append ([key , val ])
13
+ for gbps , index , image , bb , fn in zip (guided_backprops , indices , images , bounding_boxes , folders_and_names ):
14
+ top_grads = [gbps [i ] for i in index ]
15
+ get_full_plot (top_grads , image , bb , * fn )
13
16
14
17
15
18
class Agent (object ):
@@ -23,17 +26,17 @@ def __init__(self, config):
23
26
24
27
def get_bounding_box (self , image = None , files_dict = None ):
25
28
if image is None and files_dict is None :
26
- image , files_dict = sample_data (1 )
29
+ image , files_dict = sample_data (self . config . batch_size )
27
30
preprocessed_image = self ._preprocess (image .copy ())
28
- kmax_neuron_indices , top_class = self ._get_kmax_neurons (preprocessed_image )
31
+ kmax_neuron_indices , top_classes_indices = self .net . get_top_kmax_neurons (preprocessed_image )
29
32
guided_backprops = self ._get_guided_backprops (preprocessed_image , kmax_neuron_indices )
30
- masks = self ._get_image_masks (guided_backprops )
31
- topk_neurons_relative_indices = self ._get_topk_neurons (preprocessed_image , masks , top_class )
32
- bounding_box , _ = self ._get_bounding_box (masks , topk_neurons_relative_indices )
33
+ masks = self ._get_images_masks (guided_backprops )
34
+ top_k_neurons_relative_indices = self ._get_top_k_neurons (preprocessed_image , masks , top_classes_indices )
35
+ bounding_boxes = self ._get_all_bounding_boxes (masks , top_k_neurons_relative_indices )
33
36
if self .config .do_plotting :
34
- do_plot (guided_backprops , topk_neurons_relative_indices ,
35
- image , bounding_box , files_dict )
36
- return bounding_box
37
+ do_batch_plot (guided_backprops , top_k_neurons_relative_indices ,
38
+ image , bounding_boxes , files_dict )
39
+ return bounding_boxes
37
40
38
41
def make_tsne_pic_for_directory (self , folder = 'personal' ):
39
42
fc_features = None
@@ -48,52 +51,49 @@ def make_tsne_pic_for_directory(self, folder='personal'):
48
51
49
52
tsne = T_SNE ()
50
53
tsne_embedding = tsne .generate_tsne (fc_features )
51
- tsne .save_grid (images , tsne_embedding , folder + '.jpg' )
54
+ tsne .save_grid (images , tsne_embedding , folder + '.jpg' )
52
55
53
56
def _preprocess (self , image ):
54
57
return self .net .vgg16 .preprocess_input (image )
55
58
56
- def _get_kmax_neurons (self , image ):
57
- class_scores = self .net .get_class_scores (image )
58
- n = len (self .config .top_n_classes_weights )
59
- top_class = np .argmax (class_scores )
60
- top_classes = np .argsort (class_scores )[- n :]
61
- top_scores = class_scores [top_classes ]
62
- activations = self .net .get_activations (image )
63
-
64
- normalizer = 1.0 / (np .sum (self .config .top_n_classes_weights ) * np .sum (top_scores ))
65
-
66
- impact_gradient = 0
67
- for i , class_index in enumerate (top_classes ):
68
- impact_gradient_per_class = self .net .get_impact_gradient_per_class (activations = activations ,
69
- class_index = class_index )
70
- impact_gradient += impact_gradient_per_class * top_scores [i ] * \
71
- self .config .top_n_classes_weights [i ] * normalizer
72
-
73
- rank_score = activations * impact_gradient
74
- kmax_neurons = np .argsort (rank_score .ravel ())[- self .config .kmax :]
75
- return kmax_neurons , top_class
76
-
77
- def _get_guided_backprops (self , image , neuron_indices ):
78
- guided_backprops = [self .net .get_guided_backprop (image , neuron_index ) for neuron_index in neuron_indices ]
59
+ def _get_guided_backprops (self , images , neuron_indices ):
60
+ # lazy programming, this part should as well be vectorized
61
+ guided_backprops = []
62
+ for image , neuron_index in zip (images , neuron_indices ):
63
+ gbp = [self .net .get_guided_backprop (np .expand_dims (image , axis = 0 ), ni )
64
+ for ni in neuron_index ]
65
+ guided_backprops .append (gbp )
79
66
return guided_backprops
80
67
81
- def _get_image_masks (self , guided_backprops ):
82
- projected_gbps = [np .max (gb , axis = - 1 ).squeeze () for gb in guided_backprops ]
83
- raw_masks = [pgbp > np .percentile (pgbp , self .config .cut_off_percentile ) for pgbp in projected_gbps ]
84
- # erosion and dilation
85
- masks = [binary_dilation (binary_erosion (raw_mask )).astype (projected_gbps [0 ].dtype ) for raw_mask in raw_masks ]
68
+ def _get_images_masks (self , guided_backprops ):
69
+ masks = []
70
+ for gbps in guided_backprops :
71
+ projected_gbps = [np .max (gb , axis = - 1 ).squeeze () for gb in gbps ]
72
+ raw_masks = [pgbp > np .percentile (pgbp , self .config .cut_off_percentile ) for pgbp in projected_gbps ]
73
+ # erosion and dilation
74
+ masks_per_image = [binary_dilation (binary_erosion (raw_mask )).astype (projected_gbps [0 ].dtype ) for raw_mask in
75
+ raw_masks ]
76
+ masks .append (masks_per_image )
86
77
return masks
87
78
88
- def _get_topk_neurons (self , image , masks , top_class ):
89
- reshaped_image = image .reshape (np .roll (self .config .vgg16 .input_size , 1 ))
90
- images = np .stack ([np .reshape (reshaped_image * mask , self .config .vgg16 .input_size ) for mask in masks ])
91
- losses = self .net .get_batch_loss (images , top_class )
92
- return list (np .argsort (losses )[:self .config .k ])
93
- # return kmax_neuron_indices[np.argsort(losses)[:self.config.k]]
79
+ def _get_top_k_neurons (self , images , masks , top_class ):
80
+ top_k_neurons_relative_indices = []
81
+ for i , image in enumerate (images ):
82
+ reshaped_image = image .reshape (np .roll (self .config .vgg16 .input_size , 1 ))
83
+ masked_images = np .stack (
84
+ [np .reshape (reshaped_image * mask , self .config .vgg16 .input_size ) for mask in masks [i ]])
85
+ losses = self .net .get_batch_loss (masked_images , top_class [i ])
86
+ top_k_neurons_relative_indices .append (list (np .argsort (losses )[:self .config .k ]))
87
+ return top_k_neurons_relative_indices
88
+
89
+ def _get_all_bounding_boxes (self , all_masks , all_mask_indices ):
90
+ bounding_boxes = []
91
+ for mask , mask_indices in zip (all_masks , all_mask_indices ):
92
+ bounding_boxes .append (self ._get_bounding_box (mask , mask_indices ))
93
+ return bounding_boxes
94
94
95
95
def _get_bounding_box (self , masks , mask_indices ):
96
- # sorry, worst piece of code mankind has ever done
96
+ # sorry, super lazy
97
97
final_masks = np .array (masks )[mask_indices ]
98
98
the_mask = final_masks [0 ] * False
99
99
for mask in final_masks :
@@ -108,4 +108,4 @@ def _get_bounding_box(self, masks, mask_indices):
108
108
x_min = min (x_min , j )
109
109
y_max = max (y_max , i )
110
110
x_max = max (x_max , j )
111
- return [[x_min , y_min ], [x_max , y_max ]], the_mask
111
+ return [[x_min , y_min ], [x_max , y_max ]]
0 commit comments