Engee documentation
Notebook

Let's put the neural network in the Engee Function block

In this example, we will place a trained neural network on the Engee canvas as a block. Engee Function – we will generate code for Julia from it.

Task description

Previously, we trained a fully connected neural network to predict the value of based on two input variables: and . We already have the file. model.jld2, where the trained neural network is located. Now we will translate it into Julia code and create a block that can be used in any model or make our own library out of such blocks.

⚠️ Inside the block Engee Function you can only use global addressing. Therefore, if your example is located in a folder other than /user/start/data_analysis/neural_regression_to_engee_function, you need to edit the code inside the block Engee Function by specifying the full path to the file neural_net_code.jl.

Creating a block mask

It would be convenient to place some drawing on the front side of the block, which may simplify the perception of the model. We use the topology of our neural network as a mask.

image.png

We'll need a library. ChainPlots, which creates a "recipe" for neural network visualization for the function plot() after that, we can simply pass the neural network as an argument to the graph output function.

In [ ]:
Pkg.add(["JLD2", "Flux", "ChainPlots", "Symbolics"])
In [ ]:
using Flux, JLD2, ChainPlots

model = load_object( "$(@__DIR__)/model.jld2" ) # Загрузим нейросеть из файла

gr()
p = plot( model, titlefontsize=10, size=(300,300),
    xticks=:none, series_annotations="", markersize=8,
    markercolor="white", markerstrokewidth=4, linewidth=1 )

savefig( p, "$(@__DIR__)/neural_net_block_mask.png"); # Сохраним график в PNG

The link to the image is already written in the block mask. But the mask won't update automatically. To upload the illustration to the front of the block, open its properties (in mask view mode) and click "Update Mask".

Creating Julia code for a neural network

One feature of the Julia language will help us create the code.

Because the library Flux it is entirely written in Julia, each layer of the neural network is described by Julia code. What happens if the input is not numbers, but mathematical symbols from the library? Symbolics?

In [ ]:
using Symbolics
@variables x1 x2
s = model( [x1, x2] );

# Первые 200 символов этого кода
print( string(s[1])[1:200], "..." )
2.474068ifelse((0.98925877 + 0.38023216ifelse((1.1855042 + 0.8189067x1 - 0.93786836x2) < 0, 0, 1.1855042 + 0.8189067x1 - 0.93786836x2) + 1.3171272ifelse((1.784764x1 - 0.027649183 - 1.0800585x2) < 0, 0...

We see a lot ifelse.. Indeed, a neural network with ReLU activation can be rewritten as a large piecewise linear function.

Save the code to a file.jl

If we put the code in a text file, then it can be included in the block. Engee Function through the command include(), **but only at the absolute address **. However, you will always need to store this code file in the folder with the model. There is another way to put the code and mask inside the block. Engee Function and make the component self-sufficient.

In [ ]:
open("$(@__DIR__)/neural_net_code.jl", "w") do f
    println(f, "function nn(x1, x2)\n    $(s[1])\nend")
end

# Сразу же запустим этот код и получим прогноз нейросети:
include("$(@__DIR__)/neural_net_code.jl")
nn(1,2)
Out[0]:
2.5977383718979077

Verification: launching a neural network from the Engee Function block

Let's run the model and visualize the results.

In [ ]:
# Загрузим (если модель еще не открыта) и выполним модель
if "neural_regression_to_engee_function"  getfield.(engee.get_all_models(), :name)
    engee.load( "$(@__DIR__)/neural_regression_to_engee_function.engee");
end
model_data = engee.run( "neural_regression_to_engee_function" );

# Подготовим выходные переменные
model_x1 = model_data["X1"].value;
model_x2 = model_data["X2"].value;
model_y = vec( hcat( model_data["Y"].value... ));

# Построим график
scatter!( model_x1, model_x2, model_y, ms=2.5, msw=.5, leg=false, zcolor=model_y, c=:viridis,
         xlimits=(-3,3), ylimits=(-3,3), title="Прогноз от блока Engee Function", titlefont=font(10) )
Out[0]:

We see a familiar function, but each output point is "predicted" by a neural network that has learned to model the dependence we need. .

Conclusion

Using the library Symbolics It's not difficult to generate code from the Julia function, even if this function is a neural network from the library. Flux. It remains to choose a convenient way to place the code on the canvas, and you can use the neural network as a component in a model-oriented project.

Blocks used in example