Merge remote-tracking branch 'upstream/master' into TfIdf-and-BagOfWords-fixes

This commit is contained in:
Mikhail Lozhnikov
2020-04-04 15:30:06 +03:00
34 changed files with 406 additions and 64 deletions
-17
View File
@@ -57,23 +57,6 @@ jobs:
steps:
- template: macos-steps.yaml
- job: WindowsVS14
timeoutInMinutes: 360
displayName: Windows VS14
pool:
vmImage: vs2015-win2012r2
strategy:
matrix:
Plain:
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF'
CMakeGenerator: '-G "Visual Studio 14 2015 Win64"'
MSBuildVersion: '14.0'
ArchiveNoLibs: 'mlpack-windows-vs14-no-libs.zip'
ArchiveLibs: 'mlpack-windows-vs14.zip'
ArchiveTests: 'mlpack_test-vs14.xml'
steps:
- template: windows-steps.yaml
- job: WindowsVS15
timeoutInMinutes: 360
displayName: Windows VS15
+1
View File
@@ -130,6 +130,7 @@ Copyright:
Copyright 2020, Saraansh Tandon <saraanshtandon1999@gmail.com>
Copyright 2020, Gaurav Singh <gs8763076@gmail.com>
Copyright 2020, Lakshya Ojha <ojhalakshya@gmail.com>
Copyright 2020, Bisakh Mondal <bisakhmondal00@gmail.com>
License: BSD-3-clause
All rights reserved.
+4
View File
@@ -1,5 +1,9 @@
### mlpack ?.?.?
###### ????-??-??
* Templated return type of `Forward function` of loss functions (#2339).
* Added `R2 Score` regression metric (#2323).
* Added `mean squared logarithmic error` loss function for neural networks
(#2210).
@@ -1,6 +1,7 @@
/*!
@file rl.txt
@author Sriram S K
@author Joel Joseph
@brief Tutorial for how to use the Reinforcement Learning module in mlpack.
@page rltutorial Reinforcement Learning Tutorial
@@ -29,6 +30,7 @@ This tutorial is split into the following sections:
- \ref environment_rltut
- \ref agent_components_rltut
- \ref q_learning_rltut
- \ref async_learning_rltut
- \ref further_rltut
@section environment_rltut Reinforcement Learning Environments
@@ -231,9 +233,167 @@ to have converged when the average return reaches a predetermined value (i.e. >
Conversely, if the average return does not go beyond that amount even after a thousand
episodes, we can conclude that the agent will not converge and exit the training loop.
@section async_learning_rltut
In 2016, Researchers at Deepmind and University of Montreal published their paper
"Asynchronous Methods for Deep Reinforcement Learning". In it they described asynchronous
variants of four standard reinforcement learning algorithms:
- One-Step SARSA
- One-Step Q-Learning
- N-Step Q-Learning
- Advantage Actor-Critic(A3C)
Online RL algorithms and Deep Neural Networks make an unstable combination because of the
non-stationary and correlated nature of online updates. Although this is solved by Experience Replay,
it has several drawbacks: it uses more memory and computation per real interaction; and it requires
off-policy learning algorithms.
Asynchronous methods, instead of experience replay, asynchronously executes multiple agents
in parallel, on multiple instances of the environment, which solves all the above problems.
Here, we demonstrate Asynchronous Learning methods in mlpack through the training of an async
agent. Asynchronous learning involves training several agents simultaneously. Here, each of the
agents are referred to as "workers". Currently mlpack has One-Step Q-Learning worker, N-Step
Q-Learning worker and One-Step SARSA worker.
Let's examine the sample code in chunks.
Apart from the includes used for the q-learning example, two more have to be included:
@code
#include <mlpack/methods/reinforcement_learning/async_learning.hpp>
#include <mlpack/methods/reinforcement_learning/policy/aggregated_policy.hpp>
@endcode
Here we don't use experience replay, and instead of a single policy, we use three different
policies, each corresponding to its worker. Number of workers created, depends on the number of
policies given in the Aggregated Policy. The column vector contains the probability distribution
for each child policy. We should make sure its size is same as the number of policies and the sum
of its elements is equal to 1.
@code
AggregatedPolicy<GreedyPolicy<CartPole>> policy({GreedyPolicy<CartPole>(0.7, 5000, 0.1),
GreedyPolicy<CartPole>(0.7, 5000, 0.01),
GreedyPolicy<CartPole>(0.7, 5000, 0.5)},
arma::colvec("0.4 0.3 0.3"));
@endcode
Now, we will create the "OneStepQLearning" agent. We could have used "NStepQLearning" or "OneStepSarsa"
here according to our requirement.
@code
OneStepQLearning<CartPole, decltype(model), ens::AdamUpdate, decltype(policy)>
agent(std::move(config), std::move(model), std::move(policy));
@endcode
Here, unlike the Q-Learning example, instead of the entire while loop, we use the Train method of the Asynchronous
Learning class inside a for loop. 100 training episodes will take around 50 seconds.
@code
for (int i = 0; i < 100; i++)
{
agent.Train(measure);
}
@endcode
What is "measure" here? It is a lambda function which returns a boolean value (indicating the end of training)
and accepts the episode return (total reward of a deterministic test episode) as parameter.
So, let's create that.
@code
arma::vec returns(20, arma::fill::zeros);
size_t position = 0;
size_t episode = 0;
auto measure = [&returns, &position, &episode](double episodeReturn)
{
if(episode > 10000) return true;
returns[position++] = episodeReturn;
position = position % returns.n_elem;
episode++;
std::cout << "Episode No.: " << episode
<< "; Episode Return: " << episodeReturn
<< "; Average Return: " << arma::mean(returns) << endl;
};
@endcode
This will train three different agents on three CPU threads asynchronously and use this data to update the
action value estimate.
Voila, thats all there is to it.
Here is the full code to try this right away:
@code
#include <mlpack/core.hpp>
#include <mlpack/methods/ann/ffn.hpp>
#include <mlpack/methods/ann/init_rules/gaussian_init.hpp>
#include <mlpack/methods/ann/layer/layer.hpp>
#include <mlpack/methods/ann/loss_functions/mean_squared_error.hpp>
#include <mlpack/methods/reinforcement_learning/async_learning.hpp>
#include <mlpack/methods/reinforcement_learning/environment/cart_pole.hpp>
#include <mlpack/methods/reinforcement_learning/policy/greedy_policy.hpp>
#include <mlpack/methods/reinforcement_learning/policy/aggregated_policy.hpp>
#include <mlpack/methods/reinforcement_learning/training_config.hpp>
#include <ensmallen.hpp>
using namespace mlpack;
using namespace mlpack::ann;
using namespace mlpack::rl;
int main()
{
// Set up the network.
FFN<MeanSquaredError<>, GaussianInitialization> model(MeanSquaredError<>(), GaussianInitialization(0, 0.001));
model.Add<Linear<>>(4, 128);
model.Add<ReLULayer<>>();
model.Add<Linear<>>(128, 128);
model.Add<ReLULayer<>>();
model.Add<Linear<>>(128, 2);
AggregatedPolicy<GreedyPolicy<CartPole>> policy({GreedyPolicy<CartPole>(0.7, 5000, 0.1),
GreedyPolicy<CartPole>(0.7, 5000, 0.01),
GreedyPolicy<CartPole>(0.7, 5000, 0.5)},
arma::colvec("0.4 0.3 0.3"));
TrainingConfig config;
config.StepSize() = 0.01;
config.Discount() = 0.9;
config.TargetNetworkSyncInterval() = 100;
config.ExplorationSteps() = 100;
config.DoubleQLearning() = false;
config.StepLimit() = 200;
OneStepQLearning<CartPole, decltype(model), ens::VanillaUpdate, decltype(policy)>
agent(std::move(config), std::move(model), std::move(policy));
arma::vec returns(20, arma::fill::zeros);
size_t position = 0;
size_t episode = 0;
auto measure = [&returns, &position, &episode](double episodeReturn)
{
if(episode > 10000) return true;
returns[position++] = episodeReturn;
position = position % returns.n_elem;
episode++;
std::cout << "Episode No.: " << episode
<< "; Episode Return: " << episodeReturn
<< "; Average Return: " << arma::mean(returns) << endl;
};
for (int i = 0; i < 100; i++)
{
agent.Train(measure);
}
}
@endcode
@section further_rltut Further documentation
For further documentation on the rl classes, consult the \ref mlpack::rl
"complete API documentation".
*/
*/
@@ -13,6 +13,8 @@ set(SOURCES
precision_impl.hpp
recall.hpp
recall_impl.hpp
r2_score.hpp
r2_score_impl.hpp
)
# Add directory name to sources.
+76
View File
@@ -0,0 +1,76 @@
/**
* @file r2_score.hpp
* @author Bisakh Mondal
*
* The R^2 (Coefficient of determination) regression metric.
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_CORE_CV_METRICS_R2SCORE_HPP
#define MLPACK_CORE_CV_METRICS_R2SCORE_HPP
#include <mlpack/core.hpp>
namespace mlpack {
namespace cv {
/**
* The R2 Score is a metric of performance for regression algorithms
* that represents the proportion of variance (here y) that has been
* explained by the independent variables in the model. It provides
* an indication of goodness of fit and therefore a measure of how
* well unseen samples are likely to be predicted by the model,
* through the proportion of explained variance.
* As R2 Score is dataset dependent it can have wide range of values. The
* best possible score is @f$R^2 =1.0@f$. Values of R2 outside the range
* 0 to 1 can occur when the model fits the data worse than a horizontal
* hyperplane. This would occur when the wrong model was chosen, or
* nonsensical constraints were applied by mistake. A model which
* predicts exactly the expected value of y, disregarding the input
* features, gets a R2 Score equals to 0.0.
* If a model predicts @f$ \hat{y}_i $@f of the @f$ i $@f-th sample for a true
* @f$ y_i $@f for total n samples, the R2 Score is calculated by
* @f{eqnarray*}{
* R^{2} \left( y, \hat{y} \right) &=& 1-\frac{\sum_{i=1}^{n}
* \left( y_i - \hat{y_i} \right)^2 }
* {\sum_{i=1}^{n} \left( y_i - \bar{y}\right)^2}\\
* @f}
*
* where @f$ \bar{y} = frac{1}{y}\sum_{i=1}^{n} y_i $@f.
* For example, a model having R2Score = 0.85, explains 85 \% variability of
* the response data around its mean.
*/
class R2Score
{
public:
/**
* Run prediction and calculate the R squared error.
*
* @param model A regression model.
* @param data Column-major data containing test items.
* @param responses Ground truth (correct) target values for the test items,
* should be either a row vector or a column-major matrix.
* @return calculated R2 Score.
*/
template<typename MLAlgorithm, typename DataType, typename ResponsesType>
static double Evaluate(MLAlgorithm& model,
const DataType& data,
const ResponsesType& responses);
/**
* Information for hyper-parameter tuning code. It indicates that we want
* to maximize the measurement.
*/
static const bool NeedsMinimization = false;
};
} // namespace cv
} // namespace mlpack
// Include implementation.
#include "r2_score_impl.hpp"
#endif
@@ -0,0 +1,55 @@
/**
* @file r2_score_impl.hpp
* @author Bisakh Mondal
*
* The implementation of the class R2Score.
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_CORE_CV_METRICS_R2SCORE_IMPL_HPP
#define MLPACK_CORE_CV_METRICS_R2SCORE_IMPL_HPP
namespace mlpack {
namespace cv {
template<typename MLAlgorithm, typename DataType, typename ResponsesType>
double R2Score::Evaluate(MLAlgorithm& model,
const DataType& data,
const ResponsesType& responses)
{
if (data.n_cols != responses.n_cols)
{
std::ostringstream oss;
oss << "R2Score::Evaluate(): number of points (" << data.n_cols << ") "
<< "does not match number of responses (" << responses.n_cols << ")!"
<< std::endl;
throw std::invalid_argument(oss.str());
}
ResponsesType predictedResponses;
// Taking Predicted Output from the model.
model.Predict(data, predictedResponses);
// Mean value of response.
double meanResponses = arma::mean(responses);
// Calculate the numerator i.e. residual sum of squares.
double residualSumSquared = arma::accu(arma::square(responses -
predictedResponses));
// Calculate the denominator i.e.total sum of squares.
double totalSumSquared = arma::accu(arma::square(responses - meanResponses));
// Handling undefined R2 Score when both denominator and numerator is 0.0.
if (residualSumSquared == 0.0)
return totalSumSquared ? 1.0 : DBL_MIN;
return 1 - residualSumSquared / totalSumSquared;
}
} // namespace cv
} // namespace mlpack
#endif
@@ -49,7 +49,8 @@ class CrossEntropyError
* @param target The target vector.
*/
template<typename InputType, typename TargetType>
double Forward(const InputType& input, const TargetType& target);
typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network.
@@ -27,8 +27,10 @@ CrossEntropyError<InputDataType, OutputDataType>::CrossEntropyError(
template<typename InputDataType, typename OutputDataType>
template<typename InputType, typename TargetType>
double CrossEntropyError<InputDataType, OutputDataType>::Forward(
const InputType& input, const TargetType& target)
typename InputType::elem_type
CrossEntropyError<InputDataType, OutputDataType>::Forward(
const InputType& input,
const TargetType& target)
{
return -arma::accu(target % arma::log(input + eps) +
(1. - target) % arma::log(1. - input + eps));
@@ -62,7 +62,8 @@ class DiceLoss
* @param target The target vector.
*/
template<typename InputType, typename TargetType>
double Forward(const InputType& input, const TargetType& target);
typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network.
@@ -27,8 +27,9 @@ DiceLoss<InputDataType, OutputDataType>::DiceLoss(
template<typename InputDataType, typename OutputDataType>
template<typename InputType, typename TargetType>
double DiceLoss<InputDataType, OutputDataType>::Forward(
const InputType& input, const TargetType& target)
typename InputType::elem_type DiceLoss<InputDataType, OutputDataType>::Forward(
const InputType& input,
const TargetType& target)
{
return 1 - ((2 * arma::accu(target % input) + smooth) /
(arma::accu(target % target) + arma::accu(
@@ -45,7 +45,8 @@ class EarthMoverDistance
* @param target The target vector.
*/
template<typename InputType, typename TargetType>
double Forward(const InputType& input, const TargetType& target);
typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network.
@@ -26,8 +26,10 @@ EarthMoverDistance<InputDataType, OutputDataType>::EarthMoverDistance()
template<typename InputDataType, typename OutputDataType>
template<typename InputType, typename TargetType>
double EarthMoverDistance<InputDataType, OutputDataType>::Forward(
const InputType& input, const TargetType& target)
typename InputType::elem_type
EarthMoverDistance<InputDataType, OutputDataType>::Forward(
const InputType& input,
const TargetType& target)
{
return -arma::accu(target % input);
}
@@ -48,7 +48,8 @@ class HingeEmbeddingLoss
* @param target Target data to compare with.
*/
template<typename InputType, typename TargetType>
double Forward(const InputType& input, const TargetType& target);
typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network.
@@ -27,8 +27,10 @@ HingeEmbeddingLoss<InputDataType, OutputDataType>::HingeEmbeddingLoss()
template<typename InputDataType, typename OutputDataType>
template<typename InputType, typename TargetType>
double HingeEmbeddingLoss<InputDataType, OutputDataType>::Forward(
const InputType& input, const TargetType& target)
typename InputType::elem_type
HingeEmbeddingLoss<InputDataType, OutputDataType>::Forward(
const InputType& input,
const TargetType& target)
{
TargetType temp = target - (target == 0);
return (arma::accu(arma::max(1-input % temp, 0.))) / target.n_elem;
@@ -52,7 +52,8 @@ class HuberLoss
* @param target The target vector.
*/
template<typename InputType, typename TargetType>
double Forward(const InputType& input, const TargetType& target);
typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network.
@@ -30,13 +30,15 @@ HuberLoss<InputDataType, OutputDataType>::HuberLoss(
template<typename InputDataType, typename OutputDataType>
template<typename InputType, typename TargetType>
double HuberLoss<InputDataType, OutputDataType>::Forward(
const InputType& input, const TargetType& target)
typename InputType::elem_type
HuberLoss<InputDataType, OutputDataType>::Forward(const InputType& input,
const TargetType& target)
{
double loss = 0;
typedef typename InputType::elem_type ElemType;
ElemType loss = 0;
for (size_t i = 0; i < input.n_elem; ++i)
{
const double absError = std::abs(target[i] - input[i]);
const ElemType absError = std::abs(target[i] - input[i]);
loss += absError > delta
? delta * (absError - 0.5 * delta) : 0.5 * std::pow(absError, 2);
}
@@ -50,13 +52,16 @@ void HuberLoss<InputDataType, OutputDataType>::Backward(
const TargetType& target,
OutputType& output)
{
typedef typename InputType::elem_type ElemType;
output.set_size(size(input));
for (size_t i = 0; i < output.n_elem; ++i)
{
const double absError = std::abs(target[i] - input[i]);
const ElemType absError = std::abs(target[i] - input[i]);
output[i] = absError > delta
? - delta * (target[i] - input[i]) / absError : input[i] - target[i];
if (mean) output[i] /= output.n_elem;
if (mean)
output[i] /= output.n_elem;
}
}
@@ -60,7 +60,8 @@ class KLDivergence
* @param target Target data to compare with.
*/
template<typename InputType, typename TargetType>
double Forward(const InputType& input, const TargetType& target);
typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network.
@@ -28,8 +28,9 @@ KLDivergence<InputDataType, OutputDataType>::KLDivergence(const bool takeMean) :
template<typename InputDataType, typename OutputDataType>
template<typename InputType, typename TargetType>
double KLDivergence<InputDataType, OutputDataType>::Forward(
const InputType& input, const TargetType& target)
typename InputType::elem_type
KLDivergence<InputDataType, OutputDataType>::Forward(const InputType& input,
const TargetType& target)
{
if (takeMean)
{
@@ -20,7 +20,7 @@ namespace ann /** Artificial Neural Network. */ {
/**
* The Log-Hyperbolic-Cosine loss function is often used to improve
* variational auto encoder. This function is the log of hyperbolic
* variational auto encoder. This function is the log of hyperbolic
* cosine of difference between true values and predicted values.
*
* @tparam InputDataType Type of the input data (arma::colvec, arma::mat,
@@ -55,7 +55,8 @@ class LogCoshLoss
* @param target Target data to compare with.
*/
template<typename InputType, typename TargetType>
double Forward(const InputType& input, const TargetType& target);
typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network.
@@ -28,8 +28,9 @@ LogCoshLoss<InputDataType, OutputDataType>::LogCoshLoss(const double a) :
template<typename InputDataType, typename OutputDataType>
template<typename InputType, typename TargetType>
double LogCoshLoss<InputDataType, OutputDataType>::Forward(
const InputType& input, const TargetType& target)
typename InputType::elem_type
LogCoshLoss<InputDataType, OutputDataType>::Forward(const InputType& input,
const TargetType& target)
{
return arma::accu(arma::log(arma::cosh(a * (target - input)))) / a;
}
@@ -45,7 +45,8 @@ class MeanBiasError
* @param target The target vector.
*/
template<typename InputType, typename TargetType>
double Forward(const InputType& input, const TargetType& target);
typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network.
@@ -27,8 +27,9 @@ MeanBiasError<InputDataType, OutputDataType>::MeanBiasError()
template<typename InputDataType, typename OutputDataType>
template<typename InputType, typename TargetType>
double MeanBiasError<InputDataType, OutputDataType>::Forward(
const InputType& input, const TargetType& target)
typename InputType::elem_type
MeanBiasError<InputDataType, OutputDataType>::Forward(const InputType& input,
const TargetType& target)
{
return arma::accu(target - input) / target.n_cols;
}
@@ -46,7 +46,8 @@ class MeanSquaredError
* @param target The target vector.
*/
template<typename InputType, typename TargetType>
double Forward(const InputType& input, const TargetType& target);
typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network.
@@ -26,8 +26,10 @@ MeanSquaredError<InputDataType, OutputDataType>::MeanSquaredError()
template<typename InputDataType, typename OutputDataType>
template<typename InputType, typename TargetType>
double MeanSquaredError<InputDataType, OutputDataType>::Forward(
const InputType& input, const TargetType& target)
typename InputType::elem_type
MeanSquaredError<InputDataType, OutputDataType>::Forward(
const InputType& input,
const TargetType& target)
{
return arma::accu(arma::square(input - target)) / target.n_cols;
}
@@ -45,7 +45,8 @@ class MeanSquaredLogarithmicError
* @param target The target vector.
*/
template<typename InputType, typename TargetType>
double Forward(const InputType& input, const TargetType& target);
typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network.
@@ -27,8 +27,10 @@ MeanSquaredLogarithmicError<InputDataType, OutputDataType>
template<typename InputDataType, typename OutputDataType>
template<typename InputType, typename TargetType>
double MeanSquaredLogarithmicError<InputDataType, OutputDataType>::Forward(
const InputType& input, const TargetType& target)
typename InputType::elem_type
MeanSquaredLogarithmicError<InputDataType, OutputDataType>::Forward(
const InputType& input,
const TargetType& target)
{
return arma::accu(arma::square(arma::log(1. + target) -
arma::log(1. + input))) / target.n_cols;
@@ -48,7 +48,8 @@ class NegativeLogLikelihood
* between 1 and the number of classes.
*/
template<typename InputType, typename TargetType>
double Forward(const InputType& input, const TargetType& target);
typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network. The negative log
@@ -26,10 +26,13 @@ NegativeLogLikelihood<InputDataType, OutputDataType>::NegativeLogLikelihood()
template<typename InputDataType, typename OutputDataType>
template<typename InputType, typename TargetType>
double NegativeLogLikelihood<InputDataType, OutputDataType>::Forward(
const InputType& input, const TargetType& target)
typename InputType::elem_type
NegativeLogLikelihood<InputDataType, OutputDataType>::Forward(
const InputType& input,
const TargetType& target)
{
double output = 0;
typedef typename InputType::elem_type ElemType;
ElemType output = 0;
for (size_t i = 0; i < input.n_cols; ++i)
{
size_t currentTarget = target(i) - 1;
@@ -49,7 +49,8 @@ class ReconstructionLoss
* @param target The target matrix.
*/
template<typename InputType, typename TargetType>
double Forward(const InputType& input, const TargetType& target);
typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network.
@@ -30,7 +30,8 @@ ReconstructionLoss<
template<typename InputDataType, typename OutputDataType, typename DistType>
template<typename InputType, typename TargetType>
double ReconstructionLoss<InputDataType, OutputDataType, DistType>::Forward(
typename InputType::elem_type
ReconstructionLoss<InputDataType, OutputDataType, DistType>::Forward(
const InputType& input, const TargetType& target)
{
dist = DistType(input);
@@ -64,8 +64,8 @@ class SigmoidCrossEntropyError
* @param target The target vector.
*/
template<typename InputType, typename TargetType>
inline double Forward(const InputType& input,
const TargetType& target);
inline typename InputType::elem_type Forward(const InputType& input,
const TargetType& target);
/**
* Ordinary feed backward pass of a neural network.
*
@@ -29,10 +29,13 @@ SigmoidCrossEntropyError<InputDataType, OutputDataType>
template<typename InputDataType, typename OutputDataType>
template<typename InputType, typename TargetType>
inline double SigmoidCrossEntropyError<InputDataType, OutputDataType>::Forward(
const InputType& input, const TargetType& target)
inline typename InputType::elem_type
SigmoidCrossEntropyError<InputDataType, OutputDataType>::Forward(
const InputType& input,
const TargetType& target)
{
double maximum = 0;
typedef typename InputType::elem_type ElemType;
ElemType maximum = 0;
for (size_t i = 0; i < input.n_elem; ++i)
{
maximum += std::max(input[i], 0.0) +
+23
View File
@@ -17,6 +17,7 @@
#include <mlpack/core/cv/metrics/mse.hpp>
#include <mlpack/core/cv/metrics/precision.hpp>
#include <mlpack/core/cv/metrics/recall.hpp>
#include <mlpack/core/cv/metrics/r2_score.hpp>
#include <mlpack/core/cv/simple_cv.hpp>
#include <mlpack/core/cv/k_fold_cv.hpp>
#include <mlpack/methods/ann/ffn.hpp>
@@ -164,6 +165,28 @@ BOOST_AUTO_TEST_CASE(MSETest)
BOOST_REQUIRE_CLOSE(MSE::Evaluate(lr, data, responses), expectedMSE, 1e-5);
}
/**
* Test the R squared metric (R2 Score).
*/
BOOST_AUTO_TEST_CASE(R2ScoreTest)
{
// Making two points that define the linear function f(x) = x - 1.
arma::mat trainingData("0 1");
arma::rowvec trainingResponses("-1 0");
LinearRegression lr(trainingData, trainingResponses);
// Making five responses that are the output of regression function f(x)
// with some responses having a slight deviation of 0.005.
// Mean Responses = (1 + 2 + 3 + 6 + 8)/5 = 4.
arma::mat data("2 3 4 7 9");
arma::rowvec responses("1 2.005 3 6.005 8.005");
double expectedR2 = 0.99999779;
BOOST_REQUIRE_CLOSE(R2Score::Evaluate(lr, data, responses), expectedR2, 1e-5);
}
/**
* Test the mean squared error with matrix responses.
*/