Class: GRX::Loss::HuberLoss
- Inherits:
-
Object
- Object
- GRX::Loss::HuberLoss
- Defined in:
- lib/grx/loss.rb
Overview
================================================================
HuberLoss — Smooth L1 (robust against outliers)
Instance Attribute Summary collapse
-
#delta ⇒ Object
readonly
Returns the value of attribute delta.
Instance Method Summary collapse
- #call(pred, target) ⇒ Object
-
#initialize(delta: 1.0) ⇒ HuberLoss
constructor
A new instance of HuberLoss.
Constructor Details
#initialize(delta: 1.0) ⇒ HuberLoss
Returns a new instance of HuberLoss.
84 85 86 |
# File 'lib/grx/loss.rb', line 84 def initialize(delta: 1.0) @delta = delta.to_f end |
Instance Attribute Details
#delta ⇒ Object (readonly)
Returns the value of attribute delta.
82 83 84 |
# File 'lib/grx/loss.rb', line 82 def delta @delta end |
Instance Method Details
#call(pred, target) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/grx/loss.rb', line 88 def call(pred, target) raise ShapeError, "Shapes incompatibles: #{pred.shape} vs #{target.shape}" if pred.shape != target.shape diff_data = (pred - target).abs.to_a d = @delta loss_val = diff_data.sum { |v| v <= d ? 0.5 * v * v : d * (v - 0.5 * d) } / diff_data.size.to_f out = Tensor.create([loss_val], [1], requires_grad: pred.requires_grad || target.requires_grad) if pred.requires_grad || target.requires_grad out._grafo_hijos.push(pred, target) n = diff_data.size.to_f out.backward_fn = ->(g) { grad_pred = (pred - target).to_a.map do |err| abs_err = err.abs (abs_err <= d ? err : d * (err > 0 ? 1.0 : -1.0)) * (g.item / n) end pred.agregar_gradiente(Tensor.create(grad_pred, pred.shape)) if pred.requires_grad target.agregar_gradiente(Tensor.create(grad_pred.map(&:-@), target.shape)) if target.requires_grad } end out end |