"New Neural" ist ein Open-Source-Projekt für neuronale Netzwerke für die MetaTrader 5-Plattform. - Seite 16

 

Ich habe keine Möglichkeit, das Wesen des Projekts zu verstehen. Was ist zum Beispiel eine neuronale Netzwerk-Engine? Und warum muss sie für verschiedene Arten von Netzen gleich sein? Einige Netze "bewegen" sich tatsächlich auf eine Weise, andere auf eine andere. Dementsprechend kann auch die Beschreibung der Struktur der Netze unterschiedlich ausfallen. Ein einfaches Beispiel ist das Lösen von linearen Gleichungen. Es ist natürlich möglich, alle Arten von linearen Systemen mit einer Methode zu lösen - Gauß. Aber wenn wir die Struktur der Koeffizientenmatrix kennen, gibt es effizientere Lösungsmethoden. Das gleiche Problem stellt sich bei der Ausbildung von Netzen. Netzwerke mit Vorwärtspropagation werden mit der Methode der Rückwärtsfehlerfortpflanzung trainiert, Echonetzwerke werden mit MNC trainiert, usw. Warum sollten Sie statt eines Motors mehrere Motoren entwickeln? Warum brauchen wir ein Team von Programmierern, das an derselben Sache arbeitet und versucht, einen Konsens zu finden? Einstimmigkeit verhindert in diesem Fall Kreativität. Lassen Sie verschiedene Programmierer die Codes der verschiedenen Netze in Form einer Bibliothek schreiben, die von den Indikatoren und Beratern aufgerufen werden kann. In diesem Fall unterscheidet sich das Projekt nicht von dem bestehenden System, bei dem Programmierer ihre Codes an die Codebasis der Bibliothek senden, begleitet von einem Artikel mit einer detaillierten Beschreibung des Netzwerks, seiner Funktionsweise und Beispielen für seine Verwendung. Es ist nicht schlimm, wenn mehrere Programmierer unabhängig voneinander Codes für dasselbe Netz erstellen. Es gibt Dutzende von Varianten für das Training von Direct Propagation Networks. Anstatt viel Zeit mit der Diskussion über die richtige Beschreibung eines Netzes zu verschwenden, würde man bei diesem Ansatz bereits damit beginnen, die Codes für diese Netze zu erstellen. Ich bin sehr daran interessiert, den Artikel von TheXpert über Echonetze zu lesen, zum Beispiel. Aber anscheinend wird das noch lange nicht der Fall sein.

 
gpwr:

Ich kann das Wesentliche des Projekts nicht verstehen. Was ist zum Beispiel die Engine des neuronalen Netzes? Und warum sollte es für verschiedene Arten von Netzen gleich sein?

Wir wollen Vielseitigkeit. Der Darm und die Montage werden natürlich unterschiedlich sein. Eine Vereinheitlichung ist für eine mögliche Visualisierung und Zusammenfassung in Ausschüssen erforderlich.

gpwr:

Ich bin zum Beispiel sehr daran interessiert, den Artikel von TheXpert über Echonetze zu lesen. Aber es wird wahrscheinlich sehr lange dauern.

Nun, Sie können es als Teil einer Opsorce lesen :) .

Darstellung von Skalen:


 

Das ist alles :)

Einführung in das Netzwerk:


 

Vorlage für eine Musterebene:

class LayerFunctional
{
        typedef boost::shared_ptr<Synapse> SynapsePtr;
        typedef std::vector<SynapsePtr> SynapseVector;
        typedef SynapseVector::iterator SynapseIterator;

public:
        typedef boost::shared_ptr<Vector> VectorPtr;
        typedef boost::shared_ptr<IPatternCollection> PatternsPtr;

public:
        LayerFunctional
                (         bool bAdaptiveStep
                        , double step
                        , size_t newSize
                        , bool bTUsed
                );

        void Init(const Initializer& initializer);

        void AddInputSynapse(boost::shared_ptr<Synapse> pSynapse);
        void RemoveInputSynapse(boost::shared_ptr<Synapse> pSynapse);

        void AddOutputSynapse(boost::shared_ptr<Synapse> pSynapse);
        void RemoveOutputSynapse(boost::shared_ptr<Synapse> pSynapse);

        void FwdPropagate();
        void BackPropagate();

        void ClearInputs();
        void ClearErrors();

        const size_t Size() const;

        void SetSize(size_t newSize);

