Cascade-Correlation ...

This commit is contained in:
2016-05-13 20:18:19 +02:00
parent a40b6fad88
commit 9e2ce222fb
2 changed files with 44 additions and 15 deletions

View File

@@ -18,7 +18,11 @@ namespace NeuralNetwork {
setWeightRange(_weightRange); setWeightRange(_weightRange);
} }
Cascade::Network construct(const std::vector<TrainingPattern> &patterns) { virtual ~CascadeCorrelation() {
}
virtual Cascade::Network construct(const std::vector<TrainingPattern> &patterns) {
std::size_t inputs = patterns[0].first.size(); std::size_t inputs = patterns[0].first.size();
std::size_t outputs = patterns[0].second.size(); std::size_t outputs = patterns[0].second.size();
@@ -28,6 +32,7 @@ namespace NeuralNetwork {
_epoch = 0; _epoch = 0;
float error; float error;
float lastError;
if(_maxRandomOutputWeights) { if(_maxRandomOutputWeights) {
error = trainOutputsRandom(0, network, patterns); error = trainOutputsRandom(0, network, patterns);
} else { } else {
@@ -40,11 +45,18 @@ namespace NeuralNetwork {
addBestCandidate(network, candidate); addBestCandidate(network, candidate);
lastError=error;
if(_maxRandomOutputWeights) { if(_maxRandomOutputWeights) {
error = trainOutputsRandom(_epoch, network, patterns); error = trainOutputsRandom(_epoch, network, patterns);
} else { } else {
error = trainOutputs(network, patterns); error = trainOutputs(network, patterns);
} }
if(_prunningStatus && error*1.01 >= lastError) { // it is not getting bettter
network.removeLastHiddenNeuron();
error=lastError;
std::cout << "PRUNED\n";
}
} }
return network; return network;
@@ -79,7 +91,15 @@ namespace NeuralNetwork {
return _epoch; return _epoch;
} }
void setErrorThreshold(std::size_t err) { void setPruningStatus(bool status) {
_prunningStatus=status;
}
bool getPruningStatus() const {
return _prunningStatus;
}
void setErrorThreshold(float err) {
_errorTreshold = err; _errorTreshold = err;
} }
@@ -128,24 +148,25 @@ namespace NeuralNetwork {
} }
protected: protected:
std::shared_ptr<ActivationFunction::ActivationFunction> _activFunction = std::make_shared<ActivationFunction::Sigmoid>(-0.8); std::shared_ptr<ActivationFunction::ActivationFunction> _activFunction = std::make_shared<ActivationFunction::Sigmoid>(-1.0);
float _minimalErrorStep = 0.00005; float _minimalErrorStep = 0.00005;
float _errorTreshold; float _errorTreshold;
float _weightRange; float _weightRange;
bool _prunningStatus = false;
std::size_t _epoch = 0; std::size_t _epoch = 0;
std::size_t _maxHiddenUnits = 20; std::size_t _maxHiddenUnits = 20;
std::size_t _maxRandomOutputWeights = 0; std::size_t _maxRandomOutputWeights = 0;
std::size_t _numberOfCandidates; std::size_t _numberOfCandidates;
std::size_t _maxOutputLearningIterations = 1000; std::size_t _maxOutputLearningIterations = 1000;
std::size_t _maxOutputLearningIterationsWithoutChange = 50; std::size_t _maxOutputLearningIterationsWithoutChange = 5;
std::size_t _maxCandidateIterations = 4000; std::size_t _maxCandidateIterations = 4000;
std::size_t _maxCandidateIterationsWithoutChange = 50; std::size_t _maxCandidateIterationsWithoutChange = 5;
std::mt19937 _generator; std::mt19937 _generator;
std::uniform_real_distribution<> _distribution; std::uniform_real_distribution<> _distribution;
private:
std::vector<float> getInnerNeuronsOutput(Cascade::Network &network, const std::vector<float> &input) { std::vector<float> getInnerNeuronsOutput(Cascade::Network &network, const std::vector<float> &input) {
std::vector<float> output = network.computeOutput(input); std::vector<float> output = network.computeOutput(input);
@@ -161,11 +182,11 @@ namespace NeuralNetwork {
return outputOfUnits; return outputOfUnits;
} }
float trainOutputs(Cascade::Network &network, const std::vector<TrainingPattern> &patterns); virtual float trainOutputs(Cascade::Network &network, const std::vector<TrainingPattern> &patterns);
float trainOutputsRandom(std::size_t step, Cascade::Network &network, const std::vector<TrainingPattern> &patterns); virtual float trainOutputsRandom(std::size_t step, Cascade::Network &network, 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, virtual 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); const std::vector<TrainingPattern> &patterns);
void addBestCandidate(Cascade::Network &network, const std::pair<std::shared_ptr<Neuron>, std::vector<float>> &candidate) { void addBestCandidate(Cascade::Network &network, const std::pair<std::shared_ptr<Neuron>, std::vector<float>> &candidate) {
@@ -180,9 +201,9 @@ namespace NeuralNetwork {
for(auto &weight: weights) { for(auto &weight: weights) {
weight *= 0.9; weight *= 0.9;
} }
outIndex++;
n->setWeights(weights); n->setWeights(weights);
n->weight(n->getWeights().size() - 1) = -candidate.second[outIndex] / weightPortion; n->weight(n->getWeights().size() - 1) = candidate.second[outIndex] / weightPortion;
outIndex++;
} }
} }
@@ -195,7 +216,7 @@ namespace NeuralNetwork {
candidates.back()->setActivationFunction(*_activFunction.get()); candidates.back()->setActivationFunction(*_activFunction.get());
for(std::size_t weightIndex = 0; weightIndex < id; weightIndex++) { for(std::size_t weightIndex = 0; weightIndex < id; weightIndex++) {
candidates.back()->weight(weightIndex) = _distribution(_generator) * 3.0; candidates.back()->weight(weightIndex) = _distribution(_generator);// * 3.0;
} }
} }
return candidates; return candidates;

