ai/neural/training/loss-functions.js

/**
 * @fileoverview Verlustfunktionen (Loss Functions) für das Training.
 * 
 * Jede Loss-Funktion ist als Objekt mit `compute` (Vorwärts) und `derivative`
 * implementiert, um im Backpropagation-Schritt die Gradienten zu berechnen.
 *
 * Unterstützt: MSE (Mean Squared Error) und Cross-Entropy.
 *
 * @author Alexander Wolf
 * @see docs/architecture/NEURAL_NET_ARCHITECTURE.md
 */

/**
 * @typedef {Object} LossFunction
 * @property {string} name - Name der Verlustfunktion
 * @property {function(Float64Array, Float64Array): number} compute - Berechnet den Gesamtverlust
 * @property {function(Float64Array, Float64Array): Float64Array} derivative - Gradient bzgl. predicted
 */

/**
 * Registry aller verfügbaren Verlustfunktionen.
 *
 * @type {Object<string, LossFunction>}
 */
const LOSS_FUNCTIONS = {

    /**
     * Mean Squared Error: L = (1/n) Σ (predicted - target)²
     * Geeignet für Regression und einfache binäre Klassifikation.
     */
    mse: {
        name: 'mse',
        /**
         * Berechnet den MSE-Verlust.
         * @param {Float64Array} predicted - Netzwerk-Ausgabe
         * @param {Float64Array} target - Zielwerte
         * @returns {number} Durchschnittlicher quadratischer Fehler
         */
        compute(predicted, target) {
            let sum = 0;
            for (let i = 0; i < predicted.length; i++) {
                const diff = predicted[i] - target[i];
                sum += diff * diff;
            }
            return sum / predicted.length;
        },

        /**
         * Ableitung des MSE: dL/dy_i = 2(predicted_i - target_i) / n
         * @param {Float64Array} predicted
         * @param {Float64Array} target
         * @returns {Float64Array} Gradient pro Output-Neuron
         */
        derivative(predicted, target) {
            const grad = new Float64Array(predicted.length);
            const scale = 2 / predicted.length;
            for (let i = 0; i < predicted.length; i++) {
                grad[i] = scale * (predicted[i] - target[i]);
            }
            return grad;
        }
    },

    /**
     * Cross-Entropy Loss: L = -Σ target_i · log(predicted_i)
     * Standard für Klassifikation mit Softmax-Output.
     * Voraussetzung: predicted enthält Wahrscheinlichkeiten (0,1), z.B. nach Softmax.
     */
    crossEntropy: {
        name: 'crossEntropy',
        /**
         * Berechnet den Cross-Entropy-Verlust.
         * @param {Float64Array} predicted - Wahrscheinlichkeiten nach Softmax
         * @param {Float64Array} target - One-Hot-kodierte Zielklasse
         * @returns {number} Cross-Entropy-Verlust
         */
        compute(predicted, target) {
            let sum = 0;
            const epsilon = 1e-15; // Numerische Stabilität, verhindert log(0)
            for (let i = 0; i < predicted.length; i++) {
                if (target[i] > 0) {
                    sum -= target[i] * Math.log(Math.max(predicted[i], epsilon));
                }
            }
            return sum;
        },

        /**
         * Ableitung des Cross-Entropy mit Softmax: dL/dz_i = predicted_i - target_i
         * (Vereinfacht, da Softmax + Cross-Entropy eine elegante gemeinsame Ableitung haben)
         * @param {Float64Array} predicted - Softmax-Ausgabe
         * @param {Float64Array} target - One-Hot-Zielwerte
         * @returns {Float64Array} Gradient pro Output-Neuron
         */
        derivative(predicted, target) {
            const grad = new Float64Array(predicted.length);
            for (let i = 0; i < predicted.length; i++) {
                grad[i] = predicted[i] - target[i];
            }
            return grad;
        }
    }
};

// Export für globalen Zugriff (Window UND Worker-Kontext)
(function(root) {
    root.LOSS_FUNCTIONS = LOSS_FUNCTIONS;
})(typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : this);