Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef MACHINE_LEARNING_H
- #define MACHINE_LEARNING_H
- #typedef float neuron_t;
- #include <cmath>
- #include "mymath.h"
- namespace MachineLearning {
- }
- class Neuron {
- public:
- //Types
- typedef float neuron_t;
- //....
- Neuron( std::size_t InputCount = 2) : output(.5),
- data(NULL),
- inputCount(0),
- index(pullIndex()),
- {
- updateArraySizes(InputCount);
- }
- ~Neuron(){
- pushIndex();
- updateArraySizes(0);
- }
- neuron_t* getData() const {
- return data;
- }
- const neuron_t& readOutput() const {
- return output;
- }
- Neuron::neuron_t calculateOutput(Neuron_t * inputs) {
- //error handling?
- output = Math::sigmoid(Math::dot(inputs,weights(), inputCount));
- return output;
- }
- //output must have been computed before hand
- void computeLossDerivativeWithRespectToInputWeightedSum(Neuron::neuron_t LossDerivativeWithRespectToOutput){
- _lossDerivativeWithRespectToWeightedInputSum *= LossDerivativeWithRespectToOutput*output*(neuron_t(1)-output);
- }
- graphics_t lossDerivativeWithRespectToInputWeightedSum() const {
- return _lossDerivativeWithRespectToWeightedInputSum;
- }
- void adjustWeights(neuron_t * inputs){
- for (std::size_t k = 0; k < inputCount; k++){
- *(weights()[k]) *= (neuron_t(1)- MachineLearning::LEARNING_RATE*_lossDerivativeWithRespectToWeightedInputSum*( *(inputs()[k]) ) );
- }
- }
- const std::size_t& getIndex() const {
- return index;
- }
- const Neuron& operator=(const Neuron& rhs){
- if (inputCount == rhs.getInputCount()){
- updateArraySizes(rhs.getInputCount());
- }
- for (std::size_t k = 0; k < rhs.getInputCount(); k++){
- data[k] = rhs.getData()[k];
- }
- output = rhs.getOutput();
- }
- private:
- Neuron::neuron_t* weights() {
- return data;
- }
- Neuron::neuron_t* weightsDerivative() {
- return (data + inputCount);
- }
- void updateArraySizes(std::size_t newSize) {
- if (inputCount == newSize) return;
- neuron_t * dataHolder = data;
- //create new neuronsList
- if (newSize) {
- data = new neuron_t[newSize];
- if (newSize > inputSize){
- for (std::size_t k = 0; k < inputSize; k++) {
- data[k] = dataHolder[k];
- } else {
- for ( std::size_t k = 0; k < newSize; k++) {
- data[k] = dataHolder[k];
- }
- }
- } else {
- data = NULL;
- }
- //Free memory
- if (inputCount){
- delete [] dataHolder;
- }
- inputCount = newSize;
- }
- std::size_t pullIndex() {
- for (std::size_t k = 0; k < Neuron::neurons.size(); k++){
- if (Neuron::neurons[k] == NULL) {
- Neuron::neurons[k] = this;
- return k;
- }
- }
- Neuron::neurons.push_back(this);
- return Neuron::neurons.size()-1;
- }
- void pushIndex() {
- Neuron::neurons[k] = NULL;
- }
- std::size_t index;
- std::size_t inputCount;
- neuron_t output;
- neuron_t * data;
- static neuron_t learningRate;
- static neuron_t overFittingWeight;
- static std::vector<Neuron*> neurons;
- };
- std::vector<Neuron*> Neuron::neurons;
- Neuron::neuron_t Neuron::learningRate;
- Neuron::neuron_t Neuron::overFittingWeight;
- class NeuronLayer{
- typedef Neuron::neuron_t neuron_t;
- public:
- NeuronLayer(std::size_t NeuronCount) : neurons(NULL),
- neuronCount(0),
- forwardLayerIndex(-1),
- backwardLayerIndex(-1)
- {
- updateNeuronArraySize(NeuronCount);
- }
- ~NeuronLayer(){
- pushIndex();
- adjustNeuronArraySize(NeuronCount);
- adjustInputArraySize()
- }
- void setBackwardLayer(int BackwardLayerIndex){
- if ( BackwardLayerIndex < NeuronLayer::neuronLayers.size()
- && NeuronLayer::neuronLayers[BackwardLayerIndex] != NULL
- && BackwardLayerIndex > 0){
- _backwardLayerIndex = BackwardLayerIndex;
- adjustInputArraySize(NeuronLayer::neuronLayers[BackwardLayerIndex]->getNeuronCount());
- }
- }
- void setForwardLayer(int ForwardLayerIndex){
- if ( ForwardLayerIndex < NeuronLayer::neuronLayers.size()
- && NeuronLayer::neuronLayers[ForwardLayerIndex] != NULL
- && ForwardLayerIndex > 0){
- _forwardLayerIndex = ForwardLayerIndex;
- }
- }
- /*
- propogateForward copies outputs from previous row and computes output of this layer with it
- */
- void propagateForward() {
- //check if backward layer is legit
- if (_backwardLayerIndex < 0 || _backwardLayerIndex >= NeuronLayer::neuronLayers.size() ) return;
- if (NeuronLayer::neuronLayers[_backwardLayerIndex] == NULL) return;
- //copy backward layer outputs;
- for (std::size_t k = 0; k < NeuronLayer::neuronLayers[_backwardLayerIndex]->getNeuronLayer(); k++){
- *(inputs+k) = NeuronLayer::neuronLayers[_backwardLayerIndex]->neurons()[k]->readOutput();
- }
- //compute outputs
- for (std::size_t k = 0; k < neuronCount; k++){
- //both returns and internally st
- (neurons+k)->computeOutput(inputs);
- }
- }
- void propagateBackward(neuron_t * LossDerivativeWithRespectToOutputs) {
- //check if backward Layer is legit
- if ( _backwardLayerIndex < 0
- || NeuronLayer::neuronLayers[_backwardLayerIndex] == NULL
- || _backwardLayerIndex >= NeuronLayer::neuronLayers.size()) return;
- //it's true that inputCount is equal to NeuronLayer::neuronLayers[_backwardLayerIndex]->neurCount();
- for ( std::size_t k = 0; k < neuronCount; k++){
- (neurons+k)->computeLossDerivativeWithRespectToInputWeightedSum( *(LossDerivativeWithRespectToOutputs+k) );
- (neurons-K)->adjustWeights(inputs);
- }
- }
- ~NeuronLayer(){
- pushIndex();
- updateInputArraySize(0);
- updateNeuronArraySize(0);
- }
- const std::size_t& getNeuronCount() const {
- return neuronCount;
- }
- int& forwardLayerIndex() {
- return _forwardLayerIndex;
- }
- int& backwardLayerIndex() {
- return _backwardLayerIndex;
- }
- const int& forwardLayerIndex() const {
- return _forwardLayerIndex;
- }
- const int& backwardLayerIndex() const {
- return _backwardLayerIndex;
- }
- const NeuronLayer()
- private:
- void updateNeuronArraySize(std::size_t newSize) {
- //sanity check
- if (newSize == neuronCount) return;
- //put neurons on temp var
- Neuron * neuronHolder = neurons;
- //create new neuronsList
- if (newSize) {
- neurons = new Neuron[newSize]; // inputs[newSize], weights[newSize], weightsDerivative[newSize]
- // where the derivative is with respect to all inputs
- if (newSize > inputSize){
- for (std::size_t k = 0; k < inputSize; k++)
- neurons[k] = neuronHolder[k];
- } else {
- for ( std::size_t k = 0; k < newSize; k++)
- neurons[k] = neuronHolder[k];
- }
- } else neurons = NULL;
- //Free memory
- if (inputCount) delete [] neuronHolder;
- neuronCount = newSize;
- }
- void setInputArraySize(std::size_t newSize) {
- //sanity check
- if (newSize == inputCount) return;
- //put neurons on temp var
- neuron_t * inputHolder = inputs;
- //create new neuronsList
- if (newSize) {
- inputs = new neuron_t[newSize];
- if (newSize > inputSize){
- for (std::size_t k = 0; k < inputSize; k++) {
- inputs[k] = inputsHolder[k];
- } else {
- for ( std::size_t k = 0; k < newSize; k++) {
- inputs[k] = inputsHolder[k];
- }
- }
- } else inputs = NULL;
- //Free memory
- if (inputCount) delete [] inputHolder;
- inputCount = newSize;
- }
- std::size_t pullIndex() {
- for (std::size_t k = 0; k < Neuron::neuronLayers.size(); k++){
- if (NeuronLayer::neuronLayers[k] == NULL) {
- NeuronLayer::neuronLayers[k] = this;
- return k;
- }
- }
- NeuronLayer::neuronLayers.push_back(this);
- return NeuronLayer::neuronLayers.size()-1;
- }
- void pushIndex() {
- NeuronLayer::neuronLayers[k] = NULL;
- }
- int _backwardLayerIndex;
- std::size_t index;
- std::size_t inputCount;
- std::size_t neuronCount;
- neuron_t * inputs;
- NeuronLayer * neuronLayers;
- static std::vector<NeuronLayer*> neuronLayers;
- };
- std::vector<NeuronLayer*> NeuronLayer::neuronLayers;
- class NeuralNetwork {
- public:
- NeuralNetwork( const std::size_t inputs,
- const std::size_t intermediate,
- const std::size_t outputs,
- const std::size_t layers) {};
- ~NeuralNetwork(){
- pushIndex();
- adjustLayerArraySize(0);
- }
- private:
- std::size_t pullIndex() {
- for (std::size_t k = 0; k < NeuralNetwork::networks.size(); k++){
- if (NeuralNetwork::networks[k] == NULL) {
- NeuralNetwork::networks[k] = this;
- return k;
- }
- }
- NeuronLayer::networks.push_back(this);
- return NeuralNetwork::networks.size()-1;
- }
- void pushIndex() {
- NeuralNetwork::networks[k] = NULL;
- }
- std::size_t index;
- NeuronLayer * layers;
- static std::vector<NeuralNetwork*> networks;
- };
- std::vector<NeuralNetwork*> networks;
- #endif
Add Comment
Please, Sign In to add comment