Keras: что это за библиотека и как собрать первую нейросеть

Keras: что это за библиотека и как собрать первую нейросеть Полезное

Keras — это высокоуровневая библиотека Python для построения и обучения нейронных сетей: модель собирается из готовых слоев, а вычисления выполняет отдельный движок (бэкенд). В актуальной линейке Keras 3 бэкендом может быть JAX, TensorFlow или PyTorch — один и тот же код модели запускается на любом из них. Ниже — как устроен Keras, чем Sequential отличается от Functional API и полный пример от данных до сохраненной модели.

Примеры проверены 23 сентября 2026 года: Keras 3.15.1, Python 3.12, бэкенды JAX 0.11 и PyTorch 2.14 (оба на CPU), первый пример — еще и на TensorFlow 2.21.

Keras, бэкенд и tf.keras: три термина, которые путают

  • Keras — интерфейс: слои, модели, функции потерь, оптимизаторы, цикл обучения fit(). Сам Keras тензоры не перемножает.
  • Бэкенд — библиотека, которая выполняет вычисления и считает градиенты: JAX, TensorFlow или PyTorch (в новых версиях есть еще OpenVINO, но только для инференса, без обучения). Выбирается переменной окружения KERAS_BACKEND до импорта Keras.
  • tf.keras — Keras, встроенный в TensorFlow. В TensorFlow 2.16 и новее tf.keras по умолчанию указывает на Keras 3; старые учебники с from tensorflow import keras в основном работают, но часть API из Keras 2 удалена (пример ниже). Если старый проект нужно запустить без переписывания, TensorFlow оставляет Keras 2 отдельным пакетом tf_keras с переменной TF_USE_LEGACY_KERAS=1.

Коротко об истории: Keras создал Франсуа Шолле, первая версия вышла в марте 2015 года как личный проект; вскоре автор перешел в Google и почти десять лет развивал Keras там (в конце 2024 года он ушел из компании, проект остался открытым). Ранний Keras умел работать поверх Theano, TensorFlow и CNTK, затем на несколько лет стал частью TensorFlow, а в Keras 3 (конец 2023 года) снова получил несколько бэкендов. Поэтому фраза из старых статей «Keras поддерживает только TensorFlow» для текущей версии неверна.

Бэкенд Когда выбирают Что учесть
JAX исследования, быстрые вычисления с компиляцией XLA GPU-сборку JAX ставят отдельно от CPU-версии
TensorFlow нужен экосистемный деплой: TF Serving, LiteRT (бывший TensorFlow Lite) тяжелая установка, поддержка версий Python отстает
PyTorch команда уже пишет на PyTorch, нужно смешивать с его кодом модель Keras — это одновременно torch.nn.Module

Граница: «один код на любом бэкенде» верно для моделей из стандартных слоев Keras. Если внутри модели вызвать функции конкретного движка (например, tf.image или torch.fft), переносимость пропадает — для переносимого кода есть keras.ops.

Установка и выбор бэкенда

Keras ставится одной командой, бэкенд — отдельно. Нужен свежий Python: Keras 3.15 требует Python 3.11+, JAX 0.11 — 3.12+ (на более старом интерпретаторе pip молча поставит старые версии). Минимальный вариант на CPU:

python3 -m venv .venv
source .venv/bin/activate
pip install keras jax
export KERAS_BACKEND=jax

Если бэкенд не задан, Keras 3 берет его из файла ~/.keras/keras.json, а по умолчанию это tensorflow. Типовая ошибка новичка — поставить keras и jax, но забыть переменную:

python3 -c "import keras"
ModuleNotFoundError: No module named 'tensorflow'

Исправление — задать KERAS_BACKEND=jax (или torch) в окружении либо в коде строкой os.environ["KERAS_BACKEND"] = "jax" до import keras. После импорта бэкенд меняют через keras.config.set_backend("torch") с повторным импортом Keras, но все уже созданные модели, слои и тензоры после этого непригодны; на практике проще перезапустить процесс.

Первая модель на Sequential: полный пример

Задача — научить сеть отличать точки внутри круга радиуса 1 от точек снаружи. Данные генерируются в коде, поэтому пример работает без интернета и скачивания датасетов.

import os
os.environ.setdefault("KERAS_BACKEND", "jax")  # до import keras

import numpy as np
import keras
from keras import layers

keras.utils.set_random_seed(42)

# Данные: точки на плоскости, класс 1 - внутри круга радиуса 1
rng = np.random.default_rng(0)
x = rng.uniform(-2, 2, size=(2000, 2)).astype("float32")
y = (np.sum(x**2, axis=1) < 1.0).astype("float32")
x_train, y_train = x[:1600], y[:1600]
x_test, y_test = x[1600:], y[1600:]

