12 #ifndef MLPACK_METHODS_ANN_FFN_IMPL_HPP 13 #define MLPACK_METHODS_ANN_FFN_IMPL_HPP 32 template<
typename OutputLayerType,
typename InitializationRuleType,
33 typename... CustomLayers>
35 OutputLayerType outputLayer, InitializationRuleType initializeRule) :
36 outputLayer(
std::move(outputLayer)),
37 initializeRule(
std::move(initializeRule)),
47 template<
typename OutputLayerType,
typename InitializationRuleType,
48 typename... CustomLayers>
51 std::for_each(network.begin(), network.end(),
52 boost::apply_visitor(deleteVisitor));
55 template<
typename OutputLayerType,
typename InitializationRuleType,
56 typename... CustomLayers>
58 arma::mat predictors, arma::mat responses)
60 numFunctions = responses.n_cols;
61 this->predictors = std::move(predictors);
62 this->responses = std::move(responses);
63 this->deterministic =
false;
70 template<
typename OutputLayerType,
typename InitializationRuleType,
71 typename... CustomLayers>
72 template<
typename OptimizerType>
73 typename std::enable_if<
74 HasMaxIterations<OptimizerType, size_t&(OptimizerType::*)()>
79 if (optimizer.MaxIterations() < samples &&
80 optimizer.MaxIterations() != 0)
82 Log::Warn <<
"The optimizer's maximum number of iterations " 83 <<
"is less than the size of the dataset; the " 84 <<
"optimizer will not pass over the entire " 85 <<
"dataset. To fix this, modify the maximum " 86 <<
"number of iterations to be at least equal " 87 <<
"to the number of points of your dataset " 88 <<
"(" << samples <<
")." << std::endl;
92 template<
typename OutputLayerType,
typename InitializationRuleType,
93 typename... CustomLayers>
94 template<
typename OptimizerType>
95 typename std::enable_if<
96 !HasMaxIterations<OptimizerType, size_t&(OptimizerType::*)()>
105 template<
typename OutputLayerType,
typename InitializationRuleType,
106 typename... CustomLayers>
107 template<
typename OptimizerType,
typename... CallbackTypes>
109 arma::mat predictors,
111 OptimizerType& optimizer,
112 CallbackTypes&&... callbacks)
114 CheckInputShape<std::vector<LayerTypes<CustomLayers...> > >(network,
118 ResetData(std::move(predictors), std::move(responses));
120 WarnMessageMaxIterations<OptimizerType>(optimizer, this->predictors.n_cols);
124 const double out = optimizer.Optimize(*
this, parameter, callbacks...);
127 Log::Info <<
"FFN::FFN(): final objective of trained model is " << out
132 template<
typename OutputLayerType,
typename InitializationRuleType,
133 typename... CustomLayers>
134 template<
typename OptimizerType,
typename... CallbackTypes>
136 arma::mat predictors,
138 CallbackTypes&&... callbacks)
140 CheckInputShape<std::vector<LayerTypes<CustomLayers...> > >(network,
144 ResetData(std::move(predictors), std::move(responses));
146 OptimizerType optimizer;
148 WarnMessageMaxIterations<OptimizerType>(optimizer, this->predictors.n_cols);
152 const double out = optimizer.Optimize(*
this, parameter, callbacks...);
155 Log::Info <<
"FFN::FFN(): final objective of trained model is " << out
160 template<
typename OutputLayerType,
typename InitializationRuleType,
161 typename... CustomLayers>
162 template<
typename PredictorsType,
typename ResponsesType>
164 const PredictorsType& inputs, ResponsesType& results)
166 if (parameter.is_empty())
170 results = boost::apply_visitor(outputParameterVisitor, network.back());
173 template<
typename OutputLayerType,
typename InitializationRuleType,
174 typename... CustomLayers>
175 template<
typename PredictorsType,
typename ResponsesType>
177 const PredictorsType& inputs,
178 ResponsesType& results,
183 boost::apply_visitor(outputParameterVisitor, network[begin])),
186 for (
size_t i = 1; i < end - begin + 1; ++i)
189 outputParameterVisitor, network[begin + i - 1]),
190 boost::apply_visitor(outputParameterVisitor, network[begin + i])),
194 results = boost::apply_visitor(outputParameterVisitor, network[end]);
197 template<
typename OutputLayerType,
typename InitializationRuleType,
198 typename... CustomLayers>
199 template<
typename PredictorsType,
typename TargetsType,
typename GradientsType>
201 const PredictorsType& inputs,
202 const TargetsType& targets,
203 GradientsType& gradients)
205 double res = outputLayer.Forward(boost::apply_visitor(
206 outputParameterVisitor, network.back()), targets);
208 for (
size_t i = 0; i < network.size(); ++i)
210 res += boost::apply_visitor(lossVisitor, network[i]);
213 outputLayer.Backward(boost::apply_visitor(outputParameterVisitor,
214 network.back()), targets, error);
216 gradients = arma::zeros<arma::mat>(parameter.n_rows, parameter.n_cols);
219 ResetGradients(gradients);
225 template<
typename OutputLayerType,
typename InitializationRuleType,
226 typename... CustomLayers>
228 arma::mat predictors, arma::mat& results)
230 CheckInputShape<std::vector<LayerTypes<CustomLayers...> > >(
231 network, predictors.n_rows,
"FFN<>::Predict()");
233 if (parameter.is_empty())
238 deterministic =
true;
239 ResetDeterministic();
242 arma::mat resultsTemp;
243 Forward(arma::mat(predictors.colptr(0), predictors.n_rows, 1,
false,
true));
244 resultsTemp = boost::apply_visitor(outputParameterVisitor,
245 network.back()).col(0);
247 results = arma::mat(resultsTemp.n_elem, predictors.n_cols);
248 results.col(0) = resultsTemp.col(0);
250 for (
size_t i = 1; i < predictors.n_cols; ++i)
252 Forward(arma::mat(predictors.colptr(i), predictors.n_rows, 1,
false,
true));
254 resultsTemp = boost::apply_visitor(outputParameterVisitor,
256 results.col(i) = resultsTemp.col(0);
260 template<
typename OutputLayerType,
typename InitializationRuleType,
261 typename... CustomLayers>
262 template<
typename PredictorsType,
typename ResponsesType>
264 const PredictorsType& predictors,
const ResponsesType& responses)
266 CheckInputShape<std::vector<LayerTypes<CustomLayers...> > >(
267 network, predictors.n_rows,
"FFN<>::Evaluate()");
269 if (parameter.is_empty())
274 deterministic =
true;
275 ResetDeterministic();
280 double res = outputLayer.Forward(boost::apply_visitor(
281 outputParameterVisitor, network.back()), responses);
283 for (
size_t i = 0; i < network.size(); ++i)
285 res += boost::apply_visitor(lossVisitor, network[i]);
291 template<
typename OutputLayerType,
typename InitializationRuleType,
292 typename... CustomLayers>
294 const arma::mat& parameters)
297 for (
size_t i = 0; i < predictors.n_cols; ++i)
298 res +=
Evaluate(parameters, i, 1,
true);
303 template<
typename OutputLayerType,
typename InitializationRuleType,
304 typename... CustomLayers>
308 const size_t batchSize,
309 const bool deterministic)
311 if (parameter.is_empty())
314 if (deterministic != this->deterministic)
316 this->deterministic = deterministic;
317 ResetDeterministic();
320 Forward(predictors.cols(begin, begin + batchSize - 1));
321 double res = outputLayer.Forward(
322 boost::apply_visitor(outputParameterVisitor, network.back()),
323 responses.cols(begin, begin + batchSize - 1));
325 for (
size_t i = 0; i < network.size(); ++i)
327 res += boost::apply_visitor(lossVisitor, network[i]);
333 template<
typename OutputLayerType,
typename InitializationRuleType,
334 typename... CustomLayers>
336 const arma::mat& parameters,
const size_t begin,
const size_t batchSize)
338 return Evaluate(parameters, begin, batchSize,
true);
341 template<
typename OutputLayerType,
typename InitializationRuleType,
342 typename... CustomLayers>
343 template<
typename GradType>
348 for (
size_t i = 0; i < predictors.n_cols; ++i)
354 template<
typename OutputLayerType,
typename InitializationRuleType,
355 typename... CustomLayers>
356 template<
typename GradType>
361 const size_t batchSize)
363 if (gradient.is_empty())
365 if (parameter.is_empty())
368 gradient = arma::zeros<arma::mat>(parameter.n_rows, parameter.n_cols);
375 if (this->deterministic)
377 this->deterministic =
false;
378 ResetDeterministic();
381 Forward(predictors.cols(begin, begin + batchSize - 1));
382 double res = outputLayer.Forward(
383 boost::apply_visitor(outputParameterVisitor, network.back()),
384 responses.cols(begin, begin + batchSize - 1));
386 for (
size_t i = 0; i < network.size(); ++i)
388 res += boost::apply_visitor(lossVisitor, network[i]);
391 outputLayer.Backward(
392 boost::apply_visitor(outputParameterVisitor, network.back()),
393 responses.cols(begin, begin + batchSize - 1),
397 ResetGradients(gradient);
398 Gradient(predictors.cols(begin, begin + batchSize - 1));
403 template<
typename OutputLayerType,
typename InitializationRuleType,
404 typename... CustomLayers>
406 const arma::mat& parameters,
409 const size_t batchSize)
414 template<
typename OutputLayerType,
typename InitializationRuleType,
415 typename... CustomLayers>
421 template<
typename OutputLayerType,
typename InitializationRuleType,
422 typename... CustomLayers>
423 void FFN<OutputLayerType, InitializationRuleType,
426 ResetDeterministic();
430 CustomLayers...> networkInit(initializeRule);
431 networkInit.Initialize(network, parameter);
434 template<
typename OutputLayerType,
typename InitializationRuleType,
435 typename... CustomLayers>
436 void FFN<OutputLayerType, InitializationRuleType,
437 CustomLayers...>::ResetDeterministic()
440 std::for_each(network.begin(), network.end(),
441 boost::apply_visitor(deterministicSetVisitor));
444 template<
typename OutputLayerType,
typename InitializationRuleType,
445 typename... CustomLayers>
446 void FFN<OutputLayerType, InitializationRuleType,
447 CustomLayers...>::ResetGradients(arma::mat& gradient)
450 for (
size_t i = 0; i < network.size(); ++i)
457 template<
typename OutputLayerType,
typename InitializationRuleType,
458 typename... CustomLayers>
459 template<
typename InputType>
460 void FFN<OutputLayerType, InitializationRuleType,
461 CustomLayers...>
::Forward(
const InputType& input)
464 boost::apply_visitor(outputParameterVisitor, network.front())),
469 if (boost::apply_visitor(outputWidthVisitor, network.front()) != 0)
471 width = boost::apply_visitor(outputWidthVisitor, network.front());
474 if (boost::apply_visitor(outputHeightVisitor, network.front()) != 0)
476 height = boost::apply_visitor(outputHeightVisitor, network.front());
480 for (
size_t i = 1; i < network.size(); ++i)
492 outputParameterVisitor, network[i - 1]),
493 boost::apply_visitor(outputParameterVisitor, network[i])), network[i]);
498 if (boost::apply_visitor(outputWidthVisitor, network[i]) != 0)
500 width = boost::apply_visitor(outputWidthVisitor, network[i]);
504 if (boost::apply_visitor(outputHeightVisitor, network[i]) != 0)
506 height = boost::apply_visitor(outputHeightVisitor, network[i]);
515 template<
typename OutputLayerType,
typename InitializationRuleType,
516 typename... CustomLayers>
520 outputParameterVisitor, network.back()), error,
521 boost::apply_visitor(deltaVisitor, network.back())), network.back());
523 for (
size_t i = 2; i < network.size(); ++i)
526 outputParameterVisitor, network[network.size() - i]),
527 boost::apply_visitor(deltaVisitor, network[network.size() - i + 1]),
528 boost::apply_visitor(deltaVisitor, network[network.size() - i])),
529 network[network.size() - i]);
533 template<
typename OutputLayerType,
typename InitializationRuleType,
534 typename... CustomLayers>
535 template<
typename InputType>
536 void FFN<OutputLayerType, InitializationRuleType,
537 CustomLayers...>
::Gradient(
const InputType& input)
540 boost::apply_visitor(deltaVisitor, network[1])), network.front());
542 for (
size_t i = 1; i < network.size() - 1; ++i)
545 outputParameterVisitor, network[i - 1]),
546 boost::apply_visitor(deltaVisitor, network[i + 1])), network[i]);
550 outputParameterVisitor, network[network.size() - 2]), error),
551 network[network.size() - 1]);
554 template<
typename OutputLayerType,
typename InitializationRuleType,
555 typename... CustomLayers>
556 template<
typename Archive>
558 Archive& ar,
const uint32_t )
560 ar(CEREAL_NVP(parameter));
561 ar(CEREAL_NVP(width));
562 ar(CEREAL_NVP(height));
564 ar(CEREAL_NVP(reset));
567 if (cereal::is_loading<Archive>())
569 std::for_each(network.begin(), network.end(),
570 boost::apply_visitor(deleteVisitor));
577 if (cereal::is_loading<Archive>())
580 for (
size_t i = 0; i < network.size(); ++i)
585 boost::apply_visitor(resetVisitor, network[i]);
588 deterministic =
true;
589 ResetDeterministic();
593 template<
typename OutputLayerType,
typename InitializationRuleType,
594 typename... CustomLayers>
595 void FFN<OutputLayerType, InitializationRuleType,
596 CustomLayers...>::Swap(
FFN& network)
598 std::swap(outputLayer, network.outputLayer);
599 std::swap(initializeRule, network.initializeRule);
600 std::swap(width, network.width);
601 std::swap(height, network.height);
602 std::swap(reset, network.reset);
603 std::swap(this->network, network.network);
604 std::swap(predictors, network.predictors);
605 std::swap(responses, network.responses);
606 std::swap(parameter, network.parameter);
607 std::swap(numFunctions, network.numFunctions);
608 std::swap(error, network.error);
609 std::swap(deterministic, network.deterministic);
610 std::swap(delta, network.delta);
611 std::swap(inputParameter, network.inputParameter);
612 std::swap(outputParameter, network.outputParameter);
613 std::swap(gradient, network.gradient);
616 template<
typename OutputLayerType,
typename InitializationRuleType,
617 typename... CustomLayers>
620 outputLayer(network.outputLayer),
621 initializeRule(network.initializeRule),
622 width(network.width),
623 height(network.height),
624 reset(network.reset),
625 predictors(network.predictors),
626 responses(network.responses),
627 parameter(network.parameter),
628 numFunctions(network.numFunctions),
629 error(network.error),
630 deterministic(network.deterministic),
631 delta(network.delta),
632 inputParameter(network.inputParameter),
633 outputParameter(network.outputParameter),
634 gradient(network.gradient)
637 for (
size_t i = 0; i < network.network.size(); ++i)
639 this->network.push_back(boost::apply_visitor(copyVisitor,
640 network.network[i]));
641 boost::apply_visitor(resetVisitor, this->network.back());
645 template<
typename OutputLayerType,
typename InitializationRuleType,
646 typename... CustomLayers>
649 outputLayer(
std::move(network.outputLayer)),
650 initializeRule(
std::move(network.initializeRule)),
651 width(network.width),
652 height(network.height),
653 reset(network.reset),
654 predictors(
std::move(network.predictors)),
655 responses(
std::move(network.responses)),
656 parameter(
std::move(network.parameter)),
657 numFunctions(network.numFunctions),
658 error(
std::move(network.error)),
659 deterministic(network.deterministic),
660 delta(
std::move(network.delta)),
661 inputParameter(
std::move(network.inputParameter)),
662 outputParameter(
std::move(network.outputParameter)),
663 gradient(
std::move(network.gradient))
665 this->network = std::move(network.network);
668 template<
typename OutputLayerType,
typename InitializationRuleType,
669 typename... CustomLayers>
670 FFN<OutputLayerType, InitializationRuleType, CustomLayers...>&
671 FFN<OutputLayerType, InitializationRuleType,
672 CustomLayers...>::operator = (
FFN network)
static void Start(const std::string &name)
Start the given timer.
Definition: timers.cpp:28
BackwardVisitor executes the Backward() function given the input, error and delta parameter...
Definition: backward_visitor.hpp:28
double EvaluateWithGradient(const arma::mat ¶meters, GradType &gradient)
Evaluate the feedforward network with the given parameters.
Definition: ffn_impl.hpp:345
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
std::enable_if< HasMaxIterations< OptimizerType, size_t &(OptimizerType::*)()>::value, void >::type WarnMessageMaxIterations(OptimizerType &optimizer, size_t samples) const
Check if the optimizer has MaxIterations() parameter, if it does then check if it's value is less tha...
Definition: ffn_impl.hpp:77
Definition: pointer_wrapper.hpp:23
GradientSetVisitor update the gradient parameter given the gradient set.
Definition: gradient_set_visitor.hpp:26
FFN(OutputLayerType outputLayer=OutputLayerType(), InitializationRuleType initializeRule=InitializationRuleType())
Create the FFN object.
Definition: ffn_impl.hpp:34
void ResetParameters()
Reset the module infomration (weights/parameters).
Definition: ffn_impl.hpp:424
DeterministicSetVisitor set the deterministic parameter given the deterministic value.
Definition: deterministic_set_visitor.hpp:28
double Backward(const PredictorsType &inputs, const TargetsType &targets, GradientsType &gradients)
Perform the backward pass of the data in real batch mode.
Definition: ffn_impl.hpp:200
WeightSetVisitor update the module parameters given the parameters set.
Definition: weight_set_visitor.hpp:26
static MLPACK_EXPORT util::PrefixedOutStream Warn
Prints warning messages prefixed with [WARN ].
Definition: log.hpp:87
void serialize(Archive &ar, const uint32_t)
Serialize the model.
Definition: ffn_impl.hpp:557
ForwardVisitor executes the Forward() function given the input and output parameter.
Definition: forward_visitor.hpp:28
~FFN()
Destructor to release allocated memory.
Definition: ffn_impl.hpp:49
static void Stop(const std::string &name)
Stop the given timer.
Definition: timers.cpp:36
SearchModeVisitor executes the Gradient() method of the given module using the input and delta parame...
Definition: gradient_visitor.hpp:28
void ShuffleData(const MatType &inputPoints, const LabelsType &inputLabels, MatType &outputPoints, LabelsType &outputLabels, const std::enable_if_t<!arma::is_SpMat< MatType >::value > *=0, const std::enable_if_t<!arma::is_Cube< MatType >::value > *=0)
Shuffle a dataset and associated labels (or responses).
Definition: shuffle_data.hpp:28
void Forward(const PredictorsType &inputs, ResponsesType &results)
Perform the forward pass of the data in real batch mode.
Definition: ffn_impl.hpp:163
void Shuffle()
Shuffle the order of function visitation.
Definition: ffn_impl.hpp:416
static MLPACK_EXPORT util::PrefixedOutStream Info
Prints informational messages if –verbose is specified, prefixed with [INFO ].
Definition: log.hpp:84
void Gradient(const arma::mat ¶meters, const size_t begin, arma::mat &gradient, const size_t batchSize)
Evaluate the gradient of the feedforward network with the given parameters, and with respect to only ...
Definition: ffn_impl.hpp:405
Implementation of a standard feed forward network.
Definition: ffn.hpp:52
This class is used to initialize the network with the given initialization rule.
Definition: network_init.hpp:33
void Predict(arma::mat predictors, arma::mat &results)
Predict the responses to a given set of predictors.
Definition: ffn_impl.hpp:227
double Train(arma::mat predictors, arma::mat responses, OptimizerType &optimizer, CallbackTypes &&... callbacks)
Train the feedforward network on the given input data using the given optimizer.
Definition: ffn_impl.hpp:108
double Evaluate(const PredictorsType &predictors, const ResponsesType &responses)
Evaluate the feedforward network with the given predictors and responses.
Definition: ffn_impl.hpp:263
#define CEREAL_VECTOR_VARIANT_POINTER(T)
Cereal does not support the serialization of raw pointer.
Definition: pointer_vector_variant_wrapper.hpp:92