Документация Engee
Notebook

Нейронные сети Python и их интеграция с моделями Engee

В данной демонстрации мы рассмотрим пример обучения нейронных сети с помощью пакета sklearn.

Для работы с нейронными сетями с помощью Python в Engee используется пакет PyCall и команды вызова Python в Engee.

Для начала установим библиотеки sklearn и PyPlot в Engee.

In [ ]:
# Pkg.add("ScikitLearn")
Pkg.add("PyPlot")

using PyPlot

# Импорт необходимых модулей из Python
@pyimport sklearn.neural_network as nn
@pyimport sklearn.tree as tree
@pyimport numpy as np
   Resolving package versions...
  No Changes to `~/.project/Project.toml`
  No Changes to `~/.project/Manifest.toml`

Генерация данных для обучения из модели в Engee

Данная модель генерирует вектор из двух значений синусоид, которые для классификатора представляют единый сигнал. На основе определения амплитудного колебания выходного сигнала устанавливаются метки класса. На рисунке ниже продемонстрирован верхний уровень модели.

image_2.png

На рисунке ниже можно увидеть процесс формирования данных.

image_2.png

Далее показано формирование метки класса по трём диапазонам:

  1. меньше -0.7;
  2. больше -0.7 и меньше 0.7;
  3. больше 0.7.

image.png

Перейдём к генерации данных, для чего подключим вспомогательную функцию запуска модели, запустим модель и посмотрим на то, какие данные были залогированы в simout.

In [ ]:
 function run_model(name_model)
    Path = (@__DIR__) * "/" * name_model * ".engee"

    if name_model in [m.name for m in engee.get_all_models()] # Проверка условия загрузки модели в ядро
        model = engee.open( name_model ) # Открыть модель
        model_output = engee.run( model, verbose=true ); # Запустить модель
    else
        model = engee.load( Path, force=true ) # Загрузить модель
        model_output = engee.run( model, verbose=true ); # Запустить модель
        engee.close( name_model, force=true ); # Закрыть модель
    end

    return model_output
end

run_model("PyDataGen")
sleep(1)
collect(simout)
Building...
Progress 0%
Progress 100%
Progress 100%
Out[0]:
2-element Vector{WorkspaceArray}:
 WorkspaceArray{Int64}("PyDataGen/target")
 WorkspaceArray{Vector{Float64}}("PyDataGen/Data")

Далее выполним выгрузку данных из simout и приведём их к формату numpy для дальнейшей подачи их в нейронные сети Python.

In [ ]:
target = simout["PyDataGen/target"];
target = collect(target);
target = np.array(target.value); 

Data = simout["PyDataGen/Data"];
Data = collect(Data);
Data = np.array(Data.value); 

Многослойный персептрон

Первая сеть – классификатор, которую мы рассмотрим в данной демонстрации, – это сеть многослойного персептрона для предсказания принадлежности к группе данных по амплитуде колебания.

Многослойный персептрон (MLP) – это модель искусственной нейронной сети с прямой связью, которая сопоставляет наборы входных данных с набором соответствующих выходных данных. MLP состоит из нескольких уровней, каждый из которых полностью связан со следующим. Узлами слоев являются нейроны с нелинейными функциями активации, кроме узлов входного слоя. Между входным и выходным слоем может быть один или несколько нелинейных скрытых слоев.

На рисунке ниже показан MLP с одним скрытым слоем со скалярным выходом.

image.png

Перейдём к инициализации и обучению нейронной сети в Python. Для настройки MLP имеются несколько параметров:

  1. hidden_layer_sizes – размер скрытого слоя;
  2. max_iter – максимально допустимое количество итераций обучения;
  3. alpha – шаг обучения;
  4. solver – решатель, который определяет алгоритм оптимизации весов по узлам;
  5. verbose – указание, выводить ли дополнительную информацию;
  6. random_state – настройка для управления случайными значениями;
  7. learning_rate_init – скорость обучения.
