x89codered89x

machinelearning.h

Feb 19th, 2014
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.91 KB | None | 0 0
  1. #ifndef MACHINE_LEARNING_H
  2. #define MACHINE_LEARNING_H
  3.  
  4. #typedef float neuron_t;
  5.  
  6.  
  7. #include <cmath>
  8. #include "mymath.h"
  9.  
  10. namespace MachineLearning {
  11.  
  12.  
  13.  
  14. }
  15.  
  16. class Neuron {
  17.  
  18.     public:
  19.         //Types
  20.         typedef float neuron_t;
  21.  
  22.         //....
  23.  
  24.         Neuron( std::size_t InputCount = 2) :   output(.5),
  25.                                                 data(NULL),
  26.                                                 inputCount(0),
  27.                                                 index(pullIndex()),    
  28.  
  29.         {
  30.             updateArraySizes(InputCount);
  31.         }
  32.  
  33.         ~Neuron(){
  34.             pushIndex();
  35.             updateArraySizes(0);
  36.         }
  37.  
  38.  
  39.  
  40.         neuron_t* getData() const {
  41.             return data;
  42.         }
  43.  
  44.  
  45.  
  46.         const neuron_t& readOutput() const {
  47.             return output;
  48.         }
  49.  
  50.         Neuron::neuron_t calculateOutput(Neuron_t * inputs) {
  51.             //error handling?
  52.             output = Math::sigmoid(Math::dot(inputs,weights(), inputCount));
  53.             return output;
  54.  
  55.         }          
  56.  
  57.         //output must have been computed before hand
  58.         void computeLossDerivativeWithRespectToInputWeightedSum(Neuron::neuron_t LossDerivativeWithRespectToOutput){
  59.             _lossDerivativeWithRespectToWeightedInputSum *= LossDerivativeWithRespectToOutput*output*(neuron_t(1)-output);
  60.         }
  61.  
  62.         graphics_t lossDerivativeWithRespectToInputWeightedSum() const {
  63.             return _lossDerivativeWithRespectToWeightedInputSum;
  64.         }
  65.  
  66.         void adjustWeights(neuron_t * inputs){
  67.             for (std::size_t k = 0; k < inputCount; k++){
  68.                 *(weights()[k]) *= (neuron_t(1)- MachineLearning::LEARNING_RATE*_lossDerivativeWithRespectToWeightedInputSum*( *(inputs()[k]) ) );
  69.             }
  70.         }      
  71.  
  72.         const std::size_t& getIndex() const {
  73.             return index;
  74.         }
  75.  
  76.         const Neuron& operator=(const Neuron& rhs){
  77.  
  78.             if (inputCount == rhs.getInputCount()){
  79.  
  80.                 updateArraySizes(rhs.getInputCount());
  81.  
  82.             }
  83.  
  84.             for (std::size_t k = 0; k < rhs.getInputCount(); k++){
  85.                 data[k] = rhs.getData()[k];
  86.             }
  87.  
  88.             output = rhs.getOutput();
  89.         }
  90.  
  91.  
  92.     private:
  93.  
  94.         Neuron::neuron_t* weights() {
  95.             return data;   
  96.         }
  97.  
  98.         Neuron::neuron_t* weightsDerivative() {
  99.             return (data + inputCount);
  100.         }
  101.  
  102.         void updateArraySizes(std::size_t newSize) {
  103.  
  104.             if (inputCount == newSize) return;
  105.  
  106.             neuron_t * dataHolder = data;
  107.  
  108.             //create new neuronsList
  109.             if (newSize) {
  110.                 data = new neuron_t[newSize];
  111.  
  112.                 if (newSize > inputSize){
  113.                     for (std::size_t k = 0; k < inputSize; k++) {
  114.                         data[k] = dataHolder[k];
  115.  
  116.                 } else {
  117.                     for ( std::size_t k = 0; k < newSize; k++) {
  118.                         data[k] = dataHolder[k];
  119.  
  120.                     }
  121.                 }
  122.  
  123.             } else {
  124.                 data = NULL;
  125.             }
  126.  
  127.             //Free memory
  128.             if (inputCount){
  129.                 delete [] dataHolder;
  130.             }
  131.  
  132.             inputCount = newSize;
  133.         }
  134.  
  135.         std::size_t pullIndex() {
  136.             for (std::size_t k = 0; k < Neuron::neurons.size(); k++){
  137.                 if (Neuron::neurons[k] == NULL) {
  138.                     Neuron::neurons[k] = this;
  139.                     return k;
  140.                 }
  141.             }
  142.  
  143.             Neuron::neurons.push_back(this);
  144.             return Neuron::neurons.size()-1;
  145.         }
  146.  
  147.         void pushIndex() {
  148.             Neuron::neurons[k] = NULL;
  149.         }
  150.  
  151.         std::size_t index;
  152.         std::size_t inputCount;
  153.  
  154.         neuron_t output;
  155.         neuron_t * data;   
  156.  
  157.         static neuron_t learningRate;
  158.         static neuron_t overFittingWeight;
  159.         static std::vector<Neuron*> neurons;
  160. };
  161. std::vector<Neuron*> Neuron::neurons;
  162. Neuron::neuron_t Neuron::learningRate;
  163. Neuron::neuron_t Neuron::overFittingWeight;
  164.  
  165. class NeuronLayer{
  166.  
  167.     typedef Neuron::neuron_t neuron_t;
  168.  
  169.     public:
  170.  
  171.         NeuronLayer(std::size_t NeuronCount) :  neurons(NULL),
  172.                                                 neuronCount(0),
  173.                                                 forwardLayerIndex(-1),
  174.                                                 backwardLayerIndex(-1)
  175.         {
  176.  
  177.             updateNeuronArraySize(NeuronCount);
  178.  
  179.         }
  180.  
  181.         ~NeuronLayer(){
  182.  
  183.             pushIndex();
  184.             adjustNeuronArraySize(NeuronCount);
  185.             adjustInputArraySize()
  186.  
  187.  
  188.         }
  189.  
  190.         void setBackwardLayer(int BackwardLayerIndex){                 
  191.             if (        BackwardLayerIndex < NeuronLayer::neuronLayers.size()
  192.                     &&  NeuronLayer::neuronLayers[BackwardLayerIndex] != NULL  
  193.                     &&  BackwardLayerIndex > 0){
  194.  
  195.                     _backwardLayerIndex = BackwardLayerIndex;
  196.                     adjustInputArraySize(NeuronLayer::neuronLayers[BackwardLayerIndex]->getNeuronCount());
  197.             }
  198.         }
  199.  
  200.         void setForwardLayer(int ForwardLayerIndex){                   
  201.             if (        ForwardLayerIndex < NeuronLayer::neuronLayers.size()
  202.                     &&  NeuronLayer::neuronLayers[ForwardLayerIndex] != NULL   
  203.                     &&  ForwardLayerIndex > 0){
  204.  
  205.                     _forwardLayerIndex = ForwardLayerIndex;
  206.             }
  207.         }
  208.  
  209.  
  210.         /*
  211.  
  212.             propogateForward copies outputs from previous row and computes output of this layer with it
  213.  
  214.         */
  215.         void propagateForward() {
  216.  
  217.             //check if backward layer is legit
  218.             if (_backwardLayerIndex < 0 || _backwardLayerIndex >= NeuronLayer::neuronLayers.size() ) return;
  219.             if (NeuronLayer::neuronLayers[_backwardLayerIndex] == NULL) return;
  220.  
  221.             //copy backward layer outputs;
  222.             for (std::size_t k = 0; k < NeuronLayer::neuronLayers[_backwardLayerIndex]->getNeuronLayer(); k++){
  223.                 *(inputs+k) = NeuronLayer::neuronLayers[_backwardLayerIndex]->neurons()[k]->readOutput();
  224.             }
  225.  
  226.             //compute outputs
  227.             for (std::size_t k = 0; k < neuronCount; k++){
  228.  
  229.                 //both returns and internally st
  230.                 (neurons+k)->computeOutput(inputs);
  231.             }  
  232.  
  233.         }
  234.  
  235.         void propagateBackward(neuron_t * LossDerivativeWithRespectToOutputs) {
  236.             //check if backward Layer is legit
  237.                 if (        _backwardLayerIndex < 0
  238.             ||  NeuronLayer::neuronLayers[_backwardLayerIndex] == NULL 
  239.             ||  _backwardLayerIndex >= NeuronLayer::neuronLayers.size()) return;
  240.  
  241.             //it's true that inputCount is equal to NeuronLayer::neuronLayers[_backwardLayerIndex]->neurCount();
  242.  
  243.             for ( std::size_t k = 0; k < neuronCount; k++){
  244.                 (neurons+k)->computeLossDerivativeWithRespectToInputWeightedSum( *(LossDerivativeWithRespectToOutputs+k) );
  245.                 (neurons-K)->adjustWeights(inputs);
  246.             }  
  247.         }
  248.  
  249.  
  250.         ~NeuronLayer(){
  251.  
  252.             pushIndex();
  253.             updateInputArraySize(0);
  254.             updateNeuronArraySize(0);
  255.  
  256.         }
  257.  
  258.         const std::size_t& getNeuronCount() const {
  259.             return neuronCount;
  260.         }
  261.  
  262.  
  263.         int& forwardLayerIndex() {
  264.             return _forwardLayerIndex;
  265.         }
  266.         int& backwardLayerIndex() {
  267.             return _backwardLayerIndex;
  268.         }
  269.  
  270.         const int& forwardLayerIndex() const {
  271.             return _forwardLayerIndex;
  272.         }
  273.         const int& backwardLayerIndex() const {
  274.             return _backwardLayerIndex;
  275.         }
  276.  
  277.         const NeuronLayer()
  278.  
  279.  
  280.  
  281.  
  282.     private:
  283.  
  284.         void updateNeuronArraySize(std::size_t newSize) {
  285.  
  286.             //sanity check
  287.             if (newSize == neuronCount) return;
  288.  
  289.             //put neurons on temp var
  290.             Neuron * neuronHolder = neurons;
  291.  
  292.             //create new neuronsList
  293.             if (newSize) {
  294.                 neurons = new Neuron[newSize]; // inputs[newSize], weights[newSize], weightsDerivative[newSize]
  295.                                                 // where the derivative is with respect to all inputs
  296.                 if (newSize > inputSize){
  297.                     for (std::size_t k = 0; k < inputSize; k++)
  298.                         neurons[k] = neuronHolder[k];
  299.                 } else {
  300.                     for ( std::size_t k = 0; k < newSize; k++)
  301.                         neurons[k] = neuronHolder[k];
  302.                 }
  303.  
  304.             } else neurons = NULL;
  305.  
  306.             //Free memory
  307.             if (inputCount) delete [] neuronHolder;
  308.  
  309.             neuronCount = newSize;
  310.         }
  311.  
  312.  
  313.         void setInputArraySize(std::size_t newSize) {
  314.  
  315.  
  316.             //sanity check
  317.             if (newSize == inputCount) return;
  318.  
  319.             //put neurons on temp var
  320.             neuron_t * inputHolder = inputs;
  321.  
  322.             //create new neuronsList
  323.             if (newSize) {
  324.                 inputs = new neuron_t[newSize];
  325.                 if (newSize > inputSize){
  326.                     for (std::size_t k = 0; k < inputSize; k++) {
  327.                         inputs[k] = inputsHolder[k];
  328.  
  329.                 } else {
  330.                     for ( std::size_t k = 0; k < newSize; k++) {
  331.                         inputs[k] = inputsHolder[k];
  332.                     }
  333.                 }
  334.  
  335.             } else  inputs = NULL;
  336.  
  337.             //Free memory
  338.             if (inputCount) delete [] inputHolder;
  339.             inputCount = newSize;
  340.         }      
  341.  
  342.         std::size_t pullIndex() {
  343.             for (std::size_t k = 0; k < Neuron::neuronLayers.size(); k++){
  344.                 if (NeuronLayer::neuronLayers[k] == NULL) {
  345.                     NeuronLayer::neuronLayers[k] = this;
  346.                     return k;
  347.                 }
  348.             }
  349.  
  350.             NeuronLayer::neuronLayers.push_back(this);
  351.             return NeuronLayer::neuronLayers.size()-1;
  352.         }
  353.  
  354.         void pushIndex() {
  355.             NeuronLayer::neuronLayers[k] = NULL;
  356.         }
  357.  
  358.         int _backwardLayerIndex;
  359.  
  360.         std::size_t index;
  361.         std::size_t inputCount;
  362.         std::size_t neuronCount;
  363.  
  364.  
  365.         neuron_t * inputs;
  366.         NeuronLayer * neuronLayers;
  367.  
  368.         static std::vector<NeuronLayer*> neuronLayers;
  369. };
  370. std::vector<NeuronLayer*> NeuronLayer::neuronLayers;
  371.  
  372. class NeuralNetwork {
  373.    
  374.     public:
  375.  
  376.         NeuralNetwork(  const std::size_t inputs,
  377.                         const std::size_t intermediate,
  378.                         const std::size_t outputs,
  379.                         const std::size_t layers)   {};
  380.         ~NeuralNetwork(){
  381.  
  382.             pushIndex();
  383.             adjustLayerArraySize(0);
  384.  
  385.         }
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.     private:
  400.  
  401.        
  402.  
  403.         std::size_t pullIndex() {
  404.             for (std::size_t k = 0; k < NeuralNetwork::networks.size(); k++){
  405.                 if (NeuralNetwork::networks[k] == NULL) {
  406.                     NeuralNetwork::networks[k] = this;
  407.                     return k;
  408.                 }
  409.             }
  410.  
  411.             NeuronLayer::networks.push_back(this);
  412.             return NeuralNetwork::networks.size()-1;
  413.         }
  414.  
  415.         void pushIndex() {
  416.             NeuralNetwork::networks[k] = NULL;
  417.         }
  418.  
  419.  
  420.         std::size_t index;
  421.  
  422.         NeuronLayer * layers;
  423.  
  424.         static std::vector<NeuralNetwork*> networks;
  425. };
  426. std::vector<NeuralNetwork*> networks;
  427.  
  428.  
  429.  
  430.  
  431.  
  432. #endif
Add Comment
Please, Sign In to add comment