refactoring recurent

This commit is contained in:
2016-01-28 20:49:47 +01:00
parent 3c26c9641c
commit 13b179dd57
9 changed files with 229 additions and 61 deletions

View File

@@ -44,8 +44,6 @@ namespace NeuralNetwork
inline virtual void setThreads(const unsigned& t) final {threads=t;}
using Stringifiable::stringify;
protected:
/**
* @brief Number of threads used by network

View File

@@ -1,6 +1,7 @@
#pragma once
#include <string>
#include <vector>
namespace NeuralNetwork
{
@@ -66,6 +67,65 @@ namespace NeuralNetwork
* @brief Function returns bias for neuron
*/
virtual float getBias() const=0;
virtual float operator()(const std::vector<float>& inputs) =0;
/**
* @brief Function returns clone of object
*/
virtual Neuron* clone() const = 0;
protected:
};
class BiasNeuron: public Neuron {
public:
virtual float getBias() const override { return 0; };
virtual float getWeight(const Neuron&) const override { return 0; }
virtual void setBias(const float&) override{ }
virtual float output() const override { return 1.0; };
virtual void setWeight(const Neuron&, const float&) override { }
virtual std::string stringify(const std::string& prefix = "") const override { return prefix+"{ \"class\" : \"NeuralNetwork::BiasNeuron\" }"; }
virtual float value() const override { return 1.0; }
virtual long unsigned int id() const override { return 0; }
virtual float operator()(const std::vector< float >&) override { return 1.0; }
virtual Neuron* clone() const { return new BiasNeuron(); }
};
class InputNeuron: public Neuron {
public:
InputNeuron(long unsigned int _id): id_(_id) {
}
virtual float getBias() const override { return 0; };
virtual float getWeight(const Neuron&) const override { return 0; }
virtual void setBias(const float&) override{ }
virtual float output() const override { return 1.0; };
virtual void setWeight(const Neuron&, const float&) override { }
virtual std::string stringify(const std::string& prefix = "") const override { return prefix+"{ \"class\" : \"NeuralNetwork::InputNeuron\", \"id\": "+std::to_string(id_)+" }"; }
virtual float value() const override { return 1.0; }
virtual long unsigned int id() const override { return id_; }
virtual float operator()(const std::vector< float >&) override { return 1.0; }
virtual Neuron* clone() const { return new InputNeuron(id_); }
protected:
long unsigned int id_;
};
}

View File