model = keras.Sequential([
    keras.Input(shape=(2,)),
    layers.Dense(16, activation="relu"),
    layers.Dense(16, activation="relu"),
    layers.Dense(1, activation="sigmoid"),
])

model.compile(optimizer="adam",
              loss="binary_crossentropy",
              metrics=["accuracy"])

model.fit(x_train, y_train, epochs=30, batch_size=32,
          validation_split=0.2, verbose=0)

loss, acc = model.evaluate(x_test, y_test, verbose=0)
print("backend:", keras.backend.backend())
print(f"test accuracy: {acc:.3f}")

probe = np.array([[0.0, 0.0], [1.8, 1.8]], dtype="float32")
proba = model.predict(probe, verbose=0)
print("P(внутри круга):", proba.ravel().round(3))
print("классы:", (proba.ravel() > 0.5).astype(int))

Вывод на бэкенде JAX:

backend: jax
test accuracy: 0.995
P(внутри круга): [0.937 0.   ]
классы: [1 0]

Точность на отложенных 400 точках — около 99%, центр круга сеть уверенно относит к классу 1, дальний угол — к классу 0. На других бэкендах цифры немного отличаются при том же сиде: у PyTorch вышло 0.995 и вероятность 0.977, у TensorFlow — 0.993 и 0.981. Это нормально: у движков разные генераторы случайных чисел и порядок вычислений.

Что делает каждый шаг

  1. keras.Input(shape=(2,)) — форма одного примера: два числа (x и y). Размер пакета не указывают.
  2. Dense(16, activation="relu") — полносвязный слой из 16 нейронов. Нелинейность дает функция активации relu: без нее любая стопка Dense-слоев сводится к одной линейной функции, и границу круга сеть не выучит.
  3. Dense(1, activation="sigmoid") — один выход со значением от 0 до 1, его читают как вероятность класса 1.
  4. compile() связывает модель с оптимизатором (adam), функцией потерь (binary_crossentropy — для двух классов) и метриками. Сам compile() ничего не обучает.
  5. fit() — обучение: 30 проходов по данным (эпох) пакетами по 32 примера, 20% обучающих данных уходит на валидацию.
  6. evaluate() считает потерю и метрики на тестовых данных, predict() возвращает вероятности, а не классы.

Правило выбора функции потерь: два класса и один выход с sigmoid — binary_crossentropy; несколько классов и выход softmax — sparse_categorical_crossentropy, если метки — целые числа, или categorical_crossentropy, если метки закодированы one-hot.

Functional API: когда Sequential мало

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

Та же задача, но исходные координаты дополнительно подаются прямо на выходной слой (ветка-обход), и модель сохраняется в файл:

import os
os.environ.setdefault("KERAS_BACKEND", "jax")

import numpy as np
import keras
from keras import layers

keras.utils.set_random_seed(42)
rng = np.random.default_rng(0)
x = rng.uniform(-2, 2, size=(2000, 2)).astype("float32")
y = (np.sum(x**2, axis=1) < 1.0).astype("float32")

inputs = keras.Input(shape=(2,), name="xy")
h = layers.Dense(16, activation="relu")(inputs)
h = layers.Dense(16, activation="relu")(h)
# Ветка-обход: исходные координаты идут прямо к выходу
merged = layers.Concatenate()([h, inputs])
outputs = layers.Dense(1, activation="sigmoid")(merged)

model = keras.Model(inputs=inputs, outputs=outputs, name="circle")
model.compile(optimizer="adam", loss="binary_crossentropy",
              metrics=["accuracy"])
model.fit(x[:1600], y[:1600], epochs=30, batch_size=32, verbose=0)
print("params:", model.count_params())

model.save("circle.keras")
restored = keras.saving.load_model("circle.keras")
probe = np.array([[0.0, 0.0]], dtype="float32")
same = np.allclose(model.predict(probe, verbose=0),
                   restored.predict(probe, verbose=0))
print("после загрузки прогноз совпал:", same)
params: 339
после загрузки прогноз совпал: True

Число параметров легко проверить руками: первый слой 2×16 весов + 16 смещений = 48, второй 16×16 + 16 = 272, выходной получает 16 + 2 = 18 входов, то есть 18 весов + 1 смещение = 19. Итого 339. У Sequential-версии выход получает только 16 входов, там 337 параметров.

Критерий Sequential Functional API Подкласс keras.Model
Топология только цепочка любой граф слоев любая, логика в call()
Несколько входов/выходов нет да да
summary() и схема до обучения да да ограниченно
С чего начинать первая модель ветвления, общие слои нестандартный прямой проход

