This repo was developed by the Aachen ttHbb analysis group to make use of neuronal networks trained by Tensorflow / and Keras in the CMSSW framework. NNs are trained in Tensorflow and then exported as snapshots. The NNs can then be used for an evaluation in CMSSW via C++ functions.
The contents of this repo are slightly modified used to setup the ttbb and the ttH/ttZ/ttW analysis of the doktorarbeit-ttbb/ttbb repository. Therefore, this repo is only kept as a reference to the original version developed by Aachen and Marco A. Harrendorf.
- Original author: Marcel Rieger
- Forked from: gitlab.cern.ch/mharrend/CMSSW-DNN
- Main repository & issues: gitlab.cern.ch/mharrend/CMSSW-DNN
- Code mirror: github.com/mharrend/CMSSW-DNN
This project provides a simple yet fast interface to Tensorflow graphs and tensors which lets you evaluate trained models right within CMSSW. It does not depend on a converter library or custom NN implementation. By using the C-API's of both Python and NumPy (available via /cvmfs
), you can essentially load and evaluate every model that was previously saved via tf.train.Saver.save()
.
Tensorflow is available starting from CMSSW 9.0.X (PR). The software bundle for CMSSW 8.0.X is provided by M. Harrendorf.
- This package can also be used with out CMSSW, but then you have to make sure that the tensorflow python package is installed on your machine.
- Direct interface to Tensorflow / NumPy objects, no intermediate converter library required.
- Fast data access via Numpy arrays and in-place operations.
- Evaluation with multiple input and output tensors.
- Batching.
- GPU support.
- Easy way to make use of Tensorflow models obtained by training.
- Possibility to use binary or multimodal neural networks.
Tensorflow also provides a C++ API which could replace the Python/NumPy C API approch described above. However, it is not yet available in CMSSW (discussion). The plan is to transition to a pure Tensorflow backend once it becomes available while the (higher-level) API of this tool remains the same.
import tensorflow as tf
# define your model here
# example:
x_ = tf.placeholder(tf.float32, [None, 10], name="input")
W = tf.Variable(tf.ones([10, 1]))
b = tf.Variable(tf.ones([1]))
y = tf.add(tf.matmul(x_, W), b, name="output")
# create a session and initialize everything
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# train your model here
...
# save your model
saver = tf.train.Saver()
saver.save(sess, "/path/to/simplegraph")
- Checkout the Tensorflow/bin/test_tfModelUser executable and the DNN/Tensorflow/interface/tfModelUser.h class
- One has only to provide
- a Tensorflow model
- the number of input neurons or a list containing the input variables
- the number of output neurons or a list containing the output labels
- Afterwards one can evaluate the model by handing over a list containing the input variables and the function will return a vector containing the values for the output labels.
// load and initialize the model
//dnn::tf::tfModelUser modelUser(modelLoc, inputvariableList, outputLabelList); // alternative
dnn::tf::tfModelUser modelUser(modelLoc, 243, 4);
// Evaluate model event by event
returnVectorContainingOutputVariables = modelUser.evalModel(vectorContainingInputVariables);
(from test_tfgraph.cc
)
//
// setup
//
// load and initialize the graph
dnn::tf::Graph graph("/path/to/simplegraph");
// prepare input and output tensors
// no shape info required for output
dnn::tf::Shape xShape[] = {1, 10}; // 1 = single batch
dnn::tf::Tensor* x = graph.defineInput(new dnn::tf::Tensor("input:0", 2, xShape));
dnn::tf::Tensor* y = graph.defineOutput(new dnn::tf::Tensor("output:0"));
//
// evaluation
//
// example: fill a single batch of the input tensor with consecutive numbers
// -> [[0, 1, 2, ...]]
for (int i = 0; i < x->getShape(1); i++)
x->setValue<float>(0, i, (float)i);
// evaluation call
// this does not return anything but changes the output tensor(s) in-place
graph.eval();
// print the output
// -> [[float]]
std::cout << y->getValue<float>(0, 0) << std::endl;
// cleanup
delete x;
delete y;
As Keras can be backed by Tensorflow, the model saving process is identical:
import tensorflow as tf
sess = tf.Session()
from keras import backend as K
K.set_session(sess)
# define and train your keras model here
...
# save your model
saver = tf.train.Saver()
saver.save(sess, "/path/to/simplegraph")
A performance test (CPU only for now) is located at test_tfperf.cc
and runs 10k evaluations of a feed-forward network with 100 input features, 5 hidden elu layers with 200 nodes each, a softmax output with 10 nodes, and multiple batch sizes.
> test_tfperf
...
run 10000 evaluations for batch size 1
-> 1.4844 ms per batch
run 10000 evaluations for batch size 10
-> 3.4295 ms per batch
run 10000 evaluations for batch size 100
-> 7.563 ms per batch
run 10000 evaluations for batch size 1000
-> 15.7977 ms per batch
source /cvmfs/cms.cern.ch/cmsset_default.sh
export SCRAM_ARCH="slc6_amd64_gcc530"
export CMSSW_VERSION="CMSSW_8_0_26_patch2"
cmsrel $CMSSW_VERSION
cd $CMSSW_VERSION/src
cmsenv
git clone https://gitlab.cern.ch/mrieger/CMSSW-DNN.git DNN
./DNN/setup.sh
scram b -j