Neuronales Netzwerk implementieren - Datenstuktur



  • Ich will ein Neuronales Netzwerk mit C++14 implementieren und bin gerade dabei, die Datenstruktur zu definieren.

    Es soll möglichst effizient sein, als nichts mit jedes Neuron in eine Klasse packen.

    Ich dachte an einen

    typedef vector<Layer> NeuralNetwork;
    typedef vector<Neuron> Layer;
    class Neuron {
      float input;
      vector<float> weights; // hier sind die Gewichte gespeichert, Neron::size() == NextLayer.size()
    }
    
    float run(vector<float> input) // input.size() == NeuralNetwork.begin().size()
    {
      auto layer = NeuralNetwork.begin();
      // schreibe input in layer.input
      for (auto layer: NeuralNetwork)
      {
        for (neuron: layer)
        {
          nextLayer[neuron.index] += neuron.value*neuron.weights[index];
        }
      }
    }
    

    So ganz grob skizziert. Habt ihr da Verbesserungswünsche?



  • Der Input zur neuen Schicht ist eine lineare Kombination des Output der vorherigen Schicht.
    Also je Input bedeutet das: x_i=o_jwjix\_i= \sum{o\_j \cdot w_{ji}}
    Oder in Matrischreibweise: \overrightarrow{x}=W \cdot \overrightarrow{o}

    Du musst also diese Operation (Matrixmultiplikation) möglichst effizient implementieren. Zu deinem Glück gibt es bereits viele, optimierte Algorithmen zur Matrixmultiplikation.
    Am besten, du verwendest eine fertige Lib, z.B. könnte Eigen hierfür optimierte Varianten anbieten.



  • Danke für den Hinweis. Hier ist der Link zu Eigen: http://eigen.tuxfamily.org/index.php?title=Main_Page

    Aber ist meine Datenstruktur so OK oder gibt es da noch Verbesserungsmöglichkeiten?



  • fdggfd schrieb:

    Es soll möglichst effizient sein, als nichts mit jedes Neuron in eine Klasse packen.

    löl

    fdggfd schrieb:

    So ganz grob skizziert. Habt ihr da Verbesserungswünsche?

    Tu nicht sio auf Performance achten, sondern mach den Code einfach und lesbar. Die Performance ergibt sich dadurch fast von allein. Oder wenigstens optimierbar, wenn Dir neue Tricks einfallen.

    Die ganzen vielen kleinen vector<float> werden wild umher im Speicher stehen und nicht cache-freundlich sein, füchte ich.



  • @Volkard: OK, und wie würdest du es machen?



  • Etwa so:
    Ich dachte an einen
    class Neuron
    {
    list<pair<Neuron*,float>> connectedNeurons; // verbundene Neuronen mit Gewichten
    }

    typedef list<Neuron> NeuralNetwork;
    

    Wäre hier ein list<pair<shared_ptr<Neuron>,float>> angemessen?



  • Nö.



  • Also so:

    class Neuron
    {
      list<tuple<Neuron*, float>> connectedNeurons; // verbundene Neuronen mit Gewichten
      float value;
    }
    
    typedef list<Neuron> NeuralNetwork;
    

    ?



  • Wieso willst du denn überhaupt Neuronen als Klassen abbilden? Du hast einen Inputvektor x, eine lineare Abbildung W und einen Output y.
    Bei mehreren Schichten hast du das eben mehrfach. Fertig. Es gibt keinen Bedarf für eine Neuronenklasse.



  • Kann mir jemand einen möglichst primitiv gehaltenes C++-Quelltext für KNN verlinken?



  • dffds schrieb:

    Kann mir jemand einen möglichst primitiv gehaltenes C++-Quelltext für KNN verlinken?

    fang mal so an, wie du es zuerst machen wolltest.
    Dann miss die Laufzeit und wenn du nicht zufrieden bist, kannst du noch weiter optimieren.

    Mit Google sollte es recht einfach sein, C++ Quelltext zu finden, glaubst du nicht?


Log in to reply