Engee 文档
Notebook

#让我们把神经网络放在Engee功能块中

在这个例子中,我们将在Engee画布上放置一个训练好的神经网络作为一个块。 Engee Function –我们将从中为Julia生成代码。

任务说明

以前,我们训练了一个完全连接的神经网络来预测 基于两个输入变量: . 我们已经拿到文件了。 model.jld2,训练好的神经网络所在的位置。 现在我们将把它翻译成Julia代码,并创建一个可以在任何模型中使用的块,或者用这些块创建我们自己的库。

在街区内 Engee Function 您只能使用全局寻址。 因此,如果您的示例位于除 /user/start/data_analysis/neural_regression_to_engee_function,您需要编辑块内的代码 Engee Function 通过指定文件的完整路径 neural_net_code.jl.

创建块掩码

在块的前侧放置一些绘图会很方便,这可能会简化模型的感知。 我们使用我们的神经网络的拓扑作为掩码。

image.png

我们需要一个图书馆。 ChainPlots,这为函数创建了神经网络可视化的"配方" plot() 之后,我们可以简单地将神经网络作为参数传递给图输出函数。

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

到图像的链接已经写入块掩码中。 **但面具不会自动更新。**要将插图上传到块的前面,请打开其属性(在蒙版视图模式下),然后单击"更新蒙版"。

为神经网络创建Julia代码

Julia语言的一个特性将帮助我们创建代码。

因为图书馆 Flux 它完全是用Julia编写的,神经网络的每一层都由Julia代码描述。 如果输入不是数字,而是来自库的数学符号会发生什么? 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...

我们看到了很多 ifelse.. 实际上,具有ReLU激活的神经网络可以重写为大型分段线性函数。

将代码保存到文件中。jl

如果我们将代码放在文本文件中,那么它可以包含在块中。 Engee Function 通过命令 include()但仅在绝对地址。 但是,您始终需要将此代码文件与模型一起存储在文件夹中。 还有另一种方法可以将代码和掩码放在块内。 Engee Function 而使组件自给自足。

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

验证:从Engee功能块启动神经网络

让我们运行模型并可视化结果。

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]:

我们看到一个熟悉的函数,但每个输出点都由神经网络"预测",该神经网络已经学会了对我们需要的依赖性进行建模。 .

结论

使用图书馆 Symbolics 从Julia函数生成代码并不困难,即使这个函数是来自库的神经网络。 Flux. 仍然需要选择一种方便的方式将代码放置在画布上,并且您可以将神经网络用作面向模型的项目中的组件。

示例中使用的块