12 #ifndef MLPACK_TESTS_ANN_TEST_TOOLS_HPP 13 #define MLPACK_TESTS_ANN_TEST_TOOLS_HPP 24 typename std::enable_if<HasResetCheck<T,
void(T::*)()>::value>::type* = 0)
32 typename std::enable_if<!HasResetCheck<T,
void(T::*)()>::value>::type* = 0)
39 template<
typename ModuleType>
42 const double minValue = -2,
43 const double maxValue = -1,
44 const double perturbation = 1e-6)
46 arma::mat output, outputA, outputB, jacobianA, jacobianB;
50 init.
Initialize(input, input.n_rows, input.n_cols);
56 module.Forward(std::move(input), std::move(output));
57 jacobianA = arma::zeros(input.n_elem, output.n_elem);
60 arma::mat sin = arma::mat(input.memptr(), input.n_rows, input.n_cols,
63 for (
size_t i = 0; i < input.n_elem; ++i)
65 double original = sin(i);
66 sin(i) = original - perturbation;
67 module.Forward(std::move(input), std::move(outputA));
68 sin(i) = original + perturbation;
69 module.Forward(std::move(input), std::move(outputB));
73 outputB /= 2 * perturbation;
74 jacobianA.row(i) = outputB.t();
78 arma::mat deriv = arma::zeros(output.n_rows, output.n_cols);
81 arma::mat derivTemp = arma::mat(deriv.memptr(), deriv.n_rows, deriv.n_cols,
85 jacobianB = arma::zeros(input.n_elem, output.n_elem);
87 for (
size_t i = 0; i < derivTemp.n_elem; ++i)
93 module.Backward(std::move(input), std::move(deriv), std::move(delta));
95 jacobianB.col(i) = delta;
98 return arma::max(arma::max(arma::abs(jacobianA - jacobianB)));
103 template<
typename ModuleType>
107 const double eps = 1e-6)
109 module.Forward(std::move(input), std::move(target));
112 module.Backward(std::move(input), std::move(target), std::move(delta));
114 arma::mat centralDifference = arma::zeros(delta.n_rows, delta.n_cols);
115 arma::mat inputTemp = arma::mat(input.memptr(), input.n_rows, input.n_cols,
118 arma::mat centralDifferenceTemp = arma::mat(centralDifference.memptr(),
119 centralDifference.n_rows, centralDifference.n_cols,
false,
false);
121 for (
size_t i = 0; i < input.n_elem; ++i)
123 inputTemp(i) = inputTemp(i) + eps;
124 double outputA = module.Forward(std::move(input), std::move(target));
125 inputTemp(i) = inputTemp(i) - (2 * eps);
126 double outputB = module.Forward(std::move(input), std::move(target));
128 centralDifferenceTemp(i) = (outputA - outputB) / (2 * eps);
129 inputTemp(i) = inputTemp(i) + eps;
132 return arma::max(arma::max(arma::abs(centralDifference - delta)));
136 template<
class FunctionType>
140 arma::mat orgGradient, gradient, estGradient;
141 function.Gradient(orgGradient);
143 estGradient = arma::zeros(orgGradient.n_rows, orgGradient.n_cols);
146 for (
size_t i = 0; i < orgGradient.n_elem; ++i)
148 double tmp =
function.Parameters()(i);
151 function.Parameters()(i) += eps;
152 double costPlus =
function.Gradient(gradient);
155 function.Parameters()(i) -= (2 * eps);
156 double costMinus =
function.Gradient(gradient);
159 function.Parameters()(i) = tmp;
162 estGradient(i) = (costPlus - costMinus) / (2 * eps);
166 return arma::norm(orgGradient - estGradient) /
167 arma::norm(orgGradient + estGradient);
171 template<
class FunctionType>
175 arma::mat weight = arma::randu(10, 10);
176 arma::mat orgGradient = arma::zeros(10 * 10, 1);
177 function.Gradient(weight, orgGradient);
179 arma::mat estGradient = arma::zeros(weight.n_rows, weight.n_cols);
182 for (
size_t i = 0; i < weight.n_rows; ++i)
184 for (
size_t j = 0; j < weight.n_cols; ++j)
186 double tmp = weight(i, j);
189 double costPlus =
function.Output(weight, i, j);
190 weight(i, j) -= (2 * eps);
191 double costMinus =
function.Output(weight, i, j);
195 estGradient(i, j) = (costPlus - costMinus) / (2 * eps);
199 estGradient = arma::vectorise(estGradient);
201 return arma::norm(orgGradient - estGradient) /
202 arma::norm(orgGradient + estGradient);
Artificial Neural Network.
This class is used to initialize randomly the weight matrix.
void Initialize(arma::Mat< eT > &W, const size_t rows, const size_t cols)
Initialize randomly the elements of the specified weight matrix.
Include all of the base components required to write mlpack methods, and the main mlpack Doxygen docu...