Skip to content

Commit 30df67b

Browse files
author
Julian Kates-Harbeck
committed
using signal hiding to compute influence
1 parent 83db2b6 commit 30df67b

4 files changed

Lines changed: 72 additions & 34 deletions

File tree

examples/signal_influence.py

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
from plasma.conf import conf
3838
from plasma.models.loader import Loader
39+
from plasma.primitives.shots import ShotList
3940
from plasma.preprocessor.normalize import Normalizer
4041
from plasma.preprocessor.augment import ByShotAugmentator
4142
from plasma.preprocessor.preprocess import guarantee_preprocessed
@@ -73,7 +74,7 @@
7374
custom_path = None
7475
if only_predict:
7576
custom_path = sys.argv[1]
76-
shot_num = sys.argv[2]
77+
shot_num = int(sys.argv[2])
7778
print("predicting using path {} on shot {}".format(custom_path,shot_num))
7879

7980
assert(only_predict)
@@ -85,27 +86,54 @@
8586
comm.Barrier()
8687
shot_list_train,shot_list_validate,shot_list_test = guarantee_preprocessed(conf)
8788

88-
shot_list = sum([l.filter_by_number([shot_num]) for l in [shot_list_train,shot_list_validate,shot_list_test]],[])
89+
shot_list = sum([l.filter_by_number([shot_num]) for l in [shot_list_train,shot_list_validate,shot_list_test]],ShotList())
90+
assert(len(shot_list) == 1)
8991
# for s in shot_list.shots:
9092
# s.restore()
9193

92-
def hide_signal_data(shot,t=0,sig_to_hide=None):
94+
def chunks(l, n):
95+
"""Yield successive n-sized chunks from l."""
96+
return[ l[i:i + n] for i in range(0, len(l), n)]
97+
98+
def hide_signal_data(shot,t=0,sigs_to_hide=None):
9399
for sig in shot.signals:
94-
if sig == sig_to_hide or sig_to_hide == None:
100+
if sigs_to_hide is None or (sigs_to_hide is not None and sig in sigs_to_hide):
95101
shot.signals_dict[sig][t:,:] = shot.signals_dict[sig][t,:]
96102

103+
def create_shot_list_tmp(original_shot,time_points,sigs=None):
104+
shot_list_tmp = ShotList()
105+
T = len(original_shot.ttd)
106+
t_range = np.linspace(0,T-1,time_points,dtype=np.int)
107+
for t in t_range:
108+
new_shot = copy.copy(original_shot)
109+
assert(new_shot.augmentation_fn == None)
110+
new_shot.augmentation_fn = partial(hide_signal_data,t = t,sigs_to_hide=sigs)
111+
#new_shot.number = original_shot.number
112+
shot_list_tmp.append(new_shot)
113+
return shot_list_tmp,t_range
114+
115+
def get_importance_measure(original_shot,loader,custom_path,metric,time_points=10,sig=None):
116+
shot_list_tmp,t_range = create_shot_list_tmp(original_shot,time_points,sigs)
117+
y_prime,y_gold,disruptive = mpi_make_predictions(conf,shot_list_tmp,loader,custom_path)
118+
shot_list_tmp.make_light()
119+
return t_range,get_importance_measure_given_y_prime(y_prime,metric),y_prime[-1]
120+
121+
def difference_metric(y_prime,y_prime_orig):
122+
idx = np.argmax(y_prime_orig)
123+
return (np.max(y_prime_orig) - y_prime[idx])/(np.max(y_prime_orig) - np.min(y_prime_orig))
124+
125+
def get_importance_measure_given_y_prime(y_prime,metric):
126+
differences = [metric(y_prime[i],y_prime[-1]) for i in range(len(y_prime))]
127+
return 1.0-np.array(differences)#/np.max(differences)
128+
129+
130+
97131

98-
original_shot = s[0]
99-
T = len(original_shot.ttd)
100-
t_range = np.linspace(0,T-1,10,dtype=np.int)
101-
for t in t_range:
102-
new_shot = copy.deepcopy(original_shot)
103-
assert(new_shot.augmentation_fn == None)
104-
new_shot.augmentation_fn = partial(hide_signal_data,t = t)
105-
hide_signal_data(new_shot,t,None)
106-
new_shot.number = original_shot.number
107-
shot_list.append(new_shot)
132+
original_shot = shot_list[0]
133+
original_shot.augmentation_fn = None
134+
original_shot.restore(conf['paths']['processed_prepath'])
108135

