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