18#ifndef __NNFW_CKER_TRAIN_OPERATION_LOSS_H__
19#define __NNFW_CKER_TRAIN_OPERATION_LOSS_H__
37template <
typename T>
inline T
square(T value) {
return value * value; }
38template <
typename T>
inline T
log_threshold() {
return static_cast<T
>(1e-20); }
41inline void MSE(
const Shape &y_pred_shape,
const T *y_pred_data,
const Shape &y_true_shape,
45 throw std::runtime_error(
"cker::MSE: output dimension count should be 1");
47 throw std::runtime_error(
"cker::MSE: output and y_pred do not have the same batch");
48 if (y_pred_shape != y_true_shape)
49 throw std::runtime_error(
"cker::MSE: y_pred_shape != y_true_shape");
51 const auto batch = y_pred_shape.
Dims(0);
54 for (
int b = 0; b < batch; ++b)
57 for (
int i = 0; i <
size; ++i)
59 sum +=
square(y_pred_data[b *
size + i] - y_true_data[b *
size + i]);
61 output_data[b] =
static_cast<T
>(sum /
size);
66inline void MSEGrad(
const Shape &y_pred_shape,
const T *y_pred_data,
const Shape &y_true_shape,
67 const T *y_true_data,
const Shape &grad_shape, T *grad_data,
70 if (y_pred_shape != y_true_shape)
71 throw std::runtime_error(
"cker::MSEGrad: y_pred_shape != y_true_shape");
72 if (y_pred_shape != grad_shape)
73 throw std::runtime_error(
"cker::MSEGrad: y_pred_shape != grad_shape");
75 const int batch_size = grad_shape.
Dims(0);
77 auto reduction_size = 1;
78 switch (reduction_type)
81 reduction_size = batch_size * flat_size;
84 reduction_size = flat_size;
87 throw std::runtime_error(
"Unsupported reduction type");
90 for (
int b = 0; b < batch_size; ++b)
92 for (
int i = 0; i < flat_size; ++i)
94 const int offset = b * flat_size + i;
97 static_cast<T
>(-2 * (y_true_data[
offset] - y_pred_data[
offset]) / reduction_size);
104 const Shape &y_true_shape,
const T *y_true_data,
108 throw std::runtime_error(
"cker::CategoricalCrossEntropy: output dimension count should be 1");
109 if (y_pred_shape != y_true_shape)
110 throw std::runtime_error(
111 "cker::CategoricalCrossEntropy: y_pred and y_true do not have the same shape");
113 throw std::runtime_error(
114 "cker::CategoricalCrossEntropy: output and y_pred do not have the same batch");
120 output = -(y_true.array() * y_pred.array().cwiseMax(log_threshold<T>()).log()).colwise().sum();
125 const Shape &y_true_shape,
const T *y_true_data,
126 const Shape &grad_shape, T *grad_data,
129 if (y_pred_shape != y_true_shape)
130 throw std::runtime_error(
131 "cker::CategoricalCrossEntropyGrad: y_pred and y_true do not have the same shape");
132 if (y_pred_shape != grad_shape)
133 throw std::runtime_error(
134 "cker::CategoricalCrossEntropyGrad: y_pred and grad do not have the same shape");
140 const int32_t batch_size = grad_shape.
Dims(0);
141 int32_t reduction_size = 1;
142 switch (reduction_type)
145 reduction_size = batch_size;
151 throw std::runtime_error(
"Unsupported reduction type");
153 assert(reduction_size > 0);
155 grad = -(y_true.array() / y_pred.array().cwiseMax(log_threshold<T>())) /
156 static_cast<T
>(reduction_size);
161 const Shape &y_true_shape,
const T *y_true_data,
162 const Shape &loss_out_shape, T *loss_out_data,
163 const Shape &grad_shape, T *grad_data,
168 throw std::runtime_error(
169 "cker::CategoricalCrossEntropyWithLogits: loss output dimension count should be 1");
170 if (logits_shape != y_true_shape)
171 throw std::runtime_error(
172 "cker::CategoricalCrossEntropyWithLogits: logits and y_true do not have the same shape");
173 if (loss_out_shape.
Dims(0) != logits_shape.
Dims(0))
174 throw std::runtime_error(
175 "cker::CategoricalCrossEntropyWithLogits: loss_out and logits do not have the same batch");
176 if (logits_shape != grad_shape)
177 throw std::runtime_error(
178 "cker::CategoricalCrossEntropyWithLogits: logits and grad do not have the same shape");
180 auto shape_in = logits_shape;
193 logits_in.
shape.
ReplaceWith(shape_in.DimensionsCount(), shape_in.DimsData());
194 logits_in.
buffer =
const_cast<T *
>(logits_data);
197 labels_in.
buffer =
const_cast<T *
>(y_true_data);
200 std::vector<T> scratch_vec(shape_in.Dims(0) * shape_in.Dims(1),
static_cast<T
>(0));
201 scratch.
buffer = scratch_vec.data();
204 loss_out.
shape.
ReplaceWith(shape_loss_out.DimensionsCount(), shape_loss_out.DimsData());
205 loss_out.
buffer = loss_out_data;
207 back_out.
shape.
ReplaceWith(shape_in.DimensionsCount(), shape_in.DimsData());
208 back_out.
buffer = grad_data;
210 if (shape_in.Dims(0) > 0)
212 const int32_t batch_size = grad_shape.
Dims(0);
213 int32_t reduction_size = 1;
214 switch (reduction_type)
217 reduction_size = batch_size;
223 throw std::runtime_error(
"Unsupported reduction type");
225 assert(reduction_size > 0);
229 const Eigen::DSizes<Eigen::DenseIndex, 2> shape{shape_in.Dims(0), shape_in.Dims(1)};
231 functor(device, shape, BCast::ToIndexArray<2>(bcast.
x_bcast()),
232 BCast::ToIndexArray<2>(bcast.
y_bcast()),
233 logits_in.template shaped<const T, 2>(bcast.
x_reshape()),
234 labels_in.template shaped<const T, 2>(bcast.
y_reshape()), scratch.
matrix<T>(),
235 loss_out.
vec<T>(), back_out.
matrix<T>(),
static_cast<T
>(reduction_size));
static Vec FromShape(const Shape &shape)
const Vec & y_bcast() const
const Vec & x_reshape() const
const Vec & y_reshape() const
const Vec & x_bcast() const
int32_t DimensionsCount() const
void ReplaceWith(int dimensions_count, const int32_t *dims_data)
int32_t Dims(int i) const
__global uchar * offset(const Image *img, int x, int y)
const luci_interpreter::RuntimeShape output_shape
const Eigen::ThreadPoolDevice * GetThreadPoolDevice()
void CategoricalCrossEntropyGrad(const Shape &y_pred_shape, const T *y_pred_data, const Shape &y_true_shape, const T *y_true_data, const Shape &grad_shape, T *grad_data, LossReductionType reduction_type)
void CategoricalCrossEntropy(const Shape &y_pred_shape, const T *y_pred_data, const Shape &y_true_shape, const T *y_true_data, const Shape &output_shape, T *output_data)
void MSE(const Shape &y_pred_shape, const T *y_pred_data, const Shape &y_true_shape, const T *y_true_data, const Shape &output_shape, T *output_data)
void MSEGrad(const Shape &y_pred_shape, const T *y_pred_data, const Shape &y_true_shape, const T *y_true_data, const Shape &grad_shape, T *grad_data, LossReductionType reduction_type)
void CategoricalCrossEntropyWithLogits(const Shape &logits_shape, const T *logits_data, const Shape &y_true_shape, const T *y_true_data, const Shape &loss_out_shape, T *loss_out_data, const Shape &grad_shape, T *grad_data, LossReductionType reduction_type)
Eigen::ThreadPoolDevice CPUDevice
MatrixMap< Scalar > MapAsMatrixWithLastDimAsRows(Scalar *data, const Shape &shape)
int FlatSizeSkipDim(const Shape &shape, int skip_dim)
VectorMap< Scalar > MapAsVector(Scalar *data, const Shape &shape)
TTypes< T >::Matrix matrix()