This tutorial shows how to store several models in a single header file and the weights in a ROOT binary file. The models are then evaluated using the RDataFrame
import inspect
import os
import numpy as np
import ROOT
import torch
def CreateModel(nlayers=4, nunits=64):
layers = []
ninputs = 7
ninputs = nunits
print(model)
return model
def TrainModel(model, x, y, epochs=5, batch_size=50):
nbatches =
x.shape[0] // batch_size
for epoch
in range(epochs):
running_loss = 0.0
for i
in range(nbatches):
idx = perm[i * batch_size : (i + 1) * batch_size]
print(f"Epoch {epoch + 1}/{epochs} - average loss: {running_loss / nbatches:.4f}")
def ExportModel(model, modelName):
modelFile = modelName + ".onnx"
model(dummy_x)
input_names=["input"],
output_names=["output"],
external_data=False,
dynamo=True,
)
print("calling torch.onnx.export with parameters", kwargs)
print("model exported to ONNX as", modelFile)
return modelFile
def PrepareData():
sigData =
df1.AsNumpy(columns=[
"m_jj",
"m_jjj",
"m_lv",
"m_jlv",
"m_bb",
"m_wbb",
"m_wwbb"])
print("size of data", data_sig_size)
bkgData =
df2.AsNumpy(columns=[
"m_jj",
"m_jjj",
"m_lv",
"m_jlv",
"m_bb",
"m_wbb",
"m_wwbb"])
x_train = inputs_data[idx[:ntrain]]
y_train = inputs_targets[idx[:ntrain]].
reshape(-1, 1)
x_test = inputs_data[idx[ntrain:]]
y_test = inputs_targets[idx[ntrain:]].
reshape(-1, 1)
return x_train, y_train, x_test, y_test
modelFiles = []
for modelName in modelNames:
model = CreateModel(4, 64)
TrainModel(model, x_train, y_train)
return modelFiles
x_train, y_train, x_test, y_test = PrepareData()
modelNames = ["Higgs_Model_4L_50", "Higgs_Model_4L_200", "Higgs_Model_2L_500"]
model1, model2, model3 =
TrainModels(x_train, y_train, modelNames)
print("Generating inference code for the ONNX model from ", modelFile, "in the header ", generatedHeaderFile)
return generatedHeaderFile
generatedHeaderFile = "Higgs_Model.hxx"
print("removing existing file", generatedHeaderFile)
weightFile = "Higgs_Model.root"
print("removing existing file", weightFile)
hs1 =
ROOT.TH1D(
"hs1",
"Signal result 4L 50", 100, 0, 1)
hs2 =
ROOT.TH1D(
"hs2",
"Signal result 4L 200", 100, 0, 1)
hs3 =
ROOT.TH1D(
"hs3",
"Signal result 2L 500", 100, 0, 1)
hb1 =
ROOT.TH1D(
"hb1",
"Background result 4L 50", 100, 0, 1)
hb2 =
ROOT.TH1D(
"hb2",
"Background result 4L 200", 100, 0, 1)
hb3 =
ROOT.TH1D(
"hb3",
"Background result 2L 500", 100, 0, 1)
return result[0]
if y_test[i] == 1:
else:
def GetContent(h):
return x, w
xs, ws = GetContent(hs)
xb, wb = GetContent(hb)
return roc, curve
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
ROOT's RDataFrame offers a modern, high-level interface for analysis of data stored in TTree ,...
size of data 10000
Sequential(
(0): Linear(in_features=7, out_features=64, bias=True)
(1): ReLU()
(2): Linear(in_features=64, out_features=64, bias=True)
(3): ReLU()
(4): Linear(in_features=64, out_features=64, bias=True)
(5): ReLU()
(6): Linear(in_features=64, out_features=64, bias=True)
(7): ReLU()
(8): Linear(in_features=64, out_features=1, bias=True)
(9): Sigmoid()
)
Epoch 1/5 - average loss: 0.6687
Epoch 2/5 - average loss: 0.6408
Epoch 3/5 - average loss: 0.6283
Epoch 4/5 - average loss: 0.6215
Epoch 5/5 - average loss: 0.6150
calling torch.onnx.export with parameters {'input_names': ['input'], 'output_names': ['output'], 'external_data': False, 'dynamo': True}
[torch.onnx] Obtain model graph for `Sequential([...]` with `torch.export.export(..., strict=False)`...
[torch.onnx] Obtain model graph for `Sequential([...]` with `torch.export.export(..., strict=False)`... ✅
[torch.onnx] Run decompositions...
[torch.onnx] Run decompositions... ✅
[torch.onnx] Translate the graph into ONNX...
[torch.onnx] Translate the graph into ONNX... ✅
[torch.onnx] Optimize the ONNX graph...
[torch.onnx] Optimize the ONNX graph... ✅
model exported to ONNX as Higgs_Model_4L_50.onnx
Sequential(
(0): Linear(in_features=7, out_features=64, bias=True)
(1): ReLU()
(2): Linear(in_features=64, out_features=64, bias=True)
(3): ReLU()
(4): Linear(in_features=64, out_features=64, bias=True)
(5): ReLU()
(6): Linear(in_features=64, out_features=64, bias=True)
(7): ReLU()
(8): Linear(in_features=64, out_features=1, bias=True)
(9): Sigmoid()
)
Epoch 1/5 - average loss: 0.6691
Epoch 2/5 - average loss: 0.6431
Epoch 3/5 - average loss: 0.6283
Epoch 4/5 - average loss: 0.6227
Epoch 5/5 - average loss: 0.6178
calling torch.onnx.export with parameters {'input_names': ['input'], 'output_names': ['output'], 'external_data': False, 'dynamo': True}
[torch.onnx] Obtain model graph for `Sequential([...]` with `torch.export.export(..., strict=False)`...
[torch.onnx] Obtain model graph for `Sequential([...]` with `torch.export.export(..., strict=False)`... ✅
[torch.onnx] Run decompositions...
[torch.onnx] Run decompositions... ✅
[torch.onnx] Translate the graph into ONNX...
[torch.onnx] Translate the graph into ONNX... ✅
[torch.onnx] Optimize the ONNX graph...
[torch.onnx] Optimize the ONNX graph... ✅
model exported to ONNX as Higgs_Model_4L_200.onnx
Sequential(
(0): Linear(in_features=7, out_features=64, bias=True)
(1): ReLU()
(2): Linear(in_features=64, out_features=64, bias=True)
(3): ReLU()
(4): Linear(in_features=64, out_features=64, bias=True)
(5): ReLU()
(6): Linear(in_features=64, out_features=64, bias=True)
(7): ReLU()
(8): Linear(in_features=64, out_features=1, bias=True)
(9): Sigmoid()
)
Epoch 1/5 - average loss: 0.6721
Epoch 2/5 - average loss: 0.6410
Epoch 3/5 - average loss: 0.6317
Epoch 4/5 - average loss: 0.6216
Epoch 5/5 - average loss: 0.6137
calling torch.onnx.export with parameters {'input_names': ['input'], 'output_names': ['output'], 'external_data': False, 'dynamo': True}
[torch.onnx] Obtain model graph for `Sequential([...]` with `torch.export.export(..., strict=False)`...
[torch.onnx] Obtain model graph for `Sequential([...]` with `torch.export.export(..., strict=False)`... ✅
[torch.onnx] Run decompositions...
[torch.onnx] Run decompositions... ✅
[torch.onnx] Translate the graph into ONNX...
[torch.onnx] Translate the graph into ONNX... ✅
[torch.onnx] Optimize the ONNX graph...
[torch.onnx] Optimize the ONNX graph... ✅
model exported to ONNX as Higgs_Model_2L_500.onnx
Generating inference code for the ONNX model from Higgs_Model_4L_50.onnx in the header Higgs_Model.hxx
Generating inference code for the ONNX model from Higgs_Model_4L_200.onnx in the header Higgs_Model.hxx
Generating inference code for the ONNX model from Higgs_Model_2L_500.onnx in the header Higgs_Model.hxx
ROC integral for hs1 0.7373348431513707
ROC integral for hs2 0.7315016389230002
ROC integral for hs3 0.7254055845906716