Гайд · TNWS AI

Как обновлять accuracy и loss вместе через Flax NNX MultiMetric

Flax 0.12.10JAX 0.11.2Python#Flax#JAX#нейросети
4 мин—

Flax 0.12.10: MultiMetric объединяет Accuracy и Average, один update и словарь результатов с ручной проверкой.

Задача и применимость

Актуальный запрос: «как использовать MultiMetric Flax NNX». Обновлять accuracy и средний loss одним вызовом, сохраняя независимое состояние каждой метрики. nnx.MultiMetric принимает именованные дочерние метрики и маршрутизирует kwargs; compute возвращает словарь с теми же именами. Это уменьшает риск забыть обновить одну метрику в train/eval loop.

Материал проверен на Flax 0.12.10, JAX/jaxlib 0.11.2 и Python 3.12 на CPU. Используется актуальный API from flax import nnx, а не устаревший экспериментальный import и не Linen. Пример не загружает веса или внешние данные и решает одну изолированную задачу. Численный тест подтверждает контракт кода в указанной версии, но не качество нейросети на рабочем датасете.

Перед запуском установите совместимые версии пакетов в отдельное окружение и выведите flax.__version__, jax.__version__ и jaxlib.__version__. Не смешивайте примеры NNX с похожими по названию конструкциями Linen: у них различаются жизненный цикл Module, представление состояния, инициализация и способы применения transformations. При переносе кода сначала выберите один API и следуйте документации именно его версии.

Пошаговое решение

  1. Создайте MultiMetric с Accuracy и Average.
  2. Подготовьте logits, labels и per-example loss.
  3. Выполните один update со всеми именованными аргументами.
  4. Проверьте словарь compute вручную и затем reset.

Готовый проверяемый шаблон

import jax.numpy as jnp
from flax import nnx
metrics = nnx.MultiMetric(
    accuracy=nnx.metrics.Accuracy(),
    loss=nnx.metrics.Average(),
)
logits = jnp.array([[2., 1.], [0., 3.], [4., 1.]])
labels = jnp.array([0, 1, 1])
losses = jnp.array([0.2, 0.3, 0.4])
metrics.update(logits=logits, labels=labels, values=losses)
result = metrics.compute()
assert jnp.allclose(result["accuracy"], 2 / 3)
assert jnp.allclose(result["loss"], 0.3)
metrics.reset()
print(result)

Вход и ожидаемый результат

Один update вернул словарь с accuracy 0.6666667 и loss около 0.3. Имена полей совпали с именами дочерних метрик, что удобно для журналирования.

Как проверить результат

Проверьте kwargs, ожидаемые каждой дочерней метрикой: Accuracy использует logits/labels, Average в примере — values. Разделяйте экземпляры для train и validation или reset строго на границах фаз.

Перенос в рабочую модель

В рабочем проекте зафиксируйте контракт batch: порядок осей, dtype, диапазон признаков и семантику target. Инициализацию, dropout и генерацию данных разделяйте по именованным RNG streams. Обучаемые nnx.Param, статистическое состояние и optimizer state сохраняйте и проверяйте раздельно. Перед обновлением Flax/JAX прогоняйте небольшой обезличенный regression batch и сравнивайте формы, loss, конечность значений и допустимое численное отклонение.

Критерии приёмки

  1. Версии Flax, JAX и jaxlib записаны в отчёте.
  2. Формы входа, параметров и результата совпадают с контрактом.
  3. Все численные outputs и gradients конечны.
  4. Train/eval режим задан явно для стохастических и stateful слоёв.
  5. Результат проверен независимой формулой, состоянием или контрольным вызовом.
  6. Негативный случай неверной формы или режима включён в тесты проекта.

Регрессионный протокол

Сохраните минимальные входы: один объект, небольшой batch, нулевые значения, несимметричные размеры осей и заведомо несовместимую форму. Сравнивайте массивы через allclose с документированным допуском. Воспроизводимость требует одинаковых seeds и одинакового порядка запросов RNG. Производительность оценивайте после JIT-прогрева и block_until_ready, отдельно от compile time. Один удачный запуск не заменяет validation на независимых данных.

Диагностика расхождений

При расхождении сначала проверьте layout и preprocessing, затем RNG streams, train/eval mode, типы переменных State, forward, loss и optimizer update. Упростите модель до одного слоя, отключите JIT и стохастику, сравните промежуточные shapes. Возвращайте компоненты по одной. Не увеличивайте допуск и не заменяйте NaN нулями до установления причины.

Контроль после внедрения

В эксплуатации ограничьте допустимые shapes и размер batch, чтобы запрос не исчерпал память и не вызвал поток перекомпиляций. Не логируйте исходные пользовательские тензоры, ключи и содержимое обучающих примеров. Храните предыдущий проверенный checkpoint и схему State для отката. После восстановления проверяйте контрольный forward до включения модели в трафик.

Границы применимости

CPU-проверка не доказывает скорость или точную численную идентичность GPU/TPU. Случайная инициализация не является обучением, снижение train loss не гарантирует обобщение, а правильная форма не подтверждает корректность данных. Для важных решений нужны validation/test, мониторинг дрейфа, ограничения входов и человеческий контроль.

Типичные ошибки и чего не делать

  • Не передавать один scalar batch mean, если нужен per-example weighted mean.
  • Не смешивать состояния train и validation.
  • Не предполагать, что отсутствующий kwarg будет восстановлен автоматически.

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

FAQ

Что возвращает compute?

Словарь результатов по именам дочерних метрик.

Один ли reset нужен?

MultiMetric сбрасывает дочерние метрики.

Можно добавить другие метрики?

Да, совместимые Metric-объекты под уникальными именами.

Официальные источники

Частые вопросы

Что возвращает compute?

Словарь результатов по именам дочерних метрик.

Один ли reset нужен?

MultiMetric сбрасывает дочерние метрики.

Можно добавить другие метрики?

Да, совместимые Metric-объекты под уникальными именами.

Читайте также

Комментарии

Пока тихо. Скажите первое слово