        const bool ThresholdsUsed() const;
        void SetThresholdsUsed(bool used = false);

        const bool AdaptiveStepUsed() const;
        void SetAdaptiveStepUsed(bool used = false);
        const double GetStep() const;

        const VectorPtr GetInputs() const;
        const VectorPtr GetOutputs() const;
        const Vector& GetErrors() const;
        const Vector& GetThresholds() const;

        const PatternsPtr GetInputCollection() const;
        const PatternsPtr GetOutputCollection() const;


        void SetInputCollection(PatternsPtr patterns);
        void SetOutputCollection(PatternsPtr patterns);

        void FeedInputs(size_t patternIndex);
        void CompareOutputs(size_t patternIndex);

        void DoF(Vector& data);
        void DodF(Vector& data);

        void Learn();

        double CountAlpha();

        template<class Archive>
        void save(Archive & ar, const unsigned int version) const
        {
        }

        template<class Archive>
        void load(Archive & ar, const unsigned int version)
        {
        }

private:
        bool m_bAdaptiveStep;

        double m_Step;

        size_t m_Size;
        bool m_bTAreUsed;

        Vector m_vT;
        Vector m_vErrors;
        VectorPtr m_pInputs;
        VectorPtr m_pOutputs;

        SynapseVector m_vInSynapses;
        SynapseVector m_vOutSynapses;

        PatternsPtr m_pInputCollection;
        PatternsPtr m_pOutputCollection;
};

Dies ist eine Annäherung an die MLP-Implementierung, die größtenteils der universellen Schnittstelle entspricht.

m_vInSynapses

Ein Vektor der Synapsen, aus denen die Schicht besteht. Diese Synapsen und die Schicht selbst sind durch eine

m_pInputs

gemeinsamen Puffer. Daher wird eine Änderung im Puffer sowohl für das Ebenenobjekt als auch für die Synapsen sofort sichtbar.

Auch die Ausgangssynapsen sind auf die gleiche Weise über den Ausgangspuffer verbunden.

 

Synapsen:

class Synapse
{
        Synapse()
        {
        }

public:
        typedef boost::shared_ptr<Vector> VectorPtr;

public:
        Synapse(boost::shared_ptr<Vector> inputVector, boost::shared_ptr<Vector> outputVector);
        
        void AssignInput(boost::shared_ptr<Vector> inputVector);
        void AssignOutput(boost::shared_ptr<Vector> outputVector);

        void FwdPropagate();
        void BackPropagate(LayerFunctional* outLayer);

        double operator()(size_t inIdx, size_t outIdx) const;

        const Detail::Slice FromInput(size_t inIdx) const;
        const Detail::Slice ToOutput(size_t outIdx) const;

        size_t GetOutSize() const;
        size_t GetInSize() const;

        const Vector& GetErrors() const;
        void ZeroErrors();

        void Init(const Initializer& initializer);
        void Learn(LayerFunctional* outLayer, const double& step);

        const VectorPtr GetInputs() const;
        const VectorPtr GetOutputs() const;

        void SetValues(const Synapse& other);

private:
        size_t m_InSize;
        size_t m_OutSize;

        Matrix m_vSynapses;
        Vector m_vErrors;

        VectorPtr m_pInBuffer;
        VectorPtr m_pOutBuffer;
};

Fehler in den Synapsen sind ebenfalls vorhanden.

Fehler von Neuronen sind für Lernschwellen, Fehler von Synapsen sind für Lernsynapsen.

Und die eigentliche Matrix der Gewichte (was hier fehlt, ist eine gute Matrix der Verfügbarkeit der Gewichte, die manuell eingestellt werden kann) und Puffer für die Kommunikation mit den Schichten.

 

Das Netz:

class Net
{
        typedef boost::shared_ptr<LayerFunctional> LayerPtr;
        typedef boost::shared_ptr<Synapse> SynapsePtr;
        
        typedef std::vector<LayerPtr> LayersVector;
        typedef std::vector<SynapsePtr> SynapsesVector;

public:
        Net();

        void AddLayer(size_t size, bool bTUsed)
        void AddLayer(const LayerPtr& pLayer);

        LayerPtr GetLayer(size_t index) const;
        SynapsePtr GetSynapse(size_t index) const;

        void ConnectLayers(LayerPtr& inLayer, LayerPtr& outLayer);
        size_t GetLayersCount() const;

        size_t GetSynapsesCount() const;

        void Init(const Initializer& initializer);

