ceras
yet another deep learning engine
loss.hpp
Go to the documentation of this file.
1 #ifndef APWVIJWMXHAVXUGYGVNDSEFKTMBKLBMGLSHWUPRPGLFCHUBDRAHGSTDSEDNKOGTIBNQVNLXCD
2 #define APWVIJWMXHAVXUGYGVNDSEFKTMBKLBMGLSHWUPRPGLFCHUBDRAHGSTDSEDNKOGTIBNQVNLXCD
3 
4 #include "./operation.hpp"
5 #include "./tensor.hpp"
6 #include "./utils/debug.hpp"
7 
8 namespace ceras
9 {
10 
11  template < Expression Lhs_Expression, Expression Rhs_Expression >
12  auto constexpr mean_squared_logarithmic_error( Lhs_Expression const& lhs_ex, Rhs_Expression const& rhs_ex ) noexcept
13  {
14  return sum_reduce( square( minus(lhs_ex, rhs_ex)) );
15  }
16 
17  template < Expression Lhs_Expression, Expression Rhs_Expression >
18  auto constexpr squared_loss( Lhs_Expression const& lhs_ex, Rhs_Expression const& rhs_ex ) noexcept
19  {
20  return sum_reduce( square( minus(lhs_ex, rhs_ex)) );
21  }
22 
23  template < Expression Lhs_Expression, Expression Rhs_Expression >
24  auto constexpr mean_squared_error( Lhs_Expression const& lhs_ex, Rhs_Expression const& rhs_ex ) noexcept
25  {
26  return mean_reduce( square( minus(lhs_ex, rhs_ex)) );
27  }
28 
29  template < Expression Lhs_Expression, Expression Rhs_Expression >
30  auto constexpr mse( Lhs_Expression const& lhs_ex, Rhs_Expression const& rhs_ex ) noexcept
31  {
32  return mean_squared_error( lhs_ex, rhs_ex );
33  }
34 
35  template < Expression Lhs_Expression, Expression Rhs_Expression >
36  auto constexpr abs_loss( Lhs_Expression const& lhs_ex, Rhs_Expression const& rhs_ex ) noexcept
37  {
38  return sum_reduce( abs( minus(lhs_ex, rhs_ex)) );
39  }
40 
41  template < Expression Lhs_Expression, Expression Rhs_Expression >
42  auto constexpr mean_absolute_error( Lhs_Expression const& lhs_ex, Rhs_Expression const& rhs_ex ) noexcept
43  {
44  return mean_reduce( abs( minus(lhs_ex, rhs_ex)) );
45  };
46 
47  template < Expression Lhs_Expression, Expression Rhs_Expression >
48  auto constexpr mae( Lhs_Expression const& lhs_ex, Rhs_Expression const& rhs_ex ) noexcept
49  {
50  return mean_absolute_error( lhs_ex, rhs_ex );
51  };
52 
53  template < Expression Lhs_Expression, Expression Rhs_Expression >
54  auto constexpr cross_entropy( Lhs_Expression const& lhs_ex, Rhs_Expression const& rhs_ex ) noexcept
55  {
56  return negative( sum_reduce( hadamard_product( lhs_ex, log(rhs_ex) ) ) );
57  }
58 
59  namespace
60  {
61  struct cross_entropy_loss_context
62  {
63  auto make_forward() const noexcept
64  {
65  return []<Tensor Tsor>( Tsor const& ground_truth_input, Tsor const& prediction_input ) noexcept
66  {
67  Tsor sm = softmax( prediction_input );
68  typename Tsor::value_type ans{0};
69  for ( auto idx : range( ground_truth_input.size() ) )
70  ans -= ground_truth_input[idx] * std::log( std::max( static_cast<typename Tsor::value_type>(eps), sm[idx] ) );
71  auto result = as_tensor<typename Tsor::value_type, typename Tsor::allocator>(ans/(*(ground_truth_input.shape().begin())));
72  return result;
73  };
74  }
75  auto make_backward() const noexcept
76  {
77  return []<Tensor Tsor>( Tsor const& ground_truth_input, Tsor const& prediction_input, [[maybe_unused]]Tsor const& output_data, [[maybe_unused]]Tsor const& grad ) noexcept
78  {
79  // In our implementation, the grad is always 1, unless this layer is nested contributing to a combined weighted loss
80  typename Tsor::value_type const factor = grad[0]; // the shape of grad is {1,}
81  Tsor ground_truth_gradient = ground_truth_input;
82  Tsor sm = softmax( prediction_input ) - ground_truth_input;
83  return std::make_tuple( ground_truth_gradient*factor, sm*factor );
84  };
85  }
86 
87  };//struct cross_entropy_loss_context
88  }//anonymous namespace
89 
90  template < Expression Lhs_Expression, Expression Rhs_Expression >
91  auto constexpr binary_cross_entropy_loss( Lhs_Expression const& ground_truth, Rhs_Expression const& prediction ) noexcept
92  {
93  auto ones = ones_like( ground_truth );
94  auto error = negative( hadamard_product( ground_truth, log(prediction) ) + hadamard_product( (ones - ground_truth), log(ones - prediction) ) );
95  return mean_reduce( error );
96  }
97 
98 
99  // beware: do not apply softmax activation before this layer, as this loss is softmax+xentropy already
100  template < Expression Lhs_Expression, Expression Rhs_Expression >
101  auto constexpr cross_entropy_loss( Lhs_Expression const& lhs_ex, Rhs_Expression const& rhs_ex ) noexcept
102  {
103  return make_binary_operator( cross_entropy_loss_context{}.make_forward(), cross_entropy_loss_context{}.make_backward(), "CrossEntropyLoss" )( lhs_ex, rhs_ex );
104  }
105 
106  template < Expression Lhs_Expression, Expression Rhs_Expression >
107  auto constexpr hinge_loss( Lhs_Expression const& lhs_ex, Rhs_Expression const& rhs_ex ) noexcept
108  {
109  return mean_reduce( maximum( value{0.0f}, value{1.0f} - hadamard_product(lhs_ex, rhs_ex) ) );
110  }
111 
112  // loss interfaces
113  // A loss is an expression. This expression takes two parameters.
114  // The first parameter is a place_holder, that will be binded to an tensor.
115  // The second parameter is an expression, that will be evaluated to compare with the tensor binded to the first parameter
116 
130  inline auto MeanSquaredError = []()
131  {
132  return []<Expression Ex >( Ex const& output )
133  {
134  return [=]<Place_Holder Ph>( Ph const& ground_truth )
135  {
136  return mean_squared_error( ground_truth, output );
137  };
138  };
139  };
140 
144  inline auto MSE = []()
145  {
146  return MeanSquaredError();
147  };
148 
162  inline auto MeanAbsoluteError = []()
163  {
164  return []<Expression Ex >( Ex const& output )
165  {
166  return [=]<Place_Holder Ph>( Ph const& ground_truth )
167  {
168  return mean_absolute_error( ground_truth, output );
169  };
170  };
171  };
172 
173 
177  inline auto MAE = []()
178  {
179  return MeanAbsoluteError();
180  };
181 
182 
183 
184  inline auto Hinge = []()
185  {
186  return []<Expression Ex >( Ex const& output )
187  {
188  return [=]<Place_Holder Ph>( Ph const& ground_truth )
189  {
190  return hinge_loss( ground_truth, output );
191  };
192  };
193  };
194 
195  // note: do not apply softmax activation to the last layer of the model, this loss has packaged it
196  inline auto CategoricalCrossentropy = []()
197  {
198  return []<Expression Ex >( Ex const& output )
199  {
200  return [=]<Place_Holder Ph>( Ph const& ground_truth )
201  {
202  return cross_entropy_loss( ground_truth, output );
203  };
204  };
205  };
206 
207  inline auto CategoricalCrossEntropy = []()
208  {
209  return CategoricalCrossentropy();
210  };
211 
212  inline auto BinaryCrossentropy = []()
213  {
214  return []<Expression Ex >( Ex const& output )
215  {
216  return [=]<Place_Holder Ph>( Ph const& ground_truth )
217  {
218  return binary_cross_entropy_loss( ground_truth, output );
219  };
220  };
221  };
222 
223  inline auto BinaryCrossEntropy = []()
224  {
225  return BinaryCrossentropy();
226  };
227 
228 
229 }//namespace ceras
230 
231 #endif//APWVIJWMXHAVXUGYGVNDSEFKTMBKLBMGLSHWUPRPGLFCHUBDRAHGSTDSEDNKOGTIBNQVNLXCD
232 
Definition: activation.hpp:12
constexpr auto mean_squared_error(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: loss.hpp:24
static constexpr auto make_binary_operator
Definition: operation.hpp:108
constexpr auto cross_entropy(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: loss.hpp:54
constexpr tensor< T, A > ones(std::vector< unsigned long > const &shape)
Definition: tensor.hpp:994
auto Hinge
Definition: loss.hpp:184
auto BinaryCrossEntropy
Definition: loss.hpp:223
constexpr auto hinge_loss(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: loss.hpp:107
auto CategoricalCrossEntropy
Definition: loss.hpp:207
constexpr Tsor ones_like(Tsor const &tsor)
Definition: tensor.hpp:1002
constexpr auto mae(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: loss.hpp:48
auto MAE
An alias name of function MeanAbsoluteError.
Definition: loss.hpp:177
constexpr auto abs_loss(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: loss.hpp:36
constexpr auto sum_reduce(Ex const &ex) noexcept
Definition: operation.hpp:450
constexpr auto squared_loss(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: loss.hpp:18
concept Place_Holder
Definition: place_holder.hpp:71
auto MeanAbsoluteError
Computes the mean of absolute errors between labels and predictions.
Definition: loss.hpp:162
constexpr auto mean_squared_logarithmic_error(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: loss.hpp:12
auto BinaryCrossentropy
Definition: loss.hpp:212
constexpr auto square(Ex const &ex) noexcept
Definition: operation.hpp:563
concept Tensor
Definition: tensor.hpp:362
auto MSE
An alias name of function MeanSquaredError.
Definition: loss.hpp:144
auto abs(C const &c) noexcept
Returns the magnitude of the complex expression.
Definition: complex_operator.hpp:67
constexpr auto mean_absolute_error(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: loss.hpp:42
concept Expression
A type that represents a unary operator, a binary operator, a variable, a place_holder,...
Definition: operation.hpp:169
auto CategoricalCrossentropy
Definition: loss.hpp:196
constexpr auto binary_cross_entropy_loss(Lhs_Expression const &ground_truth, Rhs_Expression const &prediction) noexcept
Definition: loss.hpp:91
constexpr auto cross_entropy_loss(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: loss.hpp:101
constexpr auto minus(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: operation.hpp:531
constexpr auto negative(Ex const &ex) noexcept
Definition: operation.hpp:389
constexpr auto softmax(Ex const &ex) noexcept
Softmax activation function, an unary operator.
Definition: activation.hpp:26
auto MeanSquaredError
Computes the mean of squares of errors between labels and predictions.
Definition: loss.hpp:130
auto max(Tsor const &tsor)
Definition: tensor.hpp:1008
constexpr auto mse(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: loss.hpp:30
constexpr auto hadamard_product(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: operation.hpp:444
constexpr auto mean_reduce(Ex const &ex) noexcept
Computes the mean of elements across all dimensions of an expression.
Definition: operation.hpp:488
constexpr auto maximum(Lhs_Expression const &lhs_ex, Rhs_Expression const &rhs_ex) noexcept
Definition: operation.hpp:1591
constexpr auto log(Ex const &ex) noexcept
Computes Log of the given expression.
Definition: operation.hpp:3231
Definition: value.hpp:15