"New Neural" è un progetto di motore di rete neurale Open Source per la piattaforma MetaTrader 5. - pagina 16

 

Non ho modo di capire l'essenza del progetto. Per esempio, cos'è un motore di rete neurale? E perché deve essere lo stesso per diversi tipi di reti? Alcune reti si "muovono" effettivamente in un modo, altre in un altro. La descrizione della struttura delle reti può anche essere diversa di conseguenza. Per un esempio semplice, prendiamo la risoluzione di equazioni lineari. Naturalmente è possibile risolvere tutti i tipi di sistemi lineari con un metodo - Gauss. Ma se conosciamo la struttura della matrice dei coefficienti, ci sono metodi di soluzione più efficienti. Lo stesso è il problema dell'addestramento delle reti. Le reti di propagazione in avanti sono addestrate con il metodo di propagazione dell'errore all'indietro, le reti eco sono addestrate con MNC, ecc. Perché invece di un solo motore, creare diversi motori? Perché abbiamo bisogno di un team di programmatori che lavorano sulla stessa cosa cercando di raggiungere il consenso? L'unanimità in questo caso impedisce la creatività. Lascia che diversi programmatori scrivano i codici di diverse reti sotto forma di una libreria che può essere chiamata dagli indicatori e dai consulenti. In questo caso, il progetto non è diverso dal sistema esistente di invio da parte dei programmatori dei loro codici alla base di codice della biblioteca, accompagnato dall'articolo con una descrizione dettagliata della rete, come funziona ed esempi del suo utilizzo. Non c'è niente di male se diversi programmatori creano codici della stessa rete in modo indipendente. Ci sono decine di varianti per l'addestramento di reti a propagazione diretta. Con questo approccio, invece di perdere un sacco di tempo a discutere su come descrivere correttamente una rete, le persone inizierebbero già a creare i codici di queste reti. Sono molto interessato a leggere l'articolo di TheXpert sulle reti eco, per esempio. Ma a quanto pare non accadrà per molto tempo.

 
gpwr:

Non riesco a capire l'essenza del progetto. Per esempio, cos'è il motore delle reti neurali? E perché dovrebbe essere lo stesso per diversi tipi di reti?

Vogliamo versatilità. Il budello e il montaggio saranno ovviamente diversi. L'unificazione è necessaria per una possibile visualizzazione e combinazione in comitati.

gpwr:

Per esempio, sono molto interessato a leggere l'articolo di TheXpert sulle reti eco. Ma probabilmente ci vorrà molto tempo.

Beh, forse si può leggere come parte di un opsorce :) .

Rappresentazione di scale:


 

Questo è tutto :)

Presentazione della rete:


 

Modello di stratocampione:

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;
};

Questa è un'approssimazione per l'implementazione di MLP, la maggior parte si adatta all'interfaccia universale.

m_vInSynapses

Un vettore delle sinapsi che compongono lo strato. Queste sinapsi e lo strato stesso sono collegati attraverso un

m_pInputs

buffer comune. Pertanto, un cambiamento nel buffer sarà immediatamente visibile sia all'oggetto livello che alle sinapsi.

Anche le sinapsi di uscita sono collegate allo stesso modo attraverso il buffer di uscita.

 

Sinapsi:

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;
};

Ci sono anche errori nelle sinapsi.

Gli errori dei neuroni sono per l'apprendimento delle soglie, gli errori delle sinapsi sono per l'apprendimento delle sinapsi.

E l'attuale matrice di pesi (ciò che manca qui è una buona matrice di disponibilità di pesi, che può essere impostata manualmente) e i buffer per la comunicazione con i livelli.

 

La rete:

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;
};

Questo è più o meno l'aspetto della rete.

 

Costruire e utilizzare nel test più semplice:

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);
}

Inoltre si possono fare dei modelli per le configurazioni tipiche.

 
TheXpert:

Non funzionerà :) bisogna sapere almeno cosa prendere, cosa insegnare e come valutare. E queste sono le cose che devi organizzare con le tue mani.

Esattamente, e non lo so. Non solo, ci sono set che sono molto difficili da combinare. I neuroni sono solo uno strumento. In mani abili (prendete Leonid per esempio) è molto potente.

Mi chiedo se sarebbe disposto a darti dei consigli.

Alla fine, dovete evitare il rischio di creare un prodotto che soddisfi pienamente le vostre esigenze in termini di funzionalità, ma che sarà completamente inutilizzabile per il 99% dei potenziali utenti.

Se dobbiamo offrire un nuovo strumento di trading al mercato, dovrebbe essere rivolto a tutti, compresi quelli che hanno appena aperto il terminale, quelli che usano il volantino da anni, quelli che hanno due lauree superiori e quelli che hanno un computer superiore.

L'interfaccia e il prodotto stesso dovrebbero essere semplici e comprensibili come un set Lego.

 
Mischek:

Se il compito è quello di fornire un nuovo strumento al pubblico, idealmente dovrebbe essere rivolto a tutti, beh, quasi tutti, compresi quelli che hanno aperto il terminale per la prima volta e quelli che sono stati agganciati per anni, e quelli che hanno due lauree e quelli che hanno un Tspsh.

Penso che sia auspicabile avere qualcuno competente, ma non un programmatore.
 
cartapesta:
Condurre un sondaggio tra i commercianti. Quali compiti commerciali risolvono? Prendi ciò di cui la maggior parte delle persone ha bisogno.
È troppo difficile per i commercianti stessi venire a scrivere qualcosa qui?
Motivazione: