Belle II Software  release-06-02-00
tensorflow_adversary.py
1 #!/usr/bin/env python3
2 
3 
10 
11 import numpy as np
12 import tensorflow as tf
13 import basf2_mva
14 
16 
17 
18 def get_variables(variables):
19  result = [tv for v in variables for tv in tf.all_variables() if v == tv.name]
20  if len(result) != len(variables):
21  print([tv.name for tv in tf.all_variables()])
22  print([v for v in variables if v not in list(tf.all_variables())])
23  raise RuntimeError("Did not find all variables in tensorflow scope")
24  return result
25 
26 
27 def get_model(number_of_features, number_of_spectators, number_of_events, training_fraction, parameters):
28 
29  tf.reset_default_graph()
30  x = tf.placeholder(tf.float32, [None, number_of_features])
31  y = tf.placeholder(tf.float32, [None, 1])
32  z = tf.placeholder(tf.float32, [None, number_of_spectators])
33  w = tf.placeholder(tf.float32, [None, 1])
34 
35  if parameters['lambda'] <= 0:
36  number_of_spectators = 0
37 
38  def layer(x, shape, name, unit=tf.sigmoid):
39  with tf.name_scope(name):
40  weights = tf.Variable(tf.truncated_normal(shape, stddev=1.0 / np.sqrt(float(shape[0]))), name='weights')
41  biases = tf.Variable(tf.constant(0.0, shape=[shape[1]]), name='biases')
42  layer = unit(tf.matmul(x, weights) + biases)
43  return layer
44 
45  inference_hidden1 = layer(x, [number_of_features, number_of_features + 1], 'inference_hidden1')
46  # inference_hidden2 = layer(inference_hidden1, [number_of_features+1, number_of_features+1], 'inference_hidden2')
47  # inference_hidden3 = layer(inference_hidden2, [number_of_features+1, number_of_features+1], 'inference_hidden3')
48  # inference_hidden4 = layer(inference_hidden3, [number_of_features+1, number_of_features+1], 'inference_hidden4')
49  inference_activation = layer(inference_hidden1, [number_of_features + 1, 1], 'inference_sigmoid', unit=tf.sigmoid)
50 
51  epsilon = 1e-5
52  inference_loss = -tf.reduce_sum(y * w * tf.log(inference_activation + epsilon) +
53  (1.0 - y) * w * tf.log(1 - inference_activation + epsilon)) / tf.reduce_sum(w)
54  inference_loss = tf.reduce_sum((y - inference_activation) * (y - inference_activation))
55  for i in range(number_of_spectators):
56  for c in ['signal', 'background']:
57  z_single = tf.slice(z, [0, i], [-1, 1])
58  adversary_hidden1 = layer(inference_activation, [1, number_of_features + 1],
59  'adversary_hidden1_{}_{}'.format(i, c), unit=tf.tanh)
60  # adversary_hidden2 = layer(adversary_hidden1, [number_of_features+1, number_of_features+1],
61  # 'adversary_hidden2_{}_{}'.format(i,c), unit=tf.nn.relu)
62  adversary_means = layer(adversary_hidden1, [number_of_features + 1, 4],
63  'adversary_means_{}_{}'.format(i, c), unit=tf.identity)
64  adversary_widths = layer(adversary_hidden1, [number_of_features + 1, 4],
65  'adversary_width_{}_{}'.format(i, c), unit=tf.exp)
66  adversary_fractions_not_normed = layer(adversary_hidden1, [number_of_features + 1, 4],
67  'adversary_fractions_{}_{}'.format(i, c), unit=tf.identity)
68  adversary_fractions = tf.nn.softmax(adversary_fractions_not_normed)
69  adversary_activation = tf.reduce_sum(adversary_fractions *
70  tf.exp(-(adversary_means - z_single) * (adversary_means - z_single) /
71  (2 * adversary_widths)) / tf.sqrt(2 * np.pi * adversary_widths), axis=1)
72  if c == 'signal':
73  adversary_loss = -tf.reduce_sum(y * w * tf.log(adversary_activation + epsilon)) / tf.reduce_sum(y * w)
74  else:
75  adversary_loss = -tf.reduce_sum((1 - y) * w * tf.log(adversary_activation + epsilon)) / tf.reduce_sum((1 - y) * w)
76  tf.add_to_collection('adversary_losses', adversary_loss)
77 
78  if number_of_spectators > 0:
79  adversary_loss = tf.add_n(tf.get_collection('adversary_losses'), name='adversary_loss')
80  total_loss = inference_loss - parameters.get('lambda', 50) * adversary_loss
81  else:
82  adversary_loss = None
83  total_loss = inference_loss
84 
85  adversary_vars = [
86  'adversary_hidden1_{}_{}/weights:0',
87  'adversary_hidden1_{}_{}/biases:0',
88  # 'adversary_hidden2_{}_{}/weights:0',
89  # 'adversary_hidden2_{}_{}/biases:0',
90  'adversary_means_{}_{}/weights:0',
91  'adversary_width_{}_{}/biases:0',
92  'adversary_fractions_{}_{}/weights:0',
93  'adversary_fractions_{}_{}/biases:0',
94  ]
95  adversary_vars = [v.format(i, c) for i in range(number_of_spectators) for c in ['signal', 'background'] for v in adversary_vars]
96 
97  if number_of_spectators > 0:
98  adversary_optimizer = tf.train.AdamOptimizer(learning_rate=parameters.get('learning_rate', 0.001))
99  adversary_global_step = tf.Variable(0, name='adversary_global_step', trainable=False)
100  adversary_minimize = adversary_optimizer.minimize(adversary_loss, global_step=adversary_global_step,
101  var_list=get_variables(adversary_vars))
102  else:
103  adversary_minimize = None
104 
105  inference_vars = [
106  'inference_hidden1/weights:0',
107  'inference_hidden1/biases:0',
108  # 'inference_hidden2/weights:0',
109  # 'inference_hidden2/biases:0',
110  # 'inference_hidden3/weights:0',
111  # 'inference_hidden3/biases:0',
112  # 'inference_hidden4/weights:0',
113  # 'inference_hidden4/biases:0',
114  'inference_sigmoid/weights:0',
115  'inference_sigmoid/biases:0',
116  ]
117 
118  inference_optimizer = tf.train.AdamOptimizer(learning_rate=parameters.get('learning_rate', 0.001))
119  inference_global_step = tf.Variable(0, name='inference_global_step', trainable=False)
120  inference_minimize = inference_optimizer.minimize(total_loss, global_step=inference_global_step,
121  var_list=get_variables(inference_vars))
122 
123  init = tf.global_variables_initializer()
124 
125  config = tf.ConfigProto()
126  config.gpu_options.allow_growth = True
127  session = tf.Session(config=config)
128 
129  session.run(init)
130  state = State(x, y, inference_activation, total_loss, inference_minimize, session)
131  state.adversary_cost = adversary_loss
132  state.adversary_optimizer = adversary_minimize
133  state.w = w
134  state.K = parameters.get('adversary_steps', 10)
135  state.z = z
136 
137  return state
138 
139 
140 def partial_fit(state, X, S, y, w, epoch):
141  """
142  Pass received data to tensorflow session
143  """
144  feed_dict = {state.x: X, state.y: y, state.w: w, state.z: S}
145  if epoch % state.K == 0 or state.adversary_optimizer is None:
146  state.session.run(state.optimizer, feed_dict=feed_dict)
147  avg_cost = state.session.run(state.cost, feed_dict=feed_dict)
148  if epoch % 100 == 0:
149  print("Epoch:", '%04d' % (epoch), "cost=", "{:.9f}".format(avg_cost))
150  else:
151  state.session.run(state.adversary_optimizer, feed_dict=feed_dict)
152  return True
153 
154 
155 if __name__ == "__main__":
156  from basf2 import conditions
157  # NOTE: do not use testing payloads in production! Any results obtained like this WILL NOT BE PUBLISHED
158  conditions.testing_payloads = [
159  'localdb/database.txt'
160  ]
161 
162  variables = ['p', 'pt', 'pz', 'phi',
163  'daughter(0, p)', 'daughter(0, pz)', 'daughter(0, pt)', 'daughter(0, phi)',
164  'daughter(1, p)', 'daughter(1, pz)', 'daughter(1, pt)', 'daughter(1, phi)',
165  'daughter(2, p)', 'daughter(2, pz)', 'daughter(2, pt)', 'daughter(2, phi)',
166  'chiProb', 'dr', 'dz', 'dphi',
167  'daughter(0, dr)', 'daughter(1, dr)', 'daughter(0, dz)', 'daughter(1, dz)',
168  'daughter(0, dphi)', 'daughter(1, dphi)',
169  'daughter(0, chiProb)', 'daughter(1, chiProb)', 'daughter(2, chiProb)',
170  'daughter(0, kaonID)', 'daughter(0, pionID)', 'daughter(1, kaonID)', 'daughter(1, pionID)',
171  'daughterAngle(0, 1)', 'daughterAngle(0, 2)', 'daughterAngle(1, 2)',
172  'daughter(2, daughter(0, E))', 'daughter(2, daughter(1, E))',
173  'daughter(2, daughter(0, clusterTiming))', 'daughter(2, daughter(1, clusterTiming))',
174  'daughter(2, daughter(0, clusterE9E25))', 'daughter(2, daughter(1, clusterE9E25))',
175  'daughter(2, daughter(0, minC2TDist))', 'daughter(2, daughter(1, minC2TDist))',
176  'M']
177 
178  variables2 = ['p', 'pt', 'pz', 'phi',
179  'chiProb', 'dr', 'dz', 'dphi',
180  'daughter(2, chiProb)',
181  'daughter(0, kaonID)', 'daughter(0, pionID)', 'daughter(1, kaonID)', 'daughter(1, pionID)',
182  'daughter(2, daughter(0, E))', 'daughter(2, daughter(1, E))',
183  'daughter(2, daughter(0, clusterTiming))', 'daughter(2, daughter(1, clusterTiming))',
184  'daughter(2, daughter(0, clusterE9E25))', 'daughter(2, daughter(1, clusterE9E25))',
185  'daughter(2, daughter(0, minC2TDist))', 'daughter(2, daughter(1, minC2TDist))']
186 
187  general_options = basf2_mva.GeneralOptions()
188  general_options.m_datafiles = basf2_mva.vector("train.root")
189  general_options.m_treename = "tree"
190  general_options.m_variables = basf2_mva.vector(*variables)
191  general_options.m_spectators = basf2_mva.vector('daughterInvariantMass(0, 1)', 'daughterInvariantMass(0, 2)')
192  general_options.m_target_variable = "isSignal"
193  general_options.m_identifier = "tensorflow"
194 
195  specific_options = basf2_mva.PythonOptions()
196  specific_options.m_framework = "tensorflow"
197  specific_options.m_steering_file = 'mva/examples/orthogonal_discriminators/tensorflow_adversary.py'
198  specific_options.m_normalize = True
199  specific_options.m_nIterations = 1000
200  specific_options.m_mini_batch_size = 400
201  specific_options.m_config = '{"adversary_steps": 13, "learning_rate": 0.001, "lambda": 0.1}'
202  basf2_mva.teacher(general_options, specific_options)
203 
204  general_options.m_identifier = "tensorflow_baseline"
205  specific_options.m_nIterations = 100
206  specific_options.m_config = '{"adversary_steps": 1, "learning_rate": 0.001, "lambda": -1.0}'
207  basf2_mva.teacher(general_options, specific_options)
208 
209  general_options.m_variables = basf2_mva.vector(*variables2)
210  general_options.m_identifier = "tensorflow_feature_drop"
211  basf2_mva.teacher(general_options, specific_options)