Import/Export Network
Listed here are all the modalitites by which you save or export (load or import) the nnodely model. There are four modalityies:
Save/Load the model definition in a json file
Save/Load network parameters in a pickle file
Export/Import a standalone pytorch model
Export the network to an ONNX format
Make inference with a previously exported ONNX network
[1]:
# uncomment the command below to install the nnodely package
#!pip install nnodely
from nnodely import *
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>-- nnodely_v1.5.0 --<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
In the following lines a network is created. When the nnodely object is created the workspace folder is defined.
The workspace is used as folder to save or load all the models if no other folder is defined during a save/export operation.
[3]:
x = Input('x')
y = Input('y')
z = Input('z')
def myFun(K1,p1,p2):
return K1*p1*p2
K_x = Parameter('k_x', dimensions=1, tw=1)
c_v = Constant('c_v', tw=1, values=[[1],[2]])
parfun = ParamFun(myFun, parameters_and_constants = [K_x,c_v])
out = Output('out', Fir(parfun(x.tw(1)))+Fir(parfun(y.tw(1)))+Fir(parfun(z.tw(1))))
result_path = './results'
model = Modely(workspace=result_path)
model.addModel('model', out)
[check_names] The name 'x' is already in defined as NeuObj but it is overwritten.
[check_names] The name 'y' is already in defined as NeuObj but it is overwritten.
[check_names] The name 'z' is already in defined as NeuObj but it is overwritten.
[check_names] The name 'k_x' is already in defined as NeuObj but it is overwritten.
[check_names] The name 'c_v' is already in defined as NeuObj but it is overwritten.
[check_names] The name 'out' is already in defined as NeuObj but it is overwritten.
Save/Load the model definition in a json file
If no ‘name’ or ‘model_folder’ is defined the file is saved in workspace folder with ‘net’ as name.
[4]:
model.saveModel()
=============================== Save JSON Model ================================
Model saved in: ./results\net.json
================================================================================
[5]:
model.saveModel(name='model_definition', model_folder=result_path)
=============================== Save JSON Model ================================
Model saved in: ./results\model_definition.json
================================================================================
Save/Load network parameters in a pickle file
After the model neuralization is possible to save the parameters of the network in a pickle file
[6]:
model.neuralizeModel(0.5)
model.saveTorchModel(name='model_parameters', model_folder=result_path)
================================ nnodely Model =================================
{'Constants': {'c_v': {'dim': 1, 'tw': 1, 'values': [[1.0], [2.0]]}},
'Functions': {'FParamFun19': {'code': 'def myFun(K1,p1,p2):\n'
' return K1*p1*p2\n',
'in_dim': [{'dim': 1, 'tw': 1}],
'map_over_dim': False,
'n_input': 1,
'name': 'myFun',
'params_and_consts': ['k_x', 'c_v']}},
'Info': {'SampleTime': 0.5,
'nnodely_version': '1.5.0',
'ns': [2, 0],
'ntot': 2,
'num_parameters': 8},
'Inputs': {'x': {'dim': 1, 'ns': [2, 0], 'ntot': 2, 'tw': [-1, 0]},
'y': {'dim': 1, 'ns': [2, 0], 'ntot': 2, 'tw': [-1, 0]},
'z': {'dim': 1, 'ns': [2, 0], 'ntot': 2, 'tw': [-1, 0]}},
'Models': 'model',
'Outputs': {'out': 'Add27'},
'Parameters': {'PFir20W': {'dim': 1,
'tw': 1,
'values': [[0.10332220792770386],
[0.6755136847496033]]},
'PFir22W': {'dim': 1,
'tw': 1,
'values': [[0.3977568745613098],
[0.8827944397926331]]},
'PFir24W': {'dim': 1,
'tw': 1,
'values': [[0.7688933610916138],
[0.8726053833961487]]},
'k_x': {'dim': 1,
'tw': 1,
'values': [[0.1419960856437683],
[0.6352357268333435]]}},
'Relations': {'Add22': ['Add', ['Fir17', 'Fir21']],
'Add27': ['Add', ['Add22', 'Fir26']],
'Fir17': ['Fir', ['ParamFun16'], 'PFir20W', None, 0],
'Fir21': ['Fir', ['ParamFun20'], 'PFir22W', None, 0],
'Fir26': ['Fir', ['ParamFun25'], 'PFir24W', None, 0],
'ParamFun16': ['ParamFun', ['TimePart15'], 'FParamFun19'],
'ParamFun20': ['ParamFun', ['TimePart19'], 'FParamFun19'],
'ParamFun25': ['ParamFun', ['TimePart24'], 'FParamFun19'],
'TimePart15': ['TimePart', ['x'], -1, [-1, 0]],
'TimePart19': ['TimePart', ['y'], -1, [-1, 0]],
'TimePart24': ['TimePart', ['z'], -1, [-1, 0]]}}
================================================================================
=============================== Save Torch Model ===============================
Model saved in: ./results\model_parameters.pt
================================================================================
In order to load a pickle file the network parameters of the model must match.
[7]:
model.loadTorchModel(name='model_parameters', model_folder=result_path)
=============================== Load Torch Model ===============================
Model loaded from: ./results\model_parameters.pt
================================================================================
Export/Import pytorch model
Exports the neural network model as a stand-alone PyTorch Module class. With the pytorch model also the json model is saved.
[8]:
model.exportPythonModel(name='pytorch_model', model_folder=result_path)
=============================== Save JSON Model ================================
Model saved in: ./results\pytorch_model.json
================================================================================
========================== Export Python Torch Model ===========================
Model exported in: ./results\pytorch_model.py
================================================================================
In order to import a python model also a json model in the same folder with the same name must be present.
When the model is imported from a python model, this model has limited properties (for example cannot be exported as onnx).
[9]:
model.importPythonModel(name='pytorch_model', model_folder=result_path)
=============================== Load JSON Model ================================
Model loaded from: ./results\pytorch_model.json
================================================================================
================================ nnodely Model =================================
{'Constants': {'c_v': {'dim': 1, 'tw': 1, 'values': [[1.0], [2.0]]}},
'Functions': {'FParamFun19': {'code': 'def myFun(K1,p1,p2):\n'
' return K1*p1*p2\n',
'in_dim': [{'dim': 1, 'tw': 1}],
'map_over_dim': False,
'n_input': 1,
'name': 'myFun',
'params_and_consts': ['k_x', 'c_v']}},
'Info': {'SampleTime': 0.5,
'nnodely_version': '1.5.0',
'ns': [2, 0],
'ntot': 2,
'num_parameters': 8},
'Inputs': {'x': {'dim': 1, 'ns': [2, 0], 'ntot': 2, 'tw': [-1, 0]},
'y': {'dim': 1, 'ns': [2, 0], 'ntot': 2, 'tw': [-1, 0]},
'z': {'dim': 1, 'ns': [2, 0], 'ntot': 2, 'tw': [-1, 0]}},
'Models': 'model',
'Outputs': {'out': 'Add27'},
'Parameters': {'PFir20W': {'dim': 1,
'tw': 1,
'values': [[0.10332220792770386],
[0.6755136847496033]]},
'PFir22W': {'dim': 1,
'tw': 1,
'values': [[0.3977568745613098],
[0.8827944397926331]]},
'PFir24W': {'dim': 1,
'tw': 1,
'values': [[0.7688933610916138],
[0.8726053833961487]]},
'k_x': {'dim': 1,
'tw': 1,
'values': [[0.1419960856437683],
[0.6352357268333435]]}},
'Relations': {'Add22': ['Add', ['Fir17', 'Fir21']],
'Add27': ['Add', ['Add22', 'Fir26']],
'Fir17': ['Fir', ['ParamFun16'], 'PFir20W', None, 0],
'Fir21': ['Fir', ['ParamFun20'], 'PFir22W', None, 0],
'Fir26': ['Fir', ['ParamFun25'], 'PFir24W', None, 0],
'ParamFun16': ['ParamFun', ['TimePart15'], 'FParamFun19'],
'ParamFun20': ['ParamFun', ['TimePart19'], 'FParamFun19'],
'ParamFun25': ['ParamFun', ['TimePart24'], 'FParamFun19'],
'TimePart15': ['TimePart', ['x'], -1, [-1, 0]],
'TimePart19': ['TimePart', ['y'], -1, [-1, 0]],
'TimePart24': ['TimePart', ['z'], -1, [-1, 0]]}}
================================================================================
========================== Import Python Torch Model ===========================
Model imported from: ./results\pytorch_model.py
================================================================================
Export the network to an ONNX format
A pythorch model imported can’t be exported as onnx file.
In order to export a onnx network the model must be created by neuralization.
[10]:
model.neuralizeModel(0.5)
model.exportONNX(name='model_onnx', model_folder=result_path)
================================ nnodely Model =================================
{'Constants': {'c_v': {'dim': 1, 'tw': 1, 'values': [[1.0], [2.0]]}},
'Functions': {'FParamFun19': {'code': 'def myFun(K1,p1,p2):\n'
' return K1*p1*p2\n',
'in_dim': [{'dim': 1, 'tw': 1}],
'map_over_dim': False,
'n_input': 1,
'name': 'myFun',
'params_and_consts': ['k_x', 'c_v']}},
'Info': {'SampleTime': 0.5,
'nnodely_version': '1.5.0',
'ns': [2, 0],
'ntot': 2,
'num_parameters': 8},
'Inputs': {'x': {'dim': 1, 'ns': [2, 0], 'ntot': 2, 'tw': [-1, 0]},
'y': {'dim': 1, 'ns': [2, 0], 'ntot': 2, 'tw': [-1, 0]},
'z': {'dim': 1, 'ns': [2, 0], 'ntot': 2, 'tw': [-1, 0]}},
'Models': 'model',
'Outputs': {'out': 'Add27'},
'Parameters': {'PFir20W': {'dim': 1,
'tw': 1,
'values': [[0.10332220792770386],
[0.6755136847496033]]},
'PFir22W': {'dim': 1,
'tw': 1,
'values': [[0.3977568745613098],
[0.8827944397926331]]},
'PFir24W': {'dim': 1,
'tw': 1,
'values': [[0.7688933610916138],
[0.8726053833961487]]},
'k_x': {'dim': 1,
'tw': 1,
'values': [[0.1419960856437683],
[0.6352357268333435]]}},
'Relations': {'Add22': ['Add', ['Fir17', 'Fir21']],
'Add27': ['Add', ['Add22', 'Fir26']],
'Fir17': ['Fir', ['ParamFun16'], 'PFir20W', None, 0],
'Fir21': ['Fir', ['ParamFun20'], 'PFir22W', None, 0],
'Fir26': ['Fir', ['ParamFun25'], 'PFir24W', None, 0],
'ParamFun16': ['ParamFun', ['TimePart15'], 'FParamFun19'],
'ParamFun20': ['ParamFun', ['TimePart19'], 'FParamFun19'],
'ParamFun25': ['ParamFun', ['TimePart24'], 'FParamFun19'],
'TimePart15': ['TimePart', ['x'], -1, [-1, 0]],
'TimePart19': ['TimePart', ['y'], -1, [-1, 0]],
'TimePart24': ['TimePart', ['z'], -1, [-1, 0]]}}
================================================================================
The inputs order for the export is not specified, the order will set equal to {'z', 'x', 'y'}.
The outputs order for the export is not specified, the order will set equal to {'out'}
========================== Export Python Torch Model ===========================
Model exported in: ./results\model_onnx.py
================================================================================
======================== Export Python Onnx Torch Model ========================
Model exported in: ./results\model_onnx_onnx.py
================================================================================
============================== Export Onnx Model ===============================
Model exported in: ./results\model_onnx.onnx
================================================================================
You can also specify the input and output order inside the network
[11]:
model.exportONNX(inputs_order=['x','y','z'], outputs_order=['out'])
========================== Export Python Torch Model ===========================
Model exported in: ./results\onnx\net.py
================================================================================
======================== Export Python Onnx Torch Model ========================
Model exported in: ./results\onnx\net_onnx.py
================================================================================
============================== Export Onnx Model ===============================
Model exported in: ./results\onnx\net.onnx
================================================================================
ONNX inference
You can use a previously exported onnx model to make inference. pass the inputs and the path to the model to run a prediction process.
NOTE: All the states variables that are responsible for the recurrent loop must have an extra dimension (4 dimensions) at the beginning corresponding to the number of prediction samples.
[12]:
import numpy as np
import os
val = np.random.rand(1,2,1).astype(np.float32)
data = {'x':val, 'y':val, 'z':val}
output_onnx = Modely().onnxInference(data, name = 'net', model_folder = os.path.join(result_path, 'onnx'))
output = model({'x':val.squeeze(-1).tolist()[0], 'y':val.squeeze(-1).tolist()[0], 'z':val.squeeze(-1).tolist()[0]})
print(f'model out : {output} | onnx out : {output_onnx}')
model out : {'out': [0.5926666855812073]} | onnx out : [array([[[0.5926667]]], dtype=float32)]
Export training and validation report
Generates a PDF report with plots containing the results of the training and validation of the neural network.
[13]:
model.exportReport(name='model_report', model_folder=result_path)
======================== Export Training Results Report ========================
Report exported in: ./results\model_report.pdf
================================================================================
Example - Longitudinal dynamics of a vehicle (Non recurrent version export)
[14]:
clearNames()
vehicle = nnodely(visualizer=TextVisualizer(), seed=2, workspace='results')
# Dimensions of the layers
n = 25
na = 21
#Create neural model inputs
velocity = Input('vel')
brake = Input('brk')
gear = Input('gear')
torque = Input('trq')
altitude = Input('alt',dimensions=na)
acc = Input('acc')
# Create neural network relations
air_drag_force = Linear(b=True)(velocity.last()**2)
breaking_force = -Relu(Fir(W_init = 'init_negexp', W_init_params={'size_index':0, 'first_value':0.002, 'lambda':3})(brake.sw(n)))
gravity_force = Linear(W_init = 'init_constant', W_init_params={'value':0}, dropout=0.1, W='gravity')(altitude.last())
fuzzi_gear = Fuzzify(6, range=[2,7], functions='Rectangular')(gear.last())
local_model = LocalModel(input_function=lambda: Fir(W_init = 'init_negexp', W_init_params={'size_index':0, 'first_value':0.002, 'lambda':3}))
engine_force = local_model(torque.sw(n), fuzzi_gear)
# Create neural network output
out = Output('acc_hat', air_drag_force+breaking_force+gravity_force+engine_force)
# Add the neural model to the nnodely structure and neuralization of the model
vehicle.addModel('vehicle',[out])
vehicle.addMinimize('acc_error', acc.last(), out, loss_function='rmse')
vehicle.neuralizeModel(0.05)
## Export the Onnx Model
vehicle.exportONNX(['vel','brk','gear','trq','alt'],['acc_hat'],models='vehicle')
================================ nnodely Model =================================
{'Constants': {'Constant9': {'dim': 1, 'values': [2.0]}},
'Functions': {'FFuzzify14': {'centers': [2.0, 3.0, 4.0, 5.0, 6.0, 7.0],
'dim_out': {'dim': 6},
'functions': 'Rectangular',
'names': 'Rectangular'}},
'Info': {'SampleTime': 0.05,
'nnodely_version': '1.5.0',
'ns': [25, 0],
'ntot': 25,
'num_parameters': 198},
'Inputs': {'acc': {'dim': 1, 'ns': [1, 0], 'ntot': 1, 'sw': [-1, 0]},
'alt': {'dim': 21, 'ns': [1, 0], 'ntot': 1, 'sw': [-1, 0]},
'brk': {'dim': 1, 'ns': [25, 0], 'ntot': 25, 'sw': [-25, 0]},
'gear': {'dim': 1, 'ns': [1, 0], 'ntot': 1, 'sw': [-1, 0]},
'trq': {'dim': 1, 'ns': [25, 0], 'ntot': 25, 'sw': [-25, 0]},
'vel': {'dim': 1, 'ns': [1, 0], 'ntot': 1, 'sw': [-1, 0]}},
'Minimizers': {'acc_error': {'A': 'SamplePart73',
'B': 'Add71',
'loss': 'rmse'}},
'Models': 'vehicle',
'Outputs': {'acc_hat': 'Add71'},
'Parameters': {'PFir10W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PFir16W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PFir18W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PFir20W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PFir22W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PFir24W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PFir26W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PLinear6W': {'dim': [1, 1], 'values': [[0.38101285696029663]]},
'PLinear6b': {'dim': 1, 'values': [0.6146950721740723]},
'gravity': {'dim': [21, 1],
'init_fun': {'name': 'init_constant',
'params': {'value': 0}},
'values': [[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0]]}},
'Relations': {'Add64': ['Add', ['Mul48', 'Mul51']],
'Add65': ['Add', ['Add64', 'Mul54']],
'Add66': ['Add', ['Add65', 'Mul57']],
'Add67': ['Add', ['Add66', 'Mul60']],
'Add68': ['Add', ['Add67', 'Mul63']],
'Add69': ['Add', ['Linear32', 'Neg37']],
'Add70': ['Add', ['Add69', 'Linear40']],
'Add71': ['Add', ['Add70', 'Add68']],
'Fir35': ['Fir', ['SamplePart34'], 'PFir10W', None, 0],
'Fir46': ['Fir', ['SamplePart45'], 'PFir16W', None, 0],
'Fir49': ['Fir', ['SamplePart45'], 'PFir18W', None, 0],
'Fir52': ['Fir', ['SamplePart45'], 'PFir20W', None, 0],
'Fir55': ['Fir', ['SamplePart45'], 'PFir22W', None, 0],
'Fir58': ['Fir', ['SamplePart45'], 'PFir24W', None, 0],
'Fir61': ['Fir', ['SamplePart45'], 'PFir26W', None, 0],
'Fuzzify43': ['Fuzzify', ['SamplePart42'], 'FFuzzify14'],
'Linear32': ['Linear', ['Pow31'], 'PLinear6W', 'PLinear6b', 0],
'Linear40': ['Linear', ['SamplePart39'], 'gravity', None, 0.1],
'Mul48': ['Mul', ['Fir46', 'Select47']],
'Mul51': ['Mul', ['Fir49', 'Select50']],
'Mul54': ['Mul', ['Fir52', 'Select53']],
'Mul57': ['Mul', ['Fir55', 'Select56']],
'Mul60': ['Mul', ['Fir58', 'Select59']],
'Mul63': ['Mul', ['Fir61', 'Select62']],
'Neg37': ['Neg', ['Relu36']],
'Pow31': ['Pow', ['SamplePart29', 'Constant9']],
'Relu36': ['Relu', ['Fir35']],
'SamplePart29': ['SamplePart', ['vel'], -1, [-1, 0]],
'SamplePart34': ['SamplePart', ['brk'], -1, [-25, 0]],
'SamplePart39': ['SamplePart', ['alt'], -1, [-1, 0]],
'SamplePart42': ['SamplePart', ['gear'], -1, [-1, 0]],
'SamplePart45': ['SamplePart', ['trq'], -1, [-25, 0]],
'SamplePart73': ['SamplePart', ['acc'], -1, [-1, 0]],
'Select47': ['Select', ['Fuzzify43'], 6, 0],
'Select50': ['Select', ['Fuzzify43'], 6, 1],
'Select53': ['Select', ['Fuzzify43'], 6, 2],
'Select56': ['Select', ['Fuzzify43'], 6, 3],
'Select59': ['Select', ['Fuzzify43'], 6, 4],
'Select62': ['Select', ['Fuzzify43'], 6, 5]}}
================================================================================
========================== Export Python Torch Model ===========================
Model exported in: results\onnx\net_vehicle.py
================================================================================
======================== Export Python Onnx Torch Model ========================
Model exported in: results\onnx\net_vehicle_onnx.py
================================================================================
============================== Export Onnx Model ===============================
Model exported in: results\onnx\net_vehicle.onnx
================================================================================
Example - Longitudinal dynamics of a vehicle (Recurrent version export)
[16]:
clearNames()
vehicle = nnodely(visualizer=MPLVisualizer(),seed=2, workspace=os.path.join(os.getcwd(), 'results'))
# Dimensions of the layers
n = 25
na = 21
#Create neural model inputs
velocity = Input('vel')
brake = Input('brk')
gear = Input('gear')
torque = Input('trq')
altitude = Input('alt',dimensions=na)
acc = Input('acc')
# Create neural network relations
air_drag_force = Linear(b=True)(velocity.last()**2)
breaking_force = -Relu(Fir(W_init = 'init_negexp', W_init_params={'size_index':0, 'first_value':0.002, 'lambda':3})(brake.sw(n)))
gravity_force = Linear(W_init = 'init_constant', W_init_params={'value':0}, dropout=0.1, W='gravity')(altitude.last())
fuzzi_gear = Fuzzify(6, range=[2,7], functions='Rectangular')(gear.last())
local_model = LocalModel(input_function=lambda: Fir(W_init = 'init_negexp', W_init_params={'size_index':0, 'first_value':0.002, 'lambda':3}))
engine_force = local_model(torque.sw(n), fuzzi_gear)
acc_hat = air_drag_force+breaking_force+gravity_force+engine_force
vel_hat = acc_hat.s(-1,int_name='vel_init')
# Closing the loop
vel_hat.closedLoop(velocity)
# Create neural network output
out1 = Output('acc_hat', acc_hat)
out2 = Output('vel_hat', vel_hat)
# Add the neural model to the nnodely structure and neuralization of the model
vehicle.addModel('vehicle',[out1,out2])
vehicle.addMinimize('acc_error', acc.last(), out1, loss_function='rmse')
vehicle.neuralizeModel(0.05)
## Export the Onnx Model
vehicle.exportONNX(['brk','gear','trq','alt','vel','vel_init'],['acc_hat','vel_hat'],models='vehicle')
================================ nnodely Model =================================
{'Constants': {'Constant9': {'dim': 1, 'values': [2.0]},
'SampleTime': {'dim': 1, 'values': 0.05}},
'Functions': {'FFuzzify14': {'centers': [2.0, 3.0, 4.0, 5.0, 6.0, 7.0],
'dim_out': {'dim': 6},
'functions': 'Rectangular',
'names': 'Rectangular'}},
'Info': {'SampleTime': 0.05,
'nnodely_version': '1.5.0',
'ns': [25, 0],
'ntot': 25,
'num_parameters': 198},
'Inputs': {'acc': {'dim': 1, 'ns': [1, 0], 'ntot': 1, 'sw': [-1, 0]},
'alt': {'dim': 21, 'ns': [1, 0], 'ntot': 1, 'sw': [-1, 0]},
'brk': {'dim': 1, 'ns': [25, 0], 'ntot': 25, 'sw': [-25, 0]},
'gear': {'dim': 1, 'ns': [1, 0], 'ntot': 1, 'sw': [-1, 0]},
'trq': {'dim': 1, 'ns': [25, 0], 'ntot': 25, 'sw': [-25, 0]},
'vel': {'closedLoop': 'Add122',
'dim': 1,
'local': 1,
'ns': [1, 0],
'ntot': 1,
'sw': [-1, 0]},
'vel_init': {'closedLoop': 'Add122',
'dim': 1,
'local': 1,
'ns': [1, 0],
'ntot': 1,
'sw': [-1, 0]}},
'Minimizers': {'acc_error': {'A': 'SamplePart125',
'B': 'Add117',
'loss': 'rmse'}},
'Models': 'vehicle',
'Outputs': {'acc_hat': 'Add117', 'vel_hat': 'Add122'},
'Parameters': {'PFir10W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PFir16W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PFir18W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PFir20W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PFir22W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PFir24W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PFir26W': {'dim': 1,
'init_fun': {'name': 'init_negexp',
'params': {'first_value': 0.002,
'lambda': 3,
'size_index': 0}},
'sw': 25,
'values': [[9.957413567462936e-05],
[0.00011283227649983019],
[0.0001278557174373418],
[0.00014487950829789042],
[0.00016416999278590083],
[0.00018602897762320936],
[0.00021079844736959785],
[0.00023886593407951295],
[0.0002706705708988011],
[0.0003067099314648658],
[0.00034754787338897586],
[0.0003938233421649784],
[0.0004462603246793151],
[0.0005056791706010699],
[0.0005730096017941833],
[0.0006493049440905452],
[0.0007357588619925082],
[0.0008337240433320403],
[0.0009447330958209932],
[0.0010705228196457028],
[0.0012130612740293145],
[0.001374578569084406],
[0.0015576016157865524],
[0.0017649937653914094],
[0.0020000000949949026]]},
'PLinear6W': {'dim': [1, 1], 'values': [[0.38101285696029663]]},
'PLinear6b': {'dim': 1, 'values': [0.6146950721740723]},
'gravity': {'dim': [21, 1],
'init_fun': {'name': 'init_constant',
'params': {'value': 0}},
'values': [[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0],
[0.0]]}},
'Relations': {'Add110': ['Add', ['Mul94', 'Mul97']],
'Add111': ['Add', ['Add110', 'Mul100']],
'Add112': ['Add', ['Add111', 'Mul103']],
'Add113': ['Add', ['Add112', 'Mul106']],
'Add114': ['Add', ['Add113', 'Mul109']],
'Add115': ['Add', ['Linear78', 'Neg83']],
'Add116': ['Add', ['Add115', 'Linear86']],
'Add117': ['Add', ['Add116', 'Add114']],
'Add122': ['Add', ['SamplePart119', 'Mul121']],
'Fir101': ['Fir', ['SamplePart91'], 'PFir22W', None, 0],
'Fir104': ['Fir', ['SamplePart91'], 'PFir24W', None, 0],
'Fir107': ['Fir', ['SamplePart91'], 'PFir26W', None, 0],
'Fir81': ['Fir', ['SamplePart80'], 'PFir10W', None, 0],
'Fir92': ['Fir', ['SamplePart91'], 'PFir16W', None, 0],
'Fir95': ['Fir', ['SamplePart91'], 'PFir18W', None, 0],
'Fir98': ['Fir', ['SamplePart91'], 'PFir20W', None, 0],
'Fuzzify89': ['Fuzzify', ['SamplePart88'], 'FFuzzify14'],
'Linear78': ['Linear', ['Pow77'], 'PLinear6W', 'PLinear6b', 0],
'Linear86': ['Linear', ['SamplePart85'], 'gravity', None, 0.1],
'Mul100': ['Mul', ['Fir98', 'Select99']],
'Mul103': ['Mul', ['Fir101', 'Select102']],
'Mul106': ['Mul', ['Fir104', 'Select105']],
'Mul109': ['Mul', ['Fir107', 'Select108']],
'Mul121': ['Mul', ['Add117', 'SampleTime']],
'Mul94': ['Mul', ['Fir92', 'Select93']],
'Mul97': ['Mul', ['Fir95', 'Select96']],
'Neg83': ['Neg', ['Relu82']],
'Pow77': ['Pow', ['SamplePart75', 'Constant9']],
'Relu82': ['Relu', ['Fir81']],
'SamplePart119': ['SamplePart', ['vel_init'], -1, [-1, 0]],
'SamplePart125': ['SamplePart', ['acc'], -1, [-1, 0]],
'SamplePart75': ['SamplePart', ['vel'], -1, [-1, 0]],
'SamplePart80': ['SamplePart', ['brk'], -1, [-25, 0]],
'SamplePart85': ['SamplePart', ['alt'], -1, [-1, 0]],
'SamplePart88': ['SamplePart', ['gear'], -1, [-1, 0]],
'SamplePart91': ['SamplePart', ['trq'], -1, [-25, 0]],
'Select102': ['Select', ['Fuzzify89'], 6, 3],
'Select105': ['Select', ['Fuzzify89'], 6, 4],
'Select108': ['Select', ['Fuzzify89'], 6, 5],
'Select93': ['Select', ['Fuzzify89'], 6, 0],
'Select96': ['Select', ['Fuzzify89'], 6, 1],
'Select99': ['Select', ['Fuzzify89'], 6, 2]}}
================================================================================
========================== Export Python Torch Model ===========================
Model exported in: c:\Users\User\Desktop\VSCodeProjects\nnodely\nnodely\examples\results\onnx\net_vehicle.py
================================================================================
======================== Export Python Onnx Torch Model ========================
Model exported in: c:\Users\User\Desktop\VSCodeProjects\nnodely\nnodely\examples\results\onnx\net_vehicle_onnx.py
================================================================================
============================== Export Onnx Model ===============================
Model exported in: c:\Users\User\Desktop\VSCodeProjects\nnodely\nnodely\examples\results\onnx\net_vehicle.onnx
================================================================================
[17]:
## Make inference using the onnx model
data = {'vel_init':np.random.rand(1,1,1).astype(np.float32),'vel':np.random.rand(1,1,1).astype(np.float32), 'brk':np.random.rand(1,1,25,1).astype(np.float32), 'gear':np.random.rand(1,1,1,1).astype(np.float32), 'trq':np.random.rand(1,1,25,1).astype(np.float32), 'alt':np.random.rand(1,1,1,21).astype(np.float32)}
output_onnx = Modely().onnxInference(data,'net_vehicle','results/onnx')
output = vehicle({'vel_init':data['vel_init'].squeeze(-1).tolist()[0], 'vel':data['vel'].squeeze(-1).tolist()[0], 'brk':data['brk'].squeeze(-1).tolist()[0][0], 'gear':data['gear'].squeeze(-1).tolist()[0], 'trq':data['trq'].squeeze(-1).tolist()[0][0], 'alt':data['alt'].squeeze(1).tolist()[0]})
print(f'model out : {output} | onnx out : {output_onnx}')
model out : {'acc_hat': [0.617396891117096], 'vel_hat': [0.4668647348880768]} | onnx out : [array([[[[0.6173969]]]], dtype=float32), array([[[[0.46686473]]]], dtype=float32)]