Функциональный API: входы, выходы, ветвления

Функциональный API предоставляет гибкий способ построения нейронных сетей, позволяя определять сложные архитектуры с несколькими входами, выходами и разветвлениями. В отличие от последовательного (Sequential) подхода, здесь модель строится как граф, где слои соединяются через тензоры, а не линейно.

Входные тензоры

Для создания входа используется объект Input. Основные параметры:

  • shape — форма одного входного примера без учета размерности пакета (batch size).
  • name — необязательное имя для слоя, полезное при работе с несколькими входами.

Пример:

const { Input } = require('keras-js');

const inputA = new Input({ shape: [64], name: 'inputA' });
const inputB = new Input({ shape: [32], name: 'inputB' });

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

Соединение слоев

Каждый слой можно вызвать как функцию над тензором:

const { Dense } = require('keras-js');

const denseA = new Dense({ units: 128, activation: 'relu' }).apply(inputA);
const denseB = new Dense({ units: 64, activation: 'relu' }).apply(inputB);

apply() создает новый тензор, представляющий выход слоя, который можно использовать дальше.

Ветвления и объединения

Функциональный API позволяет строить сложные графы, объединяя несколько ветвей:

  • Concatenate — объединяет тензоры по указанной оси.
  • Add / Multiply / Subtract — выполняют арифметические операции над тензорами.
  • Merge — общий интерфейс для всех операций слияния.

Пример объединения ветвей:

const { Concatenate } = require('keras-js');

const merged = new Concatenate().apply([denseA, denseB]);

После объединения можно добавить последующие слои:

const output = new Dense({ units: 10, activation: 'softmax' }).apply(merged);

Множественные выходы

Функциональный API поддерживает модели с несколькими выходами. Для этого просто определяются несколько тензоров-выходов:

const output1 = new Dense({ units: 5, activation: 'softmax', name: 'out1' }).apply(merged);
const output2 = new Dense({ units: 1, activation: 'sigmoid', name: 'out2' }).apply(denseB);

Создание модели

Модель создается с указанием входов и выходов:

const { Model } = require('keras-js');

const model = new Model({
  inputs: [inputA, inputB],
  outputs: [output1, output2]
});

Такое определение позволяет Keras.js корректно вычислять граф и выполнять обратное распространение ошибки для всех ветвей.

Использование модели

После создания модель можно компилировать и использовать для прогнозирования:

model.compile({
  optimizer: 'adam',
  loss: { out1: 'categoricalCrossentropy', out2: 'binaryCrossentropy' },
  metrics: ['accuracy']
});

const xA = ...; // данные для inputA
const xB = ...; // данные для inputB

const yPred = model.predict([xA, xB]);

Функциональный API позволяет:

  • Легко строить сети с ветвлениями и составными входами/выходами.
  • Повторно использовать слои в разных частях графа.
  • Выполнять сложные операции слияния и трансформации тензоров.

Советы по организации графа

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

Функциональный API превращает построение нейронных сетей в работу с графами данных, где каждый слой является узлом, а тензоры — рёбрами, соединяющими эти узлы. Такой подход открывает возможности для создания архитектур, которые невозможно реализовать последовательно.