Merge remote-tracking branch 'upstream/master' into TfIdf-and-BagOfWords-fixes
This commit is contained in:
-17
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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) +
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user