Skip to content

Commit 4e437ec

Browse files
committed
[tmva][sofie] Fix issue in Keras parser in Redhape operator
With this fix now the Keras parser can parse the convolutional model generated by TMVA_CNN_Classification
1 parent d2050f4 commit 4e437ec

File tree

4 files changed

+30
-21
lines changed

4 files changed

+30
-21
lines changed

bindings/pyroot/pythonizations/python/ROOT/_pythonization/_tmva/_sofie/_parser/_keras/layers/flatten.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ def MakeKerasFlatten(layer):
1717
Returns:
1818
ROperator_Reshape: A SOFIE framework operator representing the flattening operation.
1919
"""
20-
20+
2121
keras_version = get_keras_version()
22-
22+
2323
finput = layer['layerInput']
2424
foutput = layer['layerOutput']
2525
attributes = layer['layerAttributes']
@@ -31,6 +31,6 @@ def MakeKerasFlatten(layer):
3131
fLayerDType = layer['layerDType']
3232
fNameData = finput[0]
3333
fNameOutput = foutput[0]
34-
fNameShape = flayername + "ReshapeAxes"
34+
fNameShape = flayername + "_shape"
3535
op = gbl_namespace.TMVA.Experimental.SOFIE.ROperator_Reshape(fOpMode, 0, fNameData, fNameShape, fNameOutput)
3636
return op

bindings/pyroot/pythonizations/python/ROOT/_pythonization/_tmva/_sofie/_parser/_keras/layers/reshape.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ def MakeKerasReshape(layer):
1515
Returns:
1616
ROperator_Reshape: A SOFIE framework operator representing the reshaping operation.
1717
"""
18-
18+
1919
keras_version = get_keras_version()
20-
20+
2121
finput = layer['layerInput']
2222
foutput = layer['layerOutput']
2323
attributes = layer['layerAttributes']
@@ -29,6 +29,6 @@ def MakeKerasReshape(layer):
2929
fLayerDType = layer['layerDType']
3030
fNameData = finput[0]
3131
fNameOutput = foutput[0]
32-
fNameShape = flayername + "ReshapeAxes"
32+
fNameShape = flayername + "_shape"
3333
op = gbl_namespace.TMVA.Experimental.SOFIE.ROperator_Reshape(fOpMode, 0, fNameData, fNameShape, fNameOutput)
3434
return op

bindings/pyroot/pythonizations/python/ROOT/_pythonization/_tmva/_sofie/_parser/_keras/parser.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,9 @@ def add_layer_into_RModel(rmodel, layer_data):
9898

9999
fLayerType = layer_data['layerType']
100100

101-
# reshape and flatten layers don't have weights, but they are needed inside the list of initialized
102-
# tensor list in the Rmodel
101+
print('Model: adding layer',fLayerType)
102+
103+
# reshape and flatten layers don't have weights, but they need constant tensor for the shape
103104
if fLayerType == "Reshape" or fLayerType == "Flatten":
104105
Attributes = layer_data['layerAttributes']
105106
if keras_version < '2.16':
@@ -108,8 +109,8 @@ def add_layer_into_RModel(rmodel, layer_data):
108109
LayerName = Attributes['name']
109110

110111
if fLayerType == "Reshape":
111-
TargetShape = np.asarray(Attributes['target_shape']).astype("int")
112-
TargetShape = np.insert(TargetShape,0,0)
112+
TargetShape = np.asarray(Attributes['target_shape']).astype("int64")
113+
TargetShape = np.insert(TargetShape,0,1)
113114
else:
114115
if '_build_input_shape' in Attributes.keys():
115116
input_shape = Attributes['_build_input_shape']
@@ -124,8 +125,14 @@ def add_layer_into_RModel(rmodel, layer_data):
124125

125126
# since the AddInitializedTensor method in RModel requires unique pointer, we call a helper function
126127
# in c++ that does the conversion from a regular pointer to unique one in c++
127-
rmodel.AddInitializedTensor['long'](LayerName+"ReshapeAxes", [len(TargetShape)], TargetShape)
128-
128+
#print('adding initialized tensor..',LayerName, TargetShape)
129+
shape_tensor_name = LayerName + "_shape"
130+
shape_data = TargetShape.data
131+
print(TargetShape, shape_data)
132+
print(len(TargetShape))
133+
rmodel.AddInitializedTensor['int64_t'](shape_tensor_name, [len(TargetShape)], shape_data)
134+
135+
print('check other layers...')
129136
# These layers only have one operator - excluding the recurrent layers, in which the activation function(s)
130137
# are included in the recurrent operator
131138
if fLayerType in mapKerasLayer.keys():
@@ -340,7 +347,6 @@ def Parse(filename, batch_size=1): # If a model does not have a defined batch s
340347
# and output names
341348
layer_iter = 0
342349
is_functional_model = True if keras_model.__class__.__name__ == 'Functional' else False
343-
prev_layer_name = "input"
344350
for layer in keras_model.layers:
345351
layer_data={}
346352
layer_data['layerType']=layer.__class__.__name__
@@ -365,14 +371,13 @@ def Parse(filename, batch_size=1): # If a model does not have a defined batch s
365371
if keras_version < '2.16' or is_functional_model:
366372
layer_data['layerOutput']=[x.name for x in layer.output] if isinstance(layer.output,list) else [layer.output.name]
367373
else:
368-
#sequentiall model in Keras3
374+
#sequential model in Keras3
369375
output_layer_name = "tensor_output_" + layer.name
370376
layer_data['layerOutput']=[x.name for x in layer.output] if isinstance(layer.output,list) else [output_layer_name]
371377

372378
layer_iter += 1
373379
fLayerType = layer_data['layerType']
374380
layer_data['layerDType'] = layer.dtype
375-
prev_layer_name = layer.name
376381

377382
if len(layer.weights) > 0:
378383
if keras_version < '2.16':

tutorials/machine_learning/TMVA_SOFIE_Keras_HiggsModel.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,22 +92,26 @@ def GenerateCode(modelFile = "model.keras") :
9292
modelFile = TrainModel(model,x_train, y_train, 'HiggsModel')
9393

9494
###################################################################
95-
## Step 2 : Pase model and generate inference code with SOFIE
95+
## Step 2 : Parse model and generate inference code with SOFIE
9696
###################################################################
9797

98-
9998
modelName = GenerateCode(modelFile)
10099
modelHeaderFile = modelName + ".hxx"
101100

102-
#compile the generated code
101+
###################################################################
102+
## Step 3 : Compile the generated C++ model code
103+
###################################################################
104+
103105
ROOT.gInterpreter.Declare('#include "' + modelHeaderFile + '"')
104106

105-
#get the sofie session namespace
107+
###################################################################
108+
## Step 4: Evaluate the model
109+
###################################################################
110+
111+
#get first the SOFIE session namespace
106112
sofie = getattr(ROOT, 'TMVA_SOFIE_' + modelName)
107113
session = sofie.Session()
108114

109-
#Evaluate the model
110-
111115
x = np.random.normal(0,1,7).astype(np.float32)
112116
y = session.infer(x)
113117
ykeras = model(x.reshape(1,7)).numpy()

0 commit comments

Comments
 (0)