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)
39template<
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(input, 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(input, outputA);
68 sin(i) = original + perturbation;
69 module.Forward(input, 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(input, deriv, delta);
95 jacobianB.col(i) = delta;
98 return arma::max(arma::max(arma::abs(jacobianA - jacobianB)));
104template <
typename ModuleType>
107 const double perturbation = 1e-6)
109 arma::mat output, outputA, outputB, jacobianA, jacobianB;
115 module.Forward(input, output);
116 jacobianA = arma::zeros(input.n_elem, output.n_elem);
118 for (
size_t i = 0; i < input.n_elem; ++i)
120 double original = input(i);
121 input(i) = original - perturbation;
122 module.Forward(input, outputA);
123 input(i) = original + perturbation;
124 module.Forward(input, outputB);
128 outputB /= 2 * perturbation;
129 jacobianA.row(i) = outputB.t();
133 arma::mat deriv = arma::zeros(output.n_rows, output.n_cols);
136 jacobianB = arma::zeros(input.n_elem, output.n_elem);
138 for (
size_t i = 0; i < deriv.n_elem; ++i)
144 module.Backward(input, deriv, delta);
146 jacobianB.col(i) = delta;
149 return arma::max(arma::max(arma::abs(jacobianA - jacobianB)));
154template<
typename ModuleType>
158 const double eps = 1e-6)
160 module.Forward(input, target);
163 module.Backward(input, target, delta);
165 arma::mat centralDifference = arma::zeros(delta.n_rows, delta.n_cols);
166 arma::mat inputTemp = arma::mat(input.memptr(), input.n_rows, input.n_cols,
169 arma::mat centralDifferenceTemp = arma::mat(centralDifference.memptr(),
170 centralDifference.n_rows, centralDifference.n_cols,
false,
false);
172 for (
size_t i = 0; i < input.n_elem; ++i)
174 inputTemp(i) = inputTemp(i) + eps;
175 double outputA = module.Forward(input, target);
176 inputTemp(i) = inputTemp(i) - (2 * eps);
177 double outputB = module.Forward(input, target);
179 centralDifferenceTemp(i) = (outputA - outputB) / (2 * eps);
180 inputTemp(i) = inputTemp(i) + eps;
183 return arma::max(arma::max(arma::abs(centralDifference - delta)));
187template<
class FunctionType>
191 arma::mat orgGradient, gradient, estGradient;
192 function.Gradient(orgGradient);
194 estGradient = arma::zeros(orgGradient.n_rows, orgGradient.n_cols);
197 for (
size_t i = 0; i < orgGradient.n_elem; ++i)
199 double tmp =
function.Parameters()(i);
202 function.Parameters()(i) += eps;
203 double costPlus =
function.Gradient(gradient);
206 function.Parameters()(i) -= (2 * eps);
207 double costMinus =
function.Gradient(gradient);
210 function.Parameters()(i) = tmp;
213 estGradient(i) = (costPlus - costMinus) / (2 * eps);
217 return arma::norm(orgGradient - estGradient) /
218 arma::norm(orgGradient + estGradient);
222template<
class FunctionType>
226 arma::mat weight = arma::randu(10, 10);
227 arma::mat orgGradient = arma::zeros(10 * 10, 1);
228 function.Gradient(weight, orgGradient);
230 arma::mat estGradient = arma::zeros(weight.n_rows, weight.n_cols);
233 for (
size_t i = 0; i < weight.n_rows; ++i)
235 for (
size_t j = 0; j < weight.n_cols; ++j)
237 double tmp = weight(i, j);
240 double costPlus =
function.Output(weight, i, j);
241 weight(i, j) -= (2 * eps);
242 double costMinus =
function.Output(weight, i, j);
246 estGradient(i, j) = (costPlus - costMinus) / (2 * eps);
250 estGradient = arma::vectorise(estGradient);
252 return arma::norm(orgGradient - estGradient) /
253 arma::norm(orgGradient + estGradient);
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...
Artificial Neural Network.
Linear algebra utility functions, generally performed on matrices or vectors.