Initial commit
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
//! 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user