cascade correlation: sticking to implementation by Fahlman and not paper
This commit is contained in:
@@ -3,7 +3,6 @@
|
||||
#include "../Cascade/Network.h"
|
||||
#include "../FeedForward/Network.h"
|
||||
#include "../Learning/QuickPropagation.h"
|
||||
#include "../ActivationFunction/Tangents.h"
|
||||
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
@@ -22,16 +21,16 @@ namespace NeuralNetwork {
|
||||
std::size_t inputs = patterns[0].first.size();
|
||||
std::size_t outputs = patterns[0].second.size();
|
||||
|
||||
Cascade::Network network(inputs, outputs, NeuralNetwork::ActivationFunction::Tangents());
|
||||
Cascade::Network network(inputs, outputs, *_activFunction.get());
|
||||
|
||||
network.randomizeWeights();
|
||||
|
||||
int step = 0;
|
||||
std::size_t step = 0;
|
||||
float error = trainOutputs(network, patterns);
|
||||
while(step++ < 15 && error > _maxError) {
|
||||
while(step++ < _maxHiddenUnits && error > _maxError) {
|
||||
std::vector<std::shared_ptr<Neuron>> candidates = createCandidates(network.getNeuronSize() - outputs);
|
||||
|
||||
std::shared_ptr<Neuron> candidate=trainCandidates(network, candidates, patterns);
|
||||
std::pair<std::shared_ptr<Neuron>, std::vector<float>> candidate = trainCandidates(network, candidates, patterns);
|
||||
addBestCandidate(network, candidate);
|
||||
|
||||
error = trainOutputs(network, patterns);
|
||||
@@ -59,10 +58,20 @@ namespace NeuralNetwork {
|
||||
_distribution = std::uniform_real_distribution<>(-weightRange, weightRange);
|
||||
}
|
||||
|
||||
void setMaximumHiddenNeurons(std::size_t neurons) {
|
||||
_maxHiddenUnits = neurons;
|
||||
}
|
||||
|
||||
void setActivationFunction(const ActivationFunction::ActivationFunction &function) {
|
||||
_activFunction = std::shared_ptr<ActivationFunction::ActivationFunction>(function.clone());
|
||||
}
|
||||
|
||||
protected:
|
||||
std::shared_ptr<ActivationFunction::ActivationFunction> _activFunction = std::make_shared<ActivationFunction::Sigmoid>(-4.9);
|
||||
float _minimalErrorStep = 0.00005;
|
||||
float _maxError;
|
||||
float _weightRange;
|
||||
std::size_t _maxHiddenUnits = 20;
|
||||
std::size_t _numberOfCandidates;
|
||||
std::mt19937 _generator;
|
||||
std::uniform_real_distribution<> _distribution;
|
||||
@@ -84,19 +93,23 @@ namespace NeuralNetwork {
|
||||
|
||||
float trainOutputs(Cascade::Network &network, const std::vector<TrainingPattern> &patterns);
|
||||
|
||||
std::shared_ptr<Neuron> trainCandidates(Cascade::Network &network, std::vector<std::shared_ptr<Neuron>> &candidates, const std::vector<TrainingPattern> &patterns);
|
||||
std::pair<std::shared_ptr<Neuron>, std::vector<float>> trainCandidates(Cascade::Network &network, std::vector<std::shared_ptr<Neuron>> &candidates,
|
||||
const std::vector<TrainingPattern> &patterns);
|
||||
|
||||
void addBestCandidate(Cascade::Network &network, const std::shared_ptr<Neuron> &candidate) {
|
||||
void addBestCandidate(Cascade::Network &network, const std::pair<std::shared_ptr<Neuron>, std::vector<float>> &candidate) {
|
||||
auto neuron = network.addNeuron();
|
||||
|
||||
neuron->setWeights(candidate->getWeights());
|
||||
neuron->setActivationFunction(candidate->getActivationFunction());
|
||||
float weightPortion = network.getNeuronSize() - network.outputs();
|
||||
neuron->setWeights(candidate.first->getWeights());
|
||||
neuron->setActivationFunction(candidate.first->getActivationFunction());
|
||||
std::size_t outIndex = 0;
|
||||
for(auto &n :network.getOutputNeurons()) {
|
||||
auto weights = n->getWeights();
|
||||
for(auto& weight: weights) {
|
||||
weight *=0.7;
|
||||
for(auto &weight: weights) {
|
||||
weight *= 0.7;
|
||||
}
|
||||
weights[weights.size()-1] = _distribution(_generator);
|
||||
weights[weights.size() - 1] = -candidate.second[outIndex] * weightPortion;//_distribution(_generator);
|
||||
outIndex++;
|
||||
n->setWeights(weights);
|
||||
}
|
||||
}
|
||||
@@ -107,7 +120,7 @@ namespace NeuralNetwork {
|
||||
for(std::size_t i = 0; i < _numberOfCandidates; i++) {
|
||||
candidates.push_back(std::make_shared<Neuron>(id));
|
||||
candidates.back()->setInputSize(id);
|
||||
candidates.back()->setActivationFunction(NeuralNetwork::ActivationFunction::Tangents());
|
||||
candidates.back()->setActivationFunction(*_activFunction.get());
|
||||
|
||||
for(std::size_t weightIndex = 0; weightIndex < id; weightIndex++) {
|
||||
candidates.back()->weight(weightIndex) = _distribution(_generator);
|
||||
|
||||
Reference in New Issue
Block a user