Class: GRX::Loss::CrossEntropyLoss
- Inherits:
-
Object
- Object
- GRX::Loss::CrossEntropyLoss
- Defined in:
- lib/grx/loss.rb
Overview
================================================================
CrossEntropyLoss — Softmax + NLL (multi-class) L = -sum(target * log(softmax(logits))) / batch_size
Constant Summary collapse
- EPS =
1e-7
Instance Method Summary collapse
Instance Method Details
#call(logits, target) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/grx/loss.rb', line 52 def call(logits, target) raise ShapeError, "Incompatible shapes: #{logits.shape} vs #{target.shape}" if logits.shape != target.shape probs = logits.softmax p_data = probs.to_a t_data = target.to_a batch_size = logits.shape[0].to_f loss_val = t_data.each_with_index.sum do |t, i| next 0.0 if t == 0.0 p = [p_data[i], EPS].max -t * Math.log(p) end / batch_size out = Tensor.create([loss_val], [1], requires_grad: logits.requires_grad || target.requires_grad) if logits.requires_grad || target.requires_grad out._grafo_hijos.push(logits, target) out.backward_fn = ->(g) { scale = g.item / batch_size grad_logits = p_data.zip(t_data).map { |p, t| (p - t) * scale } logits.agregar_gradiente(Tensor.create(grad_logits, logits.shape)) if logits.requires_grad } end out end |