Loss Functions — Функции потерь
Loss Functions
Унифицированные интерфейсы и реализации функций потерь (loss functions) с поддержкой GPU-ускорения через TorchSharp.
Обзор
Функции потерь используются при обучении нейросетевых моделей для оценки качества предсказаний. Реализации в IgdrasilAI:
- Работают на GPU (CUDA/CPU) через TorchSharp
- Имеют CPU fallback для совместимости
- Поддерживают различные режимы редукции (Mean, Sum)
- Вычисляют градиенты для backpropagation
Основной интерфейс
public interface ILossFunction
{
string Name { get; }
LossReduction Reduction { get; }
Task<float> ComputeLossAsync(
INeuralTensor predictions,
INeuralTensor targets,
CancellationToken cancellationToken = default);
Task<INeuralTensor> ComputeGradientAsync(
INeuralTensor predictions,
INeuralTensor targets,
CancellationToken cancellationToken = default);
}
Режимы редукции
public enum LossReduction
{
Mean, // Среднее значение потерь по всем элементам
Sum // Сумма потерь по всем элементам
}
Встроенные функции потерь
HuberLoss (Гладкая L1)
Комбинирует преимущества MSE (средней квадратической ошибки) и MAE (средней абсолютной ошибки):
- Квадратичный регион (|error| ≤ δ): гладкие градиенты
- Линейный регион (|error| > δ): устойчивость к выбросам
// Создание с GPU-ускорением
var loss = new HuberLoss(
delta: 1.0f, // Порог переключения регионов
reduction: LossReduction.Mean, // Усреднение потерь
gpuOps: backend as IGpuMathOps // GPU операции
);
// Вычисление потерь
float lossValue = await loss.ComputeLossAsync(predictions, targets);
// Получение градиентов
var gradients = await loss.ComputeGradientAsync(predictions, targets);
Математическое определение
$$L(y, \hat) = \begin\frac{1}{2}(y - \hat)^2 & \text{если } |y - \hat| \leq \delta \ \delta(|y - \hat| - \frac{1}{2}\delta) & \text{если } |y - \hat| > \delta \end$$
Градиент:
$$\frac{\partial L}{\partial \hat} = \begin-(y - \hat) & \text{если } |y - \hat| \leq \delta \ -\delta \cdot \text(y - \hat) & \text{если } |y - \hat| > \delta \end$$
Параметр Delta
| Значение | Характеристика | Применение |
|---|---|---|
| 0.1 - 0.5 | Близко к MSE, чувствительна к выбросам | Чистые данные |
| 1.0 - 2.0 | Сбалансирована (рекомендуется) | Общий случай |
| 5.0 - 10.0 | Близко к MAE, робастна к выбросам | Данные с выбросами |
Стратегия подбора
- Начните с
delta = σ(стандартное отклонение ошибок) - Оцените на validation set для разных значений delta
- Выберите delta с минимальной validation loss
- Мониторьте градиенты во время обучения
Пример: Обучение с HuberLoss
var backend = new TorchSharpBackend();
await backend.InitializeAsync();
var loss = new HuberLoss(
delta: 1.0f,
reduction: LossReduction.Mean,
gpuOps: backend as IGpuMathOps
);
var optimizer = new AdamWOptimizer(
learningRate: 0.001f,
weightDecay: 0.01f,
gpuOps: backend as IGpuMathOps
);
// Цикл обучения
for (int epoch = 0; epoch < numEpochs; epoch++)
{
float epochLoss = 0f;
int batchCount = 0;
foreach (var (predictions, targets) in trainingData)
{
// Вычисление потерь (GPU)
float batchLoss = await loss.ComputeLossAsync(predictions, targets);
// Вычисление градиентов (GPU)
var gradients = await loss.ComputeGradientAsync(predictions, targets);
// Обновление весов (GPU)
await optimizer.ApplyGradientsAsync(weights, gradients);
epochLoss += batchLoss;
batchCount++;
}
Console.WriteLine($"Epoch {epoch}: Loss = {epochLoss / batchCount:F6}");
}
await backend.ShutdownAsync();
GPU-ускорение
Архитектура вычислений
HuberLoss использует цепочку GPU операций:
Входные тензоры (predictions, targets)
↓
SubtractAsync: diff = pred - target
↓
AbsAsync: absDiff = |diff|
↓
LessEqualAsync: condition = (absDiff ≤ δ)
↓
MultiplyAsync: вычисление обоих регионов
↓
WhereAsync: условный выбор
↓
SumAsync/MeanAsync: редукция к скаляру
↓
Значение потерь
GPU операции
| Операция | Реализация | Назначение |
|---|---|---|
SubtractAsync |
torch.sub() |
Вычисление разностей |
AbsAsync |
torch.abs() |
Модули элементов |
LessEqualAsync |
tensor.le() |
Булевы сравнения |
WhereAsync |
torch.where() |
Условный выбор |
MultiplyAsync |
torch.mul() |
Поэлементное умножение |
SumAsync |
torch.sum() |
Редукция суммой |
MeanAsync |
torch.mean() |
Редукция средним |
Производительность
| Размер тензора | CPU | GPU | Ускорение |
|---|---|---|---|
| 1M элементов | ~5 ms | ~0.05 ms | 100x |
| 100K элементов | ~0.5 ms | ~0.01 ms | 50x |
| 10K элементов | ~0.05 ms | ~0.005 ms | 10x |
CPU fallback
Если GPU недоступен, автоматически используется CPU реализация:
// Только CPU (без GPU)
var cpuLoss = new HuberLoss(delta: 1.0f, gpuOps: null);
float lossValue = await cpuLoss.ComputeLossAsync(predictions, targets);
CPU реализация использует нативный C#:
float sum = 0f;
for (int i = 0; i < predictions.Length; i++)
{
var diff = predictions[i] - targets[i];
var abs = Math.Abs(diff);
if (abs <= delta)
sum += 0.5f * diff * diff; // Квадратичный регион
else
sum += delta * (abs - 0.5f * delta); // Линейный регион
}
Интеграция с оптимизаторами
HuberLoss совместима со всеми оптимизаторами IgdrasilAI:
// SGD с инерцией
var sgdOptimizer = new SgdOptimizer(
learningRate: 0.01f,
momentum: 0.9f,
gpuOps: backend as IGpuMathOps
);
// Adam (рекомендуется)
var adamOptimizer = new AdamOptimizer(
learningRate: 0.001f,
gpuOps: backend as IGpuMathOps
);
// AdamW (с weight decay)
var adamwOptimizer = new AdamWOptimizer(
learningRate: 0.001f,
weightDecay: 0.01f,
gpuOps: backend as IGpuMathOps
);
// RMSProp
var rmspropOptimizer = new RmsPropOptimizer(
learningRate: 0.001f,
gpuOps: backend as IGpuMathOps
);
Верификация
Встроенные тесты проверяют:
- ✅ Корректность CPU реализации
- ✅ Эквивалентность GPU и CPU
- ✅ Правильность вычисления градиентов
- ✅ Влияние параметра delta
- ✅ Цепочка GPU операций
var tests = new HuberLossGpuTests();
await tests.TestCpuFallback();
await tests.TestGpuVsCpu();
await tests.TestGradientComputation();
await tests.TestDeltaThreshold();
await tests.TestGpuOperationChain();
Сравнение с другими функциями потерь
| Функция | Гладкость | Робастность | GPU | Применение |
|---|---|---|---|---|
| MSE | ✅ | ❌ | ✅ | Чистые данные |
| MAE | ❌ | ✅ | ✅ | Выбросы |
| Huber | ✅ | ✅ | ✅ | Общий случай |
| SmoothL1 | ✅ | ✅ | ✅ | Детекция |
Рекомендации
Когда использовать HuberLoss
- Регрессия с потенциальными выбросами ✅
- Нужны гладкие градиенты ✅
- Обучение на GPU ✅
- Нужна робастность к ошибкам ✅
Когда использовать альтернативы
- Очень чистые данные → MSE
- Много выбросов → MAE
- Детекция объектов → SmoothL1
- Классификация → CrossEntropy
Ссылки
Дополнительные ресурсы
- 📖 GPU_ACCELERATED_HUBERLOSS.md — полная техническая документация
- 📝 QUICK_REFERENCE.md — быстрый старт
- 🧪 HuberLossGpuTest.cs — примеры тестов