Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TMVA_SOFIE_RDataFrame.py
Go to the documentation of this file.
1### \file
2### \ingroup tutorial_ml
3### \notebook -nodraw
4### Example of inference with SOFIE and RDataFrame, of a model trained with PyTorch.
5### First, generate the input ONNX model by running `TMVA_SOFIE_PyTorch_HiggsModel.py`.
6###
7### This tutorial parses the input model and runs the inference using ROOT's JITing capability.
8###
9### \macro_code
10### \macro_output
11### \author Lorenzo Moneta
12
13from os.path import exists
14
15import ROOT
16
17# check if the input file exists
18modelFile = "HiggsModel.onnx"
19modelName = "HiggsModel"
20
21if not exists(modelFile):
22 raise FileNotFoundError("You need to run TMVA_SOFIE_PyTorch_HiggsModel.py to generate the ONNX trained model")
23
24# parse the input ONNX model into RModel object
25parser = ROOT.TMVA.Experimental.SOFIE.RModelParser_ONNX()
26model = parser.Parse(modelFile)
27
28# generating inference code
29model.Generate()
30model.OutputGenerated("Higgs_trained_model_generated.hxx")
31model.PrintGenerated()
32
33# compile using ROOT JIT trained model
34print("compiling SOFIE model and inference helper....")
35ROOT.gInterpreter.Declare('#include "Higgs_trained_model_generated.hxx"\n#include <array>\n#include <vector>')
36
37# A SOFIE Session holds the model weights and the intermediate buffers and is not
38# thread-safe: create one Session per RDataFrame processing slot and dispatch on
39# the slot number. This tutorial runs single-threaded, so a single Session is enough.
40# The weights file name is passed explicitly because the generated header was
41# written under a custom name.
42ROOT.gInterpreter.ProcessLine("std::vector<TMVA_SOFIE_" + modelName + "::Session> sofie_sessions;")
43ROOT.sofie_sessions.emplace_back("Higgs_trained_model_generated.dat")
44
45# Declare the inference function for RDataFrame: it assembles the model input
46# tensor from the columns and evaluates the model. The column order must match
47# the ordering of the model input tensor.
48ROOT.gInterpreter.Declare("""
49double sofie_eval(unsigned int slot, float m_jj, float m_jjj, float m_lv, float m_jlv, float m_bb, float m_wbb,
50 float m_wwbb)
51{
52 std::array<float, 7> input{m_jj, m_jjj, m_lv, m_jlv, m_bb, m_wbb, m_wwbb};
53 return sofie_sessions[slot].infer(input.data())[0];
54}
55""")
56
57# run inference over input data
58inputFile = str(ROOT.gROOT.GetTutorialDir()) + "/machine_learning/data/Higgs_data.root"
59df1 = ROOT.RDataFrame("sig_tree", inputFile)
60h1 = df1.Define("DNN_Value", "sofie_eval(rdfslot_,m_jj, m_jjj, m_lv, m_jlv, m_bb, m_wbb, m_wwbb)").Histo1D(("h_sig", "", 100, 0, 1),"DNN_Value")
61
62df2 = ROOT.RDataFrame("bkg_tree", inputFile)
63h2 = df2.Define("DNN_Value", "sofie_eval(rdfslot_,m_jj, m_jjj, m_lv, m_jlv, m_bb, m_wbb, m_wwbb)").Histo1D(("h_bkg", "", 100, 0, 1),"DNN_Value")
64
65# run over the input data once, combining both RDataFrame graphs.
66ROOT.RDF.RunGraphs([h1, h2])
67
68print("Number of signal entries",h1.GetEntries())
69print("Number of background entries",h2.GetEntries())
70
71h1.SetLineColor("kRed")
72h2.SetLineColor("kBlue")
73
74c1 = ROOT.TCanvas()
75ROOT.gStyle.SetOptStat(0)
76
77h2.DrawClone()
78h1.DrawClone("SAME")
ROOT's RDataFrame offers a modern, high-level interface for analysis of data stored in TTree ,...
unsigned int RunGraphs(std::vector< RResultHandle > handles)
Run the event loops of multiple RDataFrames concurrently.