Files
rustytorch/crates/training/rtx-transformers/src/losses/logcosh_demo.rs
T
2026-03-04 00:08:42 +00:00

177 lines
7.0 KiB
Rust

//! LogCoshLoss Demonstration and Examples
//!
//! This module provides comprehensive examples and demonstrations of the LogCoshLoss
//! implementation, showcasing its key features and usage patterns.
use super::{LogCoshLoss, LogCoshLossBuilder, Loss, Reduction, LossCharacteristics, LossComparison};
use rtx_tensor::{Tensor, Device};
use crate::Result;
/// Comprehensive demonstration of LogCoshLoss features
pub fn demonstrate_logcosh_loss() -> Result<()> {
println!("LogCoshLoss Demonstration");
println!("========================");
let device = Device::cuda(0).unwrap_or(Device::default());
// Basic usage
println!("\n1. Basic Usage:");
let loss = LogCoshLoss::new();
let predictions = Tensor::from_data(vec![1.0, 2.0, 3.0], [3], &device)?;
let targets = Tensor::from_data(vec![1.2, 1.8, 3.5], [3], &device)?;
let loss_value = loss.forward(&predictions, &targets)?;
println!("Basic loss value: {}", loss_value.to_cpu()?[0]);
// Builder pattern
println!("\n2. Builder Pattern:");
let custom_loss = LogCoshLoss::builder()
.reduction(Reduction::Sum)
.build();
let sum_loss = custom_loss.forward(&predictions, &targets)?;
println!("Sum reduction loss: {}", sum_loss.to_cpu()?[0]);
// Different reduction modes
println!("\n3. Reduction Modes:");
for reduction in [Reduction::None, Reduction::Mean, Reduction::Sum] {
let loss = LogCoshLoss::new().with_reduction(reduction);
let result = loss.forward(&predictions, &targets)?;
println!("{:?} reduction: {:?}", reduction, result.to_cpu()?);
}
// Mathematical properties
println!("\n4. Mathematical Properties:");
let loss = LogCoshLoss::new();
for error in [0.0, 0.1, 0.5, 1.0, 2.0, 5.0, 10.0] {
let characteristics = loss.get_characteristics(error);
println!("Error {}: Loss={:.6}, Grad={:.6}, Quadratic={}, Linear={}",
error,
characteristics.loss_value,
characteristics.derivative,
characteristics.is_quadratic_region,
characteristics.is_linear_region);
}
// Numerical stability
println!("\n5. Numerical Stability:");
let large_errors = vec![50.0, 100.0, 1000.0];
for &error in &large_errors {
let loss_val = loss.compute_single_loss(error);
let expected_linear = error - 2.0f32.ln();
println!("Error {}: LogCosh={:.6}, Linear approx={:.6}, Diff={:.6}",
error, loss_val, expected_linear, (loss_val - expected_linear).abs());
}
// Gradient verification
println!("\n6. Gradient Verification:");
for error in [0.1, 1.0, 5.0] {
let analytical = loss.derivative(error);
let numerical = loss.numerical_gradient(error, 1e-5);
let error_pct = ((analytical - numerical) / analytical).abs() * 100.0;
println!("Error {}: Analytical={:.6}, Numerical={:.6}, Error={:.3}%",
error, analytical, numerical, error_pct);
}
Ok(())
}
/// Demonstrate comparison with other loss functions
pub fn demonstrate_loss_comparisons() {
println!("\nLoss Function Comparisons");
println!("========================");
// Test with various error patterns
let small_errors = vec![0.01, 0.05, 0.1, 0.2, 0.3];
let large_errors = vec![1.0, 2.0, 5.0, 10.0, 20.0];
let mixed_errors = vec![0.1, 0.5, 1.0, 3.0, 10.0, 0.2, 15.0];
println!("\n1. LogCosh vs MSE (Small Errors):");
let small_comparison = LossComparison::logcosh_vs_mse(&small_errors);
println!("LogCosh mean: {:.6}, MSE mean: {:.6}",
small_comparison.logcosh_mean, small_comparison.comparison_mean);
println!("Robustness ratio: {:.3}, Recommendation: {}",
small_comparison.robustness_ratio, small_comparison.recommendation);
println!("\n2. LogCosh vs MSE (Large Errors):");
let large_comparison = LossComparison::logcosh_vs_mse(&large_errors);
println!("LogCosh mean: {:.6}, MSE mean: {:.6}",
large_comparison.logcosh_mean, large_comparison.comparison_mean);
println!("Robustness ratio: {:.3}, Recommendation: {}",
large_comparison.robustness_ratio, large_comparison.recommendation);
println!("\n3. LogCosh vs Huber (Mixed Errors):");
let huber_comparison = LossComparison::logcosh_vs_huber(&mixed_errors, 1.0);
println!("LogCosh mean: {:.6}, Huber mean: {:.6}",
huber_comparison.logcosh_mean, huber_comparison.comparison_mean);
println!("Robustness ratio: {:.3}, Recommendation: {}",
huber_comparison.robustness_ratio, huber_comparison.recommendation);
}
/// Demonstrate advanced features
pub fn demonstrate_advanced_features() -> Result<()> {
println!("\nAdvanced Features");
println!("================");
let device = Device::cuda(0).unwrap_or(Device::default());
let loss = LogCoshLoss::new();
// Weighted loss computation
println!("\n1. Weighted Loss:");
let predictions = Tensor::from_data(vec![1.0, 2.0, 3.0, 4.0], [4], &device)?;
let targets = Tensor::from_data(vec![1.1, 1.9, 3.2, 3.8], [4], &device)?;
let weights = Tensor::from_data(vec![1.0, 2.0, 0.5, 1.5], [4], &device)?;
let unweighted = loss.forward(&predictions, &targets)?;
let weighted = loss.forward_weighted(&predictions, &targets, Some(&weights))?;
println!("Unweighted loss: {:.6}", unweighted.to_cpu()?[0]);
println!("Weighted loss: {:.6}", weighted.to_cpu()?[0]);
// Adaptive loss with delta parameter
println!("\n2. Adaptive Loss:");
for delta in [0.5, 1.0, 2.0] {
let adaptive_loss = loss.forward_adaptive(&predictions, &targets, delta)?;
println!("Delta {}: Adaptive loss = {:.6}", delta, adaptive_loss.to_cpu()?[0]);
}
// Loss statistics
println!("\n3. Loss Statistics:");
let stats = loss.compute_loss_statistics(&predictions, &targets)?;
println!("Samples: {}, Mean loss: {:.6}, Variance: {:.6}",
stats.num_samples, stats.mean_loss, stats.loss_variance);
println!("Quadratic region: {:.1}%, Linear region: {:.1}%",
stats.quadratic_region_fraction * 100.0,
stats.linear_region_fraction * 100.0);
// Forward with characteristics
println!("\n4. Forward with Characteristics:");
let (loss_val, characteristics) = loss.forward_with_characteristics(&predictions, &targets)?;
println!("Total loss: {:.6}", loss_val.to_cpu()?[0]);
for (i, char) in characteristics.iter().enumerate() {
println!("Sample {}: Error={:.3}, Loss={:.6}, In quadratic region={}",
i, char.error, char.loss_value, char.is_quadratic_region);
}
Ok(())
}
/// Run all demonstrations
pub fn run_all_demonstrations() -> Result<()> {
demonstrate_logcosh_loss()?;
demonstrate_loss_comparisons();
demonstrate_advanced_features()?;
Ok(())
}
#[cfg(all(test, feature = "disabled_tests"))]
mod demo_tests {
use super::*;
#[test]
fn test_demonstrations_run() {
// These would normally run the demonstrations
// For now, just test that the demo functions compile
assert!(true);
}
}