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(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)));
104 template <
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)));
154 template<
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)));
187 template<
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);
222 template<
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);
Artificial Neural Network.
Linear algebra utility functions, generally performed on matrices or vectors.
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...