1 #ifndef OUTPUT_MULTICLASSENTROPY_H_ 2 #define OUTPUT_MULTICLASSENTROPY_H_ 23 void check_target_data(
const Matrix& target)
27 const int nobs = target.cols();
28 const int nclass = target.rows();
29 for(
int i = 0; i < nobs; i++)
32 for(
int j = 0; j < nclass; j++)
34 if(target(j, i) == Scalar(1))
39 if(target(j, i) != Scalar(0))
40 throw std::invalid_argument(
"[class MultiClassEntropy]: Target data should only contain zero or one");
43 throw std::invalid_argument(
"[class MultiClassEntropy]: Each column of target data should only contain one \"1\"");
47 void check_target_data(
const IntegerVector& target)
50 const int nobs = target.size();
51 for(
int i = 0; i < nobs; i++)
54 throw std::invalid_argument(
"[class MultiClassEntropy]: Target data must be non-negative");
60 void evaluate(
const Matrix& prev_layer_data,
const Matrix& target)
63 const int nobs = prev_layer_data.cols();
64 const int nclass = prev_layer_data.rows();
65 if((target.cols() != nobs) || (target.rows() != nclass))
66 throw std::invalid_argument(
"[class MultiClassEntropy]: Target data have incorrect dimension");
72 m_din.resize(nclass, nobs);
73 m_din.noalias() = -target.cwiseQuotient(prev_layer_data);
78 void evaluate(
const Matrix& prev_layer_data,
const IntegerVector& target)
81 const int nobs = prev_layer_data.cols();
82 const int nclass = prev_layer_data.rows();
83 if(target.size() != nobs)
84 throw std::invalid_argument(
"[class MultiClassEntropy]: Target data have incorrect dimension");
90 m_din.resize(nclass, nobs);
92 for(
int i = 0; i < nobs; i++)
94 m_din(target[i], i) = -Scalar(1) / prev_layer_data(target[i], i);
98 const Matrix& backprop_data()
const 109 Scalar res = Scalar(0);
110 const int nelem = m_din.size();
111 const Scalar* din_data = m_din.data();
112 for(
int i = 0; i < nelem; i++)
114 if(din_data[i] < Scalar(0))
115 res += std::log(-din_data[i]);
118 return res / m_din.cols();