View File

@@ -38,6 +38,8 @@ float CascadeCorrelation::trainOutputs(Cascade::Network &network, const std::vec
} }
} }
error/=patterns.size();
if(fabs(lastError - error) < _minimalErrorStep) { if(fabs(lastError - error) < _minimalErrorStep) {
iterWithoutImporvement++; iterWithoutImporvement++;
} else { } else {
@@ -124,6 +126,8 @@ float CascadeCorrelation::trainOutputsRandom(std::size_t step, Cascade::Network
} }
} }
error/=patterns.size();
if(fabs(lastError - error) < _minimalErrorStep) { if(fabs(lastError - error) < _minimalErrorStep) {
iterWithoutImporvement++; iterWithoutImporvement++;
} else { } else {
@@ -237,7 +241,7 @@ std::pair <std::shared_ptr<NeuralNetwork::Neuron>, std::vector<float>> CascadeCo
do { do {
lastCorrelation = bestCorrelation; lastCorrelation = bestCorrelation;
/*cascor_cand_epoch*/ /*compute correlations */
for(std::size_t patternIndex = 0; patternIndex < patterns.size(); patternIndex++) { for(std::size_t patternIndex = 0; patternIndex < patterns.size(); patternIndex++) {
for(auto &candidateStruct : candidatesRegister) { for(auto &candidateStruct : candidatesRegister) {
auto candidate = candidateStruct.candidate; auto candidate = candidateStruct.candidate;
@@ -262,11 +266,11 @@ std::pair <std::shared_ptr<NeuralNetwork::Neuron>, std::vector<float>> CascadeCo
} }
} }
/*adjust ci_weights*/ /*Update Weights*/
for(auto &candidateStruct : candidatesRegister) { for(auto &candidateStruct : candidatesRegister) {
auto candidate = candidateStruct.candidate; auto candidate = candidateStruct.candidate;
for(std::size_t i = 0; i < candidateStruct.slopes.size(); i++) { for(std::size_t i = 0; i < candidateStruct.slopes.size(); i++) {
candidate->weight(i) += candidateStruct.slopes[i] * 2; candidate->weight(i) += candidateStruct.slopes[i];
candidateStruct.slopes[i] = 0.0; candidateStruct.slopes[i] = 0.0;
} }
} }
@@ -301,5 +305,9 @@ std::pair <std::shared_ptr<NeuralNetwork::Neuron>, std::vector<float>> CascadeCo
while(iterations++ < _maxCandidateIterations && iterationsWithoutIprovement < _maxCandidateIterationsWithoutChange); while(iterations++ < _maxCandidateIterations && iterationsWithoutIprovement < _maxCandidateIterationsWithoutChange);
std::cout << "iter: " << iterations << ", correlation: " << bestCorrelation << ", " << lastCorrelation << "\n"; std::cout << "iter: " << iterations << ", correlation: " << bestCorrelation << ", " << lastCorrelation << "\n";
for(auto&a: bestCorrelations) {
a*=-1.0;
}
return {bestCandidate, bestCorrelations}; return {bestCandidate, bestCorrelations};
} }