@@ -26,7 +26,13 @@ namespace Recurrent {
* @param hiddenUnits is number of hiddenUnits to be created
*/
inline Network(size_t _inputSize, size_t _outputSize,size_t hiddenUnits=0):NeuralNetwork::Network(),inputSize(_inputSize),outputSize(_outputSize), neurons(0) {
for(size_t i=0;i<_inputSize+_outputSize;i++) {
neurons.push_back(new NeuralNetwork::BiasNeuron());
for(size_t i=0;i<_inputSize;i++) {
neurons.push_back(new NeuralNetwork::InputNeuron(neurons.size()));
}
for(size_t i=0;i<_outputSize;i++) {
addNeuron();
}
@@ -35,14 +41,14 @@ namespace Recurrent {
}
};
// todo: implement
inline Network(const std::string &json) {
}
/**
* @brief Virtual destructor for Network
*/
virtual ~Network() {};
virtual ~Network() {
for(auto& a:neurons) {
delete a;
}
};
/**
* @brief This is a function to compute one iterations of network
@@ -61,7 +67,7 @@ namespace Recurrent {
*/
std::vector<float> computeOutput(const std::vector<float>& input, unsigned int iterations);
std::vector<Neuron>& getNeurons () {
std::vector<NeuralNetwork::Neuron*>& getNeurons () {
return neurons;
}
@@ -69,20 +75,27 @@ namespace Recurrent {
void stringify(std::ostream& out) const override;
Neuron& addNeuron() {
neurons.push_back(Recurrent::Neuron(neurons.size()));
Neuron &newNeuron=neurons.back();
NeuralNetwork::Neuron& addNeuron() {
neurons.push_back(new Recurrent::Neuron(neurons.size()));
NeuralNetwork::Neuron *newNeuron=neurons.back();
for(size_t i=0;i<neurons.size();i++) {
neurons[i].setWeight(newNeuron,0.0);
neurons[i]->setWeight(*newNeuron,0.0);
}
return newNeuron;
return *newNeuron;
}
/**
* @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;
protected:
size_t inputSize=0;
size_t outputSize=0;
std::vector<Recurrent::Neuron> neurons;
std::vector<NeuralNetwork::Neuron*> neurons;
};
}
}

View File

@@ -22,14 +22,15 @@ namespace Recurrent {
class Neuron : public NeuralNetwork::Neuron
{
public:
Neuron(unsigned long _id=0,const float& _bias = 0): NeuralNetwork::Neuron(), basis(new BasisFunction::Linear),
Neuron(unsigned long _id=0): NeuralNetwork::Neuron(), basis(new BasisFunction::Linear),
activation(new ActivationFunction::Sigmoid(-4.9)),
id_(_id),bias(_bias),weights(_id+1),_output(0),_value(0) {
id_(_id),weights(_id+1),_output(0),_value(0) {
}
Neuron(const Neuron &r): NeuralNetwork::Neuron(), basis(r.basis->clone()), activation(r.activation->clone()),id_(r.id_),
bias(r.bias), weights(r.weights), _output(r._output), _value(r._value) {
weights(r.weights), _output(r._output), _value(r._value) {
}
virtual ~Neuron() {
delete basis;
delete activation;
@@ -39,7 +40,6 @@ namespace Recurrent {
Recurrent::Neuron& operator=(const NeuralNetwork::Recurrent::Neuron&r) {
id_=r.id_;
bias=r.bias;
weights=r.weights;
basis=r.basis->clone();
activation=r.activation->clone();
@@ -89,19 +89,19 @@ namespace Recurrent {
* @param _bias is new bias (initial value for neuron)
*/
virtual void setBias(const float &_bias) override {
bias=_bias;
weights[0]=_bias;
}
/**
* @brief Function returns bias for neuron
*/
virtual float getBias() const override {
return bias;
return weights[0];
}
float operator()(const std::vector<float>& inputs) {
//compute value
_value=basis->operator()(weights,inputs)+bias;
_value=basis->operator()(weights,inputs);
//compute output
_output=activation->operator()(_value);
@@ -109,15 +109,83 @@ namespace Recurrent {
return _output;
}
virtual Neuron* clone() const override {
Neuron *n = new Recurrent::Neuron;
*n=*this;
return n;
}
protected:
BasisFunction::BasisFunction *basis;
ActivationFunction::ActivationFunction *activation;
unsigned long id_;
float bias;
std::vector<float> weights;
float _output;
float _value;
};
/**
* @author Tomas Cernik (Tom.Cernik@gmail.com)
* @brief Class of LSTM unit
*/
// input + input gate + forget gate + ouput gate
// https://en.wikipedia.org/wiki/Long_short-term_memory
class LSTMNeuron : public Neuron
{
public:
LSTMNeuron(unsigned long _id=0): Neuron(_id) {
}
LSTMNeuron(const Neuron &r): Neuron(r) {
}
virtual ~LSTMNeuron() {
};
virtual std::string stringify(const std::string &prefix="") const override;
LSTMNeuron& operator=(const LSTMNeuron&r) {
this->Neuron::operator=(r);
return *this;
}
/**
* @brief Returns output of neuron
*/
virtual float output() const override {
return _output;
}
/**
* @brief Returns input of neuron
*/
virtual float value() const override {
return _value;
}
float operator()(const std::vector<float>& inputs) override {
//compute value
_value=basis->operator()(weights,inputs);
//compute output
_output=activation->operator()(_value);
return _output;
}
virtual Recurrent::LSTMNeuron* clone() const override {
LSTMNeuron *n = new Recurrent::LSTMNeuron;
*n=*this;
return n;
}
protected:
std::vector<float> forgetWeights;
std::vector<float> outputWeights;
};
}
}