Сохранение модели и безопасность загрузки

В Keras 3 основной формат — один файл .keras (архитектура, веса и состояние оптимизатора). Вызов model.save("my_model") без расширения теперь падает:

ValueError: Invalid filepath extension for saving. Please add either a `.keras` extension for the native Keras format (recommended) or a `.h5` extension. Use `model.export(filepath)` if you want to export a SavedModel for use with TFLite/TFServing/etc. Received: filepath=my_model.

Формат .h5 оставлен для совместимости со старым кодом, для экспорта в TF Serving, LiteRT, ONNX или OpenVINO есть отдельный model.export() (формат задают аргументом format, для SavedModel нужен установленный TensorFlow).

Файл модели — это исполняемая логика, а не просто числа. По умолчанию load_model() работает с safe_mode=True и отказывается восстанавливать произвольный Python-код из Lambda-слоев. Отключать этот режим можно только для своих файлов. Модели из непроверенных источников не загружайте вовсе: safe_mode снижает риск, но не делает чужой файл доверенным.

Код из старых учебников: что сломается в Keras 3

Статьи 2018-2021 годов часто показывают классификатор MNIST с вызовами, которых в Keras 3 уже нет. Проверено на 3.15.1:

Старый код Что происходит в Keras 3 Замена
from keras.utils import np_utils ImportError: cannot import name 'np_utils' from keras.utils import to_categorical
model.predict_classes(x) AttributeError: 'Sequential' object has no attribute 'predict_classes' model.predict(x) > 0.5 для двух классов, argmax(axis=1) для многих
model.save("dir") ValueError (нужно расширение) model.save("model.keras")
import tensorflow.keras без TensorFlow нужен установленный TensorFlow import keras + выбор бэкенда

Если не получилось

  • ModuleNotFoundError: No module named 'tensorflow' при import keras — не задан бэкенд, а TensorFlow не установлен. Задайте KERAS_BACKEND до импорта.
  • Точность не растет от эпохи к эпохе — проверьте, что последний слой и функция потерь согласованы (sigmoid + binary_crossentropy), а метки имеют значения 0 и 1, а не 1 и 2.
  • ValueError: ... expected axis -1 of input shape to have value 2, but received input with shape (4, 3) — форма в keras.Input не совпадает с данными: у x должно быть ровно два столбца.
  • Результаты немного меняются между запусками — без keras.utils.set_random_seed() веса инициализируются случайно; на GPU часть операций недетерминирована даже с сидом.

Выводы

  • Keras — это интерфейс для сборки и обучения нейросетей, а вычисления выполняет бэкенд: в Keras 3 это JAX, TensorFlow или PyTorch.
  • Бэкенд задают KERAS_BACKEND до импорта; по умолчанию Keras ищет TensorFlow.
  • Цепочку слоев собирают через Sequential, ветвления и несколько входов — через Functional API.
  • Рабочий цикл один на все модели: compile() -> fit() -> evaluate() -> predict() -> save("*.keras").
  • Код из старых учебников (np_utils, predict_classes) в Keras 3 не работает — замены показаны в таблице выше.

Где применяется / связь с практикой

Освойте тему на практике

Keras используют там, где нужно быстро проверить гипотезу на нейросети: классификация изображений и текстов, прогноз временных рядов, рекомендательные признаки. Но библиотека — только последний шаг: до нее идут подготовка данных, выбор метрики и понимание, почему модель ошибается. Эту базу — Python для анализа данных, классические алгоритмы и первые нейросети — системно разбирают на курсе «Machine Learning. Basic».

Освойте тему на практике

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

FAQ

Нужна ли видеокарта, чтобы начать с Keras?
Нет. Учебные модели вроде примеров выше обучаются на CPU за секунды. GPU нужен для больших сетей и изображений; для этого ставят GPU-сборку выбранного бэкенда.

Что выбрать для новой работы: Keras или «чистый» PyTorch?
Keras быстрее дает рабочую модель со стандартными слоями и циклом fit(). Если нужен полностью свой цикл обучения и глубокая интеграция с экосистемой PyTorch, пишут на PyTorch напрямую; Keras 3 позволяет совмещать оба подхода на бэкенде torch.

Можно ли открыть в Keras 3 модель, сохраненную в Keras 2?
Файлы .h5 и .keras из поздних версий Keras 2 обычно загружаются; старый формат SavedModel (папка) через load_model() не открывается, для него есть обертка keras.layers.TFSMLayer только для инференса.

OTUS Журнал