136+
#remove original shot
109137

110138

111139
print("normalization",end='')
@@ -120,29 +148,30 @@ def hide_signal_data(shot,t=0,sig_to_hide=None):
120148

121149
#load last model for testing
122150
loader.set_inference_mode(True)
123-
print('saving results')
124-
y_prime = []
125-
y_gold = []
126-
disruptive= []
151+
use_signals = copy.copy(conf['paths']['use_signals'])
152+
use_signals.append(None)
153+
importances = dict()
154+
y_prime = 0
155+
use_signals = [[s] for s in use_signals[:-3]] + [use_signals[-3:-1]] + [use_signals[-1]]
156+
print(use_signals)
157+
for sigs in use_signals:
158+
t_range,measure,y_prime = get_importance_measure(original_shot,loader,custom_path,difference_metric,time_points=128,sig=sigs)
159+
if sigs is None:
160+
idx = None
161+
else:
162+
idx = tuple(sorted(sigs))
163+
importances[idx] = (t_range,measure)
164+
127165

128-
# y_prime_train,y_gold_train,disruptive_train = make_predictions(conf,shot_list_train,loader)
129-
# y_prime_test,y_gold_test,disruptive_test = make_predictions(conf,shot_list_test,loader)
130-
131-
y_prime,y_gold,disruptive = mpi_make_predictions(conf,shot_list,loader,custom_path)
132166

133167
if task_index == 0:
134-
disruptive = np.array(disruptive)
135-
136-
shot_list.make_light()
137-
138-
save_str = 'signal_influence_results_' + datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
168+
save_str = 'signal_influence_results_{}_'.format(shot_num) + datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
139169
result_base_path = conf['paths']['results_prepath']
140170
if not os.path.exists(result_base_path):
141171
os.makedirs(result_base_path)
142-
143172
np.savez(result_base_path+save_str,
144-
y_gold=y_gold,y_prime=y_prime,disruptive=disruptive,
145-
shot_list=shot_list,conf = conf)
173+
original_shot=original_shot,importances=importances,y_prime=y_prime,conf = conf)
174+
shot_list.make_light()
146175

147176
sys.stdout.flush()
148177
if task_index == 0:

plasma/preprocessor/augment.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ def __str__(self):
1515
s += "\n including by shot augmentation"
1616
return s
1717

18-
@abc.abstractmethod
1918
def apply(self,shot):
2019
'''
2120
The purpose of the method is to apply normalization to a shot and then optionally apply augmentation with a function that is individual to every shot.
@@ -28,8 +27,11 @@ def apply(self,shot):
2827
'''
2928
#first just apply normalization as usual.
3029
self.normalizer.apply(shot)
31-
assert(shot.augmentation_fn is not None)
32-
shot.augmentation_fn(shot)
30+
if shot.augmentation_fn is not None:
31+
shot.augmentation_fn(shot)
32+
33+
def set_inference_mode(self,is_inference):
34+
self.normalizer.set_inference_mode(is_inference)
3335

3436

3537
class AbstractAugmentator(object):
@@ -50,6 +52,10 @@ def __str__(self):
5052
s += "Signal to augmented: {}\n".format(self.to_augment_str)
5153
s += "Is inference: {}\n".format(self.is_inference)
5254
return s
55+
56+
#for compatibility with code that changes the mode of the normalizer
57+
def set_inference_mode(self,is_inference):
58+
self.normalizer.set_inference_mode(is_inference)
5359

5460
@abc.abstractmethod
5561
def apply(self,shot):
@@ -58,6 +64,7 @@ def apply(self,shot):
5864
@abc.abstractmethod
5965
def augment(self,sig):
6066
pass
67+
6168

6269
class Augmentator(AbstractAugmentator):
6370

plasma/primitives/data.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ def get_idx(self,machine):
118118
return idx
119119

120120
def __eq__(self,other):
121+
if other is None:
122+
return False
121123
return self.description.__eq__(other.description)
122124

123125

plasma/primitives/shots.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ def __hash__(self):
329329

330330
def __str__(self):
331331
string = 'number: {}\n'.format(self.number)
332-
string = 'machine: {}\n'.format(self.machine)
332+
string += 'machine: {}\n'.format(self.machine)
333333
string += 'signals: {}\n'.format(self.signals )
334334
string += 'signals_dict: {}\n'.format(self.signals_dict )
335335
string += 'ttd: {}\n'.format(self.ttd )

0 commit comments

Comments
 (0)