Skip to content

Onnx tuto

Cyril Moineau requested to merge ONNXTuto into main

This branch contains change to create an ONNX tutorial

  • Update Connector to allow the creation of incomplete graph (aka. with no producers at root)
  • Add binding of MetaOperator
  • Add indentity cell as a workaround to specify one input to a metaoperator.
  • Use of args for the declaration of graph with connecotr instead of using vector, allow this sythax: y = div_op(x, add_op(pow_op(e, mul_op(x, b)), o)) instead of y = div_op([x, add_op([pow_op([e, mul_op([x, b])]), o])])

This MR allow to create MetaOperator for the swish activation:

import aidge_core
import aidge_backend_cpu
import numpy as np

from math import exp

NB_CHAN = 10

e_prod = aidge_core.Producer(aidge_core.Tensor(np.array([exp(1)]*NB_CHAN, dtype=np.float32)), "exp")
one_prod = aidge_core.Producer(aidge_core.Tensor(np.array([1]*NB_CHAN, dtype=np.float32)), "one")
beta = 0.1
beta_prod = aidge_core.Producer(aidge_core.Tensor(np.array([-beta]*NB_CHAN, dtype=np.float32)), "beta")

mul_op = aidge_core.Mul(name="MUL")
pow_op = aidge_core.Pow(name="POW")
add_op = aidge_core.Add(name="ADD")
div_op = aidge_core.Div(name="DIV")
input_op = aidge_core.Identity("Input")


x = aidge_core.Connector(input_op)
b = aidge_core.Connector(beta_prod)
e = aidge_core.Connector(e_prod)
o = aidge_core.Connector(one_prod)

y = div_op(x, add_op(pow_op(e, mul_op(x, b)), o))
swish_micro_graph = aidge_core.generate_graph([y])

swish_op = aidge_core.meta_operator(
    "Swish",
    swish_micro_graph,
    "Swish_Op",
    input_nodes  = [input_op],
    output_nodes = [div_op],
)

swish = aidge_core.sequential([swish_op])


swish.save("swish")

data_input = aidge_core.Producer(aidge_core.Tensor(np.arange(NB_CHAN, dtype=np.float32)+1.0), "data")

data_input.add_child(swish)

data_input.get_operator().set_datatype(aidge_core.DataType.Float32)

data_input.get_operator().set_backend("cpu")

swish.set_datatype(aidge_core.DataType.Float32)
swish.set_backend("cpu")


# Create SCHEDULER
scheduler = aidge_core.SequentialScheduler(swish)

# Run inference !
scheduler.forward(verbose=True)

for outNode in swish.get_nodes():
    output_aidge = np.array(outNode.get_operator().output(0))
    print(outNode.name())
    print(output_aidge)

x = np.arange(NB_CHAN, dtype=np.float32)+1.0

print(x / (1. + np.exp(-beta*x)))

Output:

run: Swish_94105819020080
[##################################################] 100% |                                    

Swish_Op
[0.5249792 1.0996679 1.7233275 2.3947506 3.1122966 3.8739378 4.6773143
 5.519796  6.3985453 7.310586 ]
[0.5249792 1.099668  1.7233275 2.3947506 3.1122966 3.8739378 4.6773148
 5.519796  6.3985453 7.310586 ]

Micro graph of the swish op:

%%{init: {'flowchart': { 'curve': 'monotoneY'}, 'fontFamily': 'Verdana' } }%%
flowchart TB

Producer_1(beta)
Producer_2(one)
Div_1(DIV)
Add_1(ADD)
Identity_1(Input)
Producer_3(exp)
Pow_1(POW)
Mul_1(MUL)
Identity_1-->Div_1
Add_1-->Div_1
Pow_1-->Add_1
Producer_2-->Add_1
input0((in - 0))-->Identity_1
Producer_3-->Pow_1
Mul_1-->Pow_1
Identity_1-->Mul_1
Producer_1-->Mul_1
Edited by Cyril Moineau

Merge request reports

Loading