Deep Learning Algorithm Implementations 1.0.0
C++ implementations of fundamental deep learning algorithms
Loading...
Searching...
No Matches
losses.cpp
Go to the documentation of this file.
1#include "loss/losses.hpp"
2#include <cmath>
3#include <algorithm>
4
5namespace dl::loss {
6
7 // ============================================================================
8 // MSE Loss Implementation
9 // ============================================================================
10
11 template<typename T>
12 Variable<T> MSELoss<T>::forward(const Variable<T>& predictions, const Variable<T>& targets) {
13 // TODO: Implement MSE loss computation
14 // Steps:
15 // 1. Compute difference: diff = predictions - targets
16 // 2. Square the difference: squared_diff = diff * diff
17 // 3. Apply reduction (mean, sum, or none)
18
19 Variable<T> diff = predictions - targets;
20 Variable<T> squared_diff = diff * diff;
21
22 if (reduction_ == "mean") {
23 return squared_diff.mean();
24 } else if (reduction_ == "sum") {
25 return squared_diff.sum();
26 } else {
27 return squared_diff;
28 }
29 }
30
31 // ============================================================================
32 // Cross Entropy Loss Implementation
33 // ============================================================================
34
35 template<typename T>
37 // TODO: Implement numerically stable softmax
38 // Steps:
39 // 1. Subtract max for numerical stability: shifted = logits - max(logits)
40 // 2. Compute exp: exp_shifted = exp(shifted)
41 // 3. Normalize: softmax = exp_shifted / sum(exp_shifted)
42
43 // Placeholder implementation
44 Variable<T> exp_logits = logits.exp();
45 Variable<T> sum_exp = exp_logits.sum();
46 // TODO: Implement proper broadcasting division
47 return exp_logits; // Placeholder
48 }
49
50 template<typename T>
51 Variable<T> CrossEntropyLoss<T>::log_softmax(const Variable<T>& logits) {
52 // TODO: Implement numerically stable log_softmax
53 // log_softmax(x) = x - log(sum(exp(x)))
54 // More stable than log(softmax(x))
55
56 // Placeholder implementation
57 return logits.log(); // Placeholder
58 }
59
60 template<typename T>
62 // TODO: Implement cross entropy loss
63 // Steps:
64 // 1. Apply log_softmax to predictions
65 // 2. Compute negative log likelihood: -targets * log_softmax_pred
66 // 3. Apply reduction
67
68 Variable<T> log_probs = log_softmax(predictions);
69 Variable<T> nll = targets * log_probs;
70 Variable<T> loss = nll * Variable<T>(Matrix<T>(1, 1, -1.0), false); // Negate
71
72 if (reduction_ == "mean") {
73 return loss.mean();
74 } else if (reduction_ == "sum") {
75 return loss.sum();
76 } else {
77 return loss;
78 }
79 }
80
81 // ============================================================================
82 // Binary Cross Entropy Loss Implementation
83 // ============================================================================
84
85 template<typename T>
86 Variable<T> BCELoss<T>::forward(const Variable<T>& predictions, const Variable<T>& targets) {
87 // TODO: Implement BCE loss
88 // BCE = -[y * log(p) + (1-y) * log(1-p)]
89 // Steps:
90 // 1. Compute log(predictions) and log(1 - predictions)
91 // 2. Apply BCE formula
92 // 3. Apply reduction
93
94 // Add small epsilon for numerical stability
95 T eps = 1e-7;
96 Variable<T> eps_var(Matrix<T>(1, 1, eps), false);
97 Variable<T> one_var(Matrix<T>(1, 1, 1.0), false);
98
99 // Clamp predictions to avoid log(0)
100 // TODO: Implement proper clamping
101 Variable<T> log_pred = predictions.log();
102 Variable<T> log_one_minus_pred = (one_var - predictions).log();
103
104 Variable<T> loss = targets * log_pred + (one_var - targets) * log_one_minus_pred;
105 loss = loss * Variable<T>(Matrix<T>(1, 1, -1.0), false); // Negate
106
107 if (reduction_ == "mean") {
108 return loss.mean();
109 } else if (reduction_ == "sum") {
110 return loss.sum();
111 } else {
112 return loss;
113 }
114 }
115
116 // ============================================================================
117 // BCE with Logits Loss Implementation
118 // ============================================================================
119
120 template<typename T>
122 // TODO: Implement BCE with logits (more numerically stable)
123 // Use the identity: BCE_with_logits(x, y) = max(x, 0) - x*y + log(1 + exp(-|x|))
124 // This avoids computing sigmoid explicitly
125
126 // Placeholder: Apply sigmoid then BCE
127 Variable<T> sigmoid_pred = predictions.sigmoid();
128 BCELoss<T> bce_loss(reduction_);
129 return bce_loss.forward(sigmoid_pred, targets);
130 }
131
132 // ============================================================================
133 // Hinge Loss Implementation
134 // ============================================================================
135
136 template<typename T>
137 Variable<T> HingeLoss<T>::forward(const Variable<T>& predictions, const Variable<T>& targets) {
138 // TODO: Implement hinge loss
139 // Hinge(y_pred, y_true) = max(0, 1 - y_true * y_pred)
140 // Steps:
141 // 1. Compute margin: 1 - targets * predictions
142 // 2. Apply max(0, margin) - this requires implementing max operation
143 // 3. Apply reduction
144
145 Variable<T> one_var(Matrix<T>(1, 1, 1.0), false);
146 Variable<T> margin = one_var - targets * predictions;
147
148 // TODO: Implement max(0, margin) operation
149 // For now, placeholder implementation
150 Variable<T> loss = margin; // Placeholder
151
152 if (reduction_ == "mean") {
153 return loss.mean();
154 } else if (reduction_ == "sum") {
155 return loss.sum();
156 } else {
157 return loss;
158 }
159 }
160
161 // ============================================================================
162 // Huber Loss Implementation
163 // ============================================================================
164
165 template<typename T>
166 Variable<T> HuberLoss<T>::forward(const Variable<T>& predictions, const Variable<T>& targets) {
167 // TODO: Implement Huber loss
168 // Huber(y_pred, y_true) = {
169 // 0.5 * (y_pred - y_true)² if |y_pred - y_true| <= delta
170 // delta * |y_pred - y_true| - 0.5 * delta² otherwise
171 // }
172 // Steps:
173 // 1. Compute absolute difference: |predictions - targets|
174 // 2. Create mask for |diff| <= delta
175 // 3. Apply conditional logic
176 // 4. Apply reduction
177
178 Variable<T> diff = predictions - targets;
179 Variable<T> abs_diff = diff; // TODO: Implement abs() operation
180
181 // Placeholder: Use MSE for now
182 Variable<T> squared_diff = diff * diff;
183 Variable<T> half_var(Matrix<T>(1, 1, 0.5), false);
184 Variable<T> loss = half_var * squared_diff;
185
186 if (reduction_ == "mean") {
187 return loss.mean();
188 } else if (reduction_ == "sum") {
189 return loss.sum();
190 } else {
191 return loss;
192 }
193 }
194
195 // ============================================================================
196 // Explicit Template Instantiations
197 // ============================================================================
198
199 template class MSELoss<float>;
200 template class MSELoss<double>;
201 template class CrossEntropyLoss<float>;
202 template class CrossEntropyLoss<double>;
203 template class BCELoss<float>;
204 template class BCELoss<double>;
205 template class BCEWithLogitsLoss<float>;
206 template class BCEWithLogitsLoss<double>;
207 template class HingeLoss<float>;
208 template class HingeLoss<double>;
209 template class HuberLoss<float>;
210 template class HuberLoss<double>;
211
212} // namespace dl::loss
Binary Cross Entropy Loss with autograd support.
Definition losses.hpp:121
Variable< T > forward(const Variable< T > &predictions, const Variable< T > &targets) override
Forward pass: compute binary cross entropy loss.
Definition losses.cpp:86
Binary Cross Entropy with Logits Loss.
Definition losses.hpp:148
Variable< T > forward(const Variable< T > &predictions, const Variable< T > &targets) override
Forward pass: compute BCE loss from logits.
Definition losses.cpp:121
Cross Entropy Loss with autograd support.
Definition losses.hpp:83
Variable< T > forward(const Variable< T > &predictions, const Variable< T > &targets) override
Forward pass: compute cross entropy loss.
Definition losses.cpp:61
Hinge Loss with autograd support.
Definition losses.hpp:176
Variable< T > forward(const Variable< T > &predictions, const Variable< T > &targets) override
Forward pass: compute hinge loss.
Definition losses.cpp:137
Huber Loss with autograd support.
Definition losses.hpp:207
Variable< T > forward(const Variable< T > &predictions, const Variable< T > &targets) override
Forward pass: compute Huber loss.
Definition losses.cpp:166
Mean Squared Error Loss with autograd support.
Definition losses.hpp:55
Variable< T > forward(const Variable< T > &predictions, const Variable< T > &targets) override
Forward pass: compute MSE loss.
Definition losses.cpp:12
Variable class that supports automatic differentiation.
Definition autograd.hpp:58
Variable< T > mean() const
Definition autograd.cpp:102
Variable< T > sigmoid() const
Definition autograd.cpp:113
Variable< T > log() const
Definition autograd.cpp:158
Variable< T > exp() const
Definition autograd.cpp:147
Variable< T > sum() const
Definition autograd.cpp:91
PyTorch-like loss functions with automatic differentiation.