tweaking speed

This commit is contained in:
2016-05-08 12:09:24 +02:00
parent 4b42a8c310
commit 79d094e1cb
6 changed files with 131 additions and 107 deletions

View File

@@ -20,7 +20,7 @@ namespace FeedForward {
* @brief Constructor for Network * @brief Constructor for Network
* @param _inputSize is number of inputs to network * @param _inputSize is number of inputs to network
*/ */
inline Network(size_t _inputSize):NeuralNetwork::Network(_inputSize,_inputSize),layers() { inline Network(size_t _inputSize):NeuralNetwork::Network(_inputSize,_inputSize),layers(),_partialInput(_inputSize),_partialOutput(_inputSize) {
appendLayer(_inputSize); appendLayer(_inputSize);
}; };
@@ -42,9 +42,17 @@ namespace FeedForward {
_inputs=size; _inputs=size;
} }
if(_partialInput.size() < size+1) {
_partialInput.resize(size+1);
}
if(_partialOutput.size() < size+1) {
_partialOutput.resize(size+1);
}
_outputs=size; _outputs=size;
return *layers[layers.size()-1];//.back(); return *layers.back();
} }
Layer& operator[](const std::size_t &id) { Layer& operator[](const std::size_t &id) {
@@ -80,6 +88,8 @@ namespace FeedForward {
protected: protected:
std::vector<Layer*> layers; std::vector<Layer*> layers;
std::vector<float> _partialInput = {};
std::vector<float> _partialOutput = {};
private: private:
inline Network():NeuralNetwork::Network(0,0),layers() { inline Network():NeuralNetwork::Network(0,0),layers() {

View File

@@ -217,7 +217,7 @@ namespace NeuralNetwork
} }
virtual ActivationFunction::ActivationFunction& getActivationFunction() override { virtual ActivationFunction::ActivationFunction& getActivationFunction() override {
throw usageException("activation function"); throw usageException("biasNeuron - activation function");
} }
virtual void setBasisFunction(const BasisFunction::BasisFunction&) override { virtual void setBasisFunction(const BasisFunction::BasisFunction&) override {
@@ -268,7 +268,7 @@ namespace NeuralNetwork
} }
virtual ActivationFunction::ActivationFunction& getActivationFunction() override { virtual ActivationFunction::ActivationFunction& getActivationFunction() override {
throw usageException("activation function"); throw usageException("input neuron - activation function");
} }
virtual void setBasisFunction(const BasisFunction::BasisFunction&) override { virtual void setBasisFunction(const BasisFunction::BasisFunction&) override {

View File

@@ -9,111 +9,117 @@
#include <limits> #include <limits>
namespace NeuralNetwork { namespace NeuralNetwork {
namespace Recurrent { namespace Recurrent {
/** /**
* @author Tomas Cernik (Tom.Cernik@gmail.com) * @author Tomas Cernik (Tom.Cernik@gmail.com)
* @brief Reccurent model of Artifical neural network * @brief Reccurent model of Artifical neural network
*/ */
class Network: public NeuralNetwork::Network { class Network : public NeuralNetwork::Network {
public: public:
/** /**
* @brief Constructor for Network * @brief Constructor for Network
* @param _inputSize is number of inputs to network * @param _inputSize is number of inputs to network
* @param _outputSize is size of output from network * @param _outputSize is size of output from network
* @param hiddenUnits is number of hiddenUnits to be created * @param hiddenUnits is number of hiddenUnits to be created
*/ */
inline Network(size_t inputSize, size_t outputSize,size_t hiddenUnits=0):NeuralNetwork::Network(inputSize,outputSize), neurons(0),outputs(0) { inline Network(size_t inputSize, size_t outputSize, size_t hiddenUnits = 0) : NeuralNetwork::Network(inputSize, outputSize), neurons(0), _outputsOfNeurons(0) {
neurons.push_back(new NeuralNetwork::BiasNeuron()); neurons.push_back(new NeuralNetwork::BiasNeuron());
for(size_t i=0;i<inputSize;i++) { for(size_t i = 0; i < inputSize; i++) {
neurons.push_back(new NeuralNetwork::InputNeuron(neurons.size())); neurons.push_back(new NeuralNetwork::InputNeuron(neurons.size()));
}
for(size_t i = 0; i < outputSize; i++) {
addNeuron();
}
for(size_t i = 0; i < hiddenUnits; i++) {
addNeuron();
}
};
Network(const Network &r) : NeuralNetwork::Network(r), neurons(0), _outputsOfNeurons(r._outputsOfNeurons) {
neurons.push_back(new NeuralNetwork::BiasNeuron());
for(std::size_t i = 1; i < r.neurons.size(); i++) {
neurons.push_back(r.neurons[i]->clone());
}
} }
for(size_t i=0;i<outputSize;i++) { Network &operator=(const Network &r);
addNeuron();
/**
* @brief Virtual destructor for Network
*/
virtual ~Network() {
for(auto &a:neurons) {
delete a;
}
};
void reset() {
for(auto &output: _outputsOfNeurons) {
output=0.0;
}
} }
for(size_t i=0;i<hiddenUnits;i++) { /**
addNeuron(); * @brief This is a function to compute one iterations of network
* @param input is input of network
* @returns output of network
*/
inline virtual std::vector<float> computeOutput(const std::vector<float> &input) override {
return computeOutput(input, 1);
} }
};
Network(const Network &r) : NeuralNetwork::Network(r), neurons(0), outputs(r.outputs) { /**
neurons.push_back(new NeuralNetwork::BiasNeuron()); * @brief This is a function to compute iterations of network
for(std::size_t i=1;i<r.neurons.size();i++) { * @param input is input of network
neurons.push_back(r.neurons[i]->clone()); * @param iterations is number of iterations
* @returns output of network
*/
std::vector<float> computeOutput(const std::vector<float> &input, unsigned int iterations);
std::vector<NeuronInterface *> &getNeurons() {
return neurons;
} }
}
Network& operator=(const Network&r); virtual SimpleJSON::Type::Object serialize() const override;
/** NeuronInterface &addNeuron() {
* @brief Virtual destructor for Network neurons.push_back(new Neuron(neurons.size()));
*/ NeuronInterface *newNeuron = neurons.back();
virtual ~Network() { for(std::size_t i = 0; i < neurons.size(); i++) {
for(auto& a:neurons) { neurons[i]->setInputSize(newNeuron->id + 1);
delete a; }
return *newNeuron;
} }
};
/** /**
* @brief This is a function to compute one iterations of network * @brief creates new network from joining two
* @param input is input of network * @param r is network that is connected to outputs of this network
* @returns output of network * @returns network of constructed from two networks
*/ */
inline virtual std::vector<float> computeOutput(const std::vector<float>& input) override { NeuralNetwork::Recurrent::Network connectWith(const NeuralNetwork::Recurrent::Network &r) const;
return computeOutput(input,1);
}
/** static std::unique_ptr<Network> deserialize(const SimpleJSON::Type::Object &);
* @brief This is a function to compute iterations of network
* @param input is input of network
* @param iterations is number of iterations
* @returns output of network
*/
std::vector<float> computeOutput(const std::vector<float>& input, unsigned int iterations);
std::vector<NeuronInterface*>& getNeurons () { std::size_t size() const {
return neurons; return neurons.size();
} };
virtual SimpleJSON::Type::Object serialize() const override; NeuronInterface &operator[](std::size_t index) {
return *neurons[index];
NeuronInterface& addNeuron() {
neurons.push_back(new Neuron(neurons.size()));
NeuronInterface *newNeuron=neurons.back();
for(std::size_t i=0;i<neurons.size();i++) {
neurons[i]->setInputSize(newNeuron->id+1);
} }
return *newNeuron;
}
/** typedef SimpleJSON::Factory<Network> Factory;
* @brief creates new network from joining two
* @param r is network that is connected to outputs of this network
* @returns network of constructed from two networks
*/
NeuralNetwork::Recurrent::Network connectWith(const NeuralNetwork::Recurrent::Network &r) const;
static std::unique_ptr<Network> deserialize(const SimpleJSON::Type::Object&); protected:
std::vector<NeuronInterface *> neurons;
std::vector<float> _outputsOfNeurons;
std::size_t size() const { SIMPLEJSON_REGISTER(NeuralNetwork::Recurrent::Network::Factory, NeuralNetwork::Recurrent::Network, deserialize)
return neurons.size(); };
}; }
NeuronInterface& operator[](std::size_t index) {
return *neurons[index];
}
typedef SimpleJSON::Factory<Network> Factory;
protected:
std::vector<NeuronInterface*> neurons;
std::vector<float> outputs;
SIMPLEJSON_REGISTER(NeuralNetwork::Recurrent::Network::Factory,NeuralNetwork::Recurrent::Network, deserialize)
};
}
} }

View File

@@ -3,7 +3,9 @@
SIMPLEJSON_REGISTER_FINISH(NeuralNetwork::FeedForward::Layer::Factory, NeuralNetwork::FeedForward::Layer,NeuralNetwork::FeedForward::Layer::deserialize) SIMPLEJSON_REGISTER_FINISH(NeuralNetwork::FeedForward::Layer::Factory, NeuralNetwork::FeedForward::Layer,NeuralNetwork::FeedForward::Layer::deserialize)
void NeuralNetwork::FeedForward::Layer::solve(const std::vector<float> &input, std::vector<float> &output) { void NeuralNetwork::FeedForward::Layer::solve(const std::vector<float> &input, std::vector<float> &output) {
output.resize(neurons.size()); if(output.size() < neurons.size()) {
output.resize(neurons.size());
}
for(auto&neuron: neurons) { for(auto&neuron: neurons) {
output[neuron->id] = neuron->operator()(input); output[neuron->id] = neuron->operator()(input);

View File

@@ -3,21 +3,18 @@
SIMPLEJSON_REGISTER_FINISH(NeuralNetwork::FeedForward::Network::Factory, NeuralNetwork::FeedForward::Network,NeuralNetwork::FeedForward::Network::deserialize) SIMPLEJSON_REGISTER_FINISH(NeuralNetwork::FeedForward::Network::Factory, NeuralNetwork::FeedForward::Network,NeuralNetwork::FeedForward::Network::deserialize)
std::vector<float> NeuralNetwork::FeedForward::Network::computeOutput(const std::vector<float>& input) { std::vector<float> NeuralNetwork::FeedForward::Network::computeOutput(const std::vector<float>& input) {
std::vector<float> partialInput(input.size()+1);
std::vector<float> partialOutput;
// 0 is bias // 0 is bias
partialInput[0]=1.0; _partialInput[0]=1.0;
for(std::size_t i=0;i<input.size();i++) { for(std::size_t i=0;i<input.size();i++) {
partialInput[i+1]=input[i]; _partialInput[i+1]=input[i];
} }
for(std::size_t i=1;i<layers.size();i++) { for(std::size_t i=1;i<layers.size();i++) {
layers[i]->solve(partialInput,partialOutput); layers[i]->solve(_partialInput,_partialOutput);
partialInput.swap(partialOutput); _partialInput.swap(_partialOutput);
} }
return std::vector<float>(partialInput.begin()+1,partialInput.end()); return std::vector<float>(_partialInput.begin()+1,_partialInput.begin()+outputs()+1);
} }
void NeuralNetwork::FeedForward::Network::randomizeWeights() { void NeuralNetwork::FeedForward::Network::randomizeWeights() {
@@ -44,6 +41,15 @@ std::unique_ptr<NeuralNetwork::FeedForward::Network> NeuralNetwork::FeedForward:
for(auto& layerObject: obj["layers"].as<SimpleJSON::Type::Array>()) { for(auto& layerObject: obj["layers"].as<SimpleJSON::Type::Array>()) {
network->layers.push_back(NeuralNetwork::FeedForward::Layer::Factory::deserialize(layerObject.as<SimpleJSON::Type::Object>()).release()); network->layers.push_back(NeuralNetwork::FeedForward::Layer::Factory::deserialize(layerObject.as<SimpleJSON::Type::Object>()).release());
if(network->_partialInput.size() < network->layers.back()->size()) {
network->_partialInput.resize(network->layers.back()->size());
}
if(network->_partialOutput.size() < network->layers.back()->size()) {
network->_partialOutput.resize(network->layers.back()->size());
}
} }
network->_inputs=network->layers[0]->size()-1; network->_inputs=network->layers[0]->size()-1;

View File

@@ -7,17 +7,17 @@ std::vector<float> NeuralNetwork::Recurrent::Network::computeOutput(const std::v
assert(input.size() == _inputs); assert(input.size() == _inputs);
if(outputs.size() != neurons.size()) { if(_outputsOfNeurons.size() != neurons.size()) {
outputs.resize(neurons.size()); _outputsOfNeurons.resize(neurons.size());
for(auto &neuron:neurons) { for(auto &neuron:neurons) {
outputs[neuron->id]=neuron->output(); _outputsOfNeurons[neuron->id]=neuron->output();
} }
} }
std::vector<float> newOutputs(neurons.size()); std::vector<float> newOutputs(neurons.size());
for(size_t i=0;i<_inputs;i++) { for(size_t i=0;i<_inputs;i++) {
outputs[i+1]=input[i]; _outputsOfNeurons[i+1]=input[i];
newOutputs[i+1]=input[i]; newOutputs[i+1]=input[i];
} }
@@ -27,9 +27,9 @@ std::vector<float> NeuralNetwork::Recurrent::Network::computeOutput(const std::v
for(unsigned int iter=0;iter< iterations;iter++) { for(unsigned int iter=0;iter< iterations;iter++) {
for(size_t i=_inputs+1;i<neuronsSize;i++) { for(size_t i=_inputs+1;i<neuronsSize;i++) {
newOutputs[i] = neurons[i]->operator()(outputs); newOutputs[i] = neurons[i]->operator()(_outputsOfNeurons);
} }
outputs.swap(newOutputs); _outputsOfNeurons.swap(newOutputs);
} }
std::vector<float> ret; std::vector<float> ret;
@@ -40,7 +40,7 @@ std::vector<float> NeuralNetwork::Recurrent::Network::computeOutput(const std::v
return ret; return ret;
} }
NeuralNetwork::Recurrent::Network NeuralNetwork::Recurrent::Network::connectWith(const NeuralNetwork::Recurrent::Network &r) const { NeuralNetwork::Recurrent::Network NeuralNetwork::Recurrent::Network::connectWith(const NeuralNetwork::Recurrent::Network &) const {
} }
@@ -68,7 +68,7 @@ SimpleJSON::Type::Object NeuralNetwork::Recurrent::Network::serialize() const {
{"class", "NeuralNetwork::Recurrent::Network"}, {"class", "NeuralNetwork::Recurrent::Network"},
{"inputSize", _inputs}, {"inputSize", _inputs},
{"outputSize", _outputs}, {"outputSize", _outputs},
{"outputs", outputs}, {"outputs", _outputsOfNeurons},
{"neurons", neuronsSerialized} {"neurons", neuronsSerialized}
}; };
} }