In [ ]:
clf = nn.MLPClassifier(hidden_layer_sizes=(100,), max_iter=10, alpha=1e-4, solver="sgd", verbose=1, random_state=1, learning_rate_init=.1)
clf[:fit](Data, target)
/home/engee/micromamba/lib/python3.11/site-packages/sklearn/neural_network/_multilayer_perceptron.py:691: ConvergenceWarning: Stochastic Optimizer: Maximum iterations (10) reached and the optimization hasn't converged yet.
  warnings.warn(
Out[0]:
MLPClassifier(learning_rate_init=0.1, max_iter=10, random_state=1, solver='sgd',
              verbose=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.

Как мы видим из предупреждения, было достигнуто максимальное количество итераций, а оптимизация не сошлась. Следовательно, необходимо увеличить количество итераций. Повторим инициализацию и обучение нейронной сети в Python с новыми параметрами сети.

In [ ]:
clf = nn.MLPClassifier(hidden_layer_sizes=(100,), max_iter=140, alpha=1e-4, solver="sgd", verbose=1, random_state=1, learning_rate_init=.1)
clf[:fit](Data, target)
Out[0]:
MLPClassifier(learning_rate_init=0.1, max_iter=140, random_state=1,
              solver='sgd', verbose=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.

Теперь выполним оценку качества модели. Как мы видим, нейронная сеть имеет высокую точность угадывания.

In [ ]:
accuracy = clf[:score](Data, target)
println("Точность: $accuracy")
Точность: 0.995004995004995

Дерево решений

Рассмотрим пример кода для обучения нейронной сети со структурой дерева решений (decision tree). Это непараметрический метод обучения с учителем, используемый для классификации и регрессии.

В рамках этого метода требуется создать модель, которая прогнозирует значение целевой переменной, изучая простые правила принятия решений, выведенные из особенностей данных.

Дерево можно рассматривать как кусочно-постоянную аппроксимацию. Начнём с объявления и обучения дерева решений.

In [ ]:
dt_clf = tree.DecisionTreeClassifier()
dt_clf.fit(Data, target)
Out[0]:
DecisionTreeClassifier()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.

Построим график дерева решений и увеличим размер и плотность пикселей, чтобы сделать график более наглядным.

In [ ]:
plt.figure(figsize=(13, 4), dpi=200)
tree.plot_tree(dt_clf, filled=true)
No description has been provided for this image
Out[0]:
7-element Vector{PyObject}:
 PyObject Text(0.6, 0.8333333333333334, 'x[1] <= 0.351\ngini = 0.573\nsamples = 1001\nvalue = [462, 83, 456]')
 PyObject Text(0.4, 0.5, 'x[0] <= -0.35\ngini = 0.261\nsamples = 539\nvalue = [0, 83, 456]')
 PyObject Text(0.5, 0.6666666666666667, 'True  ')
 PyObject Text(0.2, 0.16666666666666666, 'gini = 0.0\nsamples = 456\nvalue = [0, 0, 456]')
 PyObject Text(0.6, 0.16666666666666666, 'gini = 0.0\nsamples = 83\nvalue = [0, 83, 0]')
 PyObject Text(0.8, 0.5, 'gini = 0.0\nsamples = 462\nvalue = [462, 0, 0]')
 PyObject Text(0.7, 0.6666666666666667, '  False')

Создадим новый график для вывод результата нейронной сети.

In [ ]:
plt.figure(figsize=(18, 6), dpi=80)  # увеличим размер и плотность пикселей
plt.scatter(Data[:, 1], Data[:, 2], c=target, cmap=plt.cm.Paired, edgecolors="k")
plt.title("Neural Network")
No description has been provided for this image
Out[0]:
PyObject Text(0.5, 1.0, 'Neural Network')

Как мы видим из результирующего графика, все сгенерированные нами значения были на основе суммы входных данных распределены на три отдельные группы.

Вывод

Мы на конкретных примерах показали опции интеграции нейронных сетей в Engee, а также возможности объединения модельно-орентированного проектирования и функциональности Python.