        void FeedInputs(size_t patternIndex);
        void FwdPropagate();
        void BackPropagate();
        void CountErrors(size_t patternIndex);
        void Learn();

        size_t GetLayerID(const LayerPtr& pLayer) const;

        void save(Archive & ar, const unsigned int version) const
        void load(Archive & ar, const unsigned int version)

private:
        struct Link;

        typedef std::vector<Link> LinksVector;

private:
        size_t m_LayersCount;
        size_t m_SynapsesCount;

        LayersVector m_vLayers;
        SynapsesVector m_vSynapses;
        LinksVector m_vLinks;
};

So sieht das Netz ungefähr aus.

 

Erstellen und Verwenden im einfachsten Test:

void XORTest()
{
        Net net;

        LayerPtr inLayer(new Layer<Functions::LinearFunction>(false, 0.2, 2, false));
        LayerPtr hiddenLayer(new Layer<Functions::BiSigmoidFunction>(false, 0.2, 3, false));
        LayerPtr outLayer(new Layer<Functions::LinearFunction>(false, 0.2, 1, false));

        net.AddLayer(inLayer);
        net.AddLayer(hiddenLayer);
        net.AddLayer(outLayer);

        net.ConnectLayers(inLayer, hiddenLayer);
        net.ConnectLayers(hiddenLayer, outLayer);

        PatternsPtr inPattern(new PatternCollection<>(2));
        // filling patterns

        PatternsPtr outPattern(new PatternCollection<>(1));
        // filling patterns

        inLayer->SetInputCollection(inPattern);
        outLayer->SetOutputCollection(outPattern);

        Initializer initer(0.1);
        net.Init(initer);

        size_t count = 0;
        double Es = 0.0;

        do 
        {
                Es = 0.0;
                for (size_t i = 0; i < 4; ++i)
                {
                        net.FeedInputs(i);
                        net.FwdPropagate();
                        net.CountErrors(i);
                        net.BackPropagate();
                        net.Learn();

                        Vector v(outLayer->Size());
                        v = outLayer->GetErrors();
                        v *= v;

                        Es += v.sum()/2.0;
                }

                ++count;
        } while(Es > 0.0001 && count < 10000);
}

Außerdem können Vorlagen für typische Konfigurationen erstellt werden.

 
TheXpert:

Das wird nicht funktionieren :) man muss zumindest wissen, was man nimmt, was man lehrt und wie man bewertet. Und das sind die Dinge, die Sie mit Ihren Händen organisieren müssen.

Genau. Und ich weiß es nicht. Darüber hinaus gibt es Sets, die nur sehr schwer zu kombinieren sind. Neuronen sind nur ein Werkzeug. In geschickten Händen (z. B. bei Leonid) ist sie sehr mächtig.

Ich frage mich, ob er bereit wäre, Ihnen einen Rat zu geben.

Letztlich müssen Sie das Risiko vermeiden, ein Produkt zu entwickeln, das zwar Ihre Anforderungen an die Funktionalität voll erfüllt, aber für 99 % der potenziellen Nutzer völlig unbrauchbar ist.

Wenn wir dem Markt ein neues Handelsinstrument anbieten müssen, sollte es sich an alle richten, auch an diejenigen, die gerade erst das Terminal geöffnet haben, an diejenigen, die seit Jahren das Handrad benutzen, an diejenigen, die zwei höhere Abschlüsse haben und an diejenigen, die einen höheren Computer besitzen.

Die Schnittstelle und das Produkt selbst sollten so einfach und verständlich sein wie ein Lego-Bausatz.

 
Mischek:

Wenn die Aufgabe darin besteht, dem Publikum ein neues Werkzeug zur Verfügung zu stellen, sollte es sich idealerweise an alle richten, na ja, fast alle, einschließlich derjenigen, die das Terminal zum ersten Mal geöffnet haben, und derjenigen, die schon seit Jahren süchtig danach sind, und derjenigen, die zwei Hochschulabschlüsse haben, und derjenigen, die einen Tspsh haben.

Ich denke, es ist wünschenswert, jemanden zu haben, der kompetent, aber kein Programmierer ist.
 
papaklass:
Führen Sie eine Umfrage unter den Händlern durch. Welche Handelsaufgaben lösen sie? Holen Sie sich, was die meisten Menschen brauchen.
Ist es zu viel Aufwand für die Händler selbst, hier etwas zu schreiben?