В Keras.js пользовательские функции потерь позволяют задавать
собственные критерии оценки ошибок модели при обучении, выходя за
пределы стандартного набора mean_squared_error,
categorical_crossentropy и других встроенных функций. Это
особенно важно при работе с нестандартными задачами, где стандартные
метрики не отражают специфику ошибки, или при экспериментах с новыми
подходами к оптимизации.
В Keras.js функции потерь задаются как функции JavaScript с двумя обязательными аргументами:
function customLoss(yTrue, yPred) {
// yTrue — ожидаемые значения (targets)
// yPred — предсказанные значения (predictions)
return lossValue; // число или тензор, представляющий ошибку
}
Функция может включать сложные математические операции, комбинации стандартных метрик или условия для обработки выбросов и специальных случаев.
Для операций с тензорами в Keras.js используются встроенные методы
объекта K (аналог Keras backend в Python):
K.mean(tensor) — среднее значение элементов
тензора.K.sum(tensor) — сумма элементов.K.square(tensor) — возведение элементов в квадрат.K.abs(tensor) — модуль элементов.K.maximum(a, b) — поэлементный максимум.Пример реализации функции потерь на основе MSE с порогом:
function thresholdedMSE(yTrue, yPred) {
const diff = K.sub(yPred, yTrue);
const squaredDiff = K.square(diff);
const mask = K.greater(squaredDiff, 0.01); // игнорируем ошибки меньше порога
const filteredDiff = K.mul(squaredDiff, mask);
return K.mean(filteredDiff);
}
В этом примере мелкие ошибки не учитываются, что может быть полезно при шумных данных.
Для задач, где ошибки одной категории более критичны, чем другой, применяются асимметричные функции потерь. Например, при регрессии можно штрафовать недооценку сильнее, чем переоценку:
function asymmetricLoss(yTrue, yPred) {
const diff = K.sub(yPred, yTrue);
const loss = K.where(
K.greater(diff, 0),
K.mul(diff, 2), // переоценка
K.mul(K.abs(diff), 5) // недооценка
);
return K.mean(loss);
}
Использование K.where позволяет задавать поэлементные
условия, что делает функцию потерь гибкой и легко настраиваемой.
Регуляризация часто включается непосредственно в функцию потерь для контроля переобучения. В Keras.js это может быть сделано через L1 и L2 нормы весов:
function lossWithL2(yTrue, yPred, model) {
const mse = K.mean(K.square(K.sub(yPred, yTrue)));
let l2Penalty = K.scalar(0);
model.layers.forEach(layer => {
if (layer.weights) {
layer.weights.forEach(w => {
l2Penalty = K.add(l2Penalty, K.sum(K.square(w))));
});
}
});
return K.add(mse, K.mul(K.scalar(0.01), l2Penalty));
}
В этом примере 0.01 — коэффициент регуляризации,
регулирующий влияние штрафа на веса.
Keras.js обрабатывает данные батчами. Функции потерь должны корректно
работать с тензорами любого размера. Рекомендуется использовать
агрегирующие операции (K.mean, K.sum) для
перевода тензора ошибок в скалярное значение, чтобы оптимизатор мог
корректно обновлять веса.
function combinedLoss(yTrue, yPred) {
const mse = K.mean(K.square(K.sub(yPred, yTrue)));
const mae = K.mean(K.abs(K.sub(yPred, yTrue)));
return K.add(K.mul(mse, K.scalar(0.7)), K.mul(mae, K.scalar(0.3)));
}
Пользовательские функции потерь в Keras.js дают возможность тонко настраивать обучение моделей, адаптируя алгоритмы под специфические задачи и условия. Они обеспечивают гибкость, позволяя создавать новые метрики, контролировать переобучение и учитывать особенности данных.