"Новый нейронный" - проект Open Source движка нейронной сети для платформы MetaTrader 5. - страница 16

 

Я никак не могу понять суть проекта. Например, что такое движок нейронных сетей? И почему он должен быть один для разных типов сетей? Одни сети эффективно "двигаются" одним способом, другие другим. Описание структуры сетей соответственно тоже может быть разным. Для простого примера возьмите решение линейных уравнений. Можно конечно все типы линейных систем решить одним методом - Гаусса. Но, если мы знаем структуру матрицы коэффициентов, то есть более эффективные методы решения. Так же состоит задача обучения сетей. Сети прямого распространения обучаются методом обратного распространения ошибки, эхо сети обучаются МНК, и т.п. Почему бы вместо одного движка, создать несколько? Зачем нужна команда программистов работающих над одним и тем же и при этом пытающихся прийти к единомыслию? Единомыслие в данном случае препятствует творчеству. Пусть разные программисты пишут коды разных сетей в виде библиотеки с возможностью их вызова из индикаторов и советников. В таком случае, проект ничем не отличен от существующей системы посылки программистами их кодов в кодбазу библиотек, сопровождающейся статьёй с подробным описанием сети, как она работает и примеров её применения. Ничего плохого если несколько программистов независимо создадут коды одной и той же сети. Существуют десятки вариантов обучения сетей прямого рапсространения. При таком подходе к делу, вместо траты много времени на обсуждение как правильно описать сеть, народ начал бы уже создавать коды этих сетей. Например, мне очень интересно почитать статью TheXpert об эхо сетях. Но видимо получится нескоро.

 
gpwr:

Я никак не могу понять суть проекта. Например, что такое движок нейронных сетей? И почему он должен быть один для разных типов сетей?

Мы ж хотим универсальности. Нутрь и сборка будут конечно различаться. Унификация нужна для возможной визуализации и объединения в комитеты.

gpwr:

 Например, мне очень интересно почитать статью TheXpert об эхо сетях. Но видимо получится нескоро.

Ну вот в рамках опенсорса возможно и почитаешь :) .

Представление весов:


 

Собсно это все :)

Представление сети:


 

Примерный шаблон слоя:

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

Это прикидка для реализации MLP, бОльшая часть подходит под универсальный интерфейс.

m_vInSynapses

Вектор синапсов, входящих в слой. Эти синапсы и сам слой связаны через

m_pInputs

общий буфер. Поэтому изменение в буфере будет видно сразу как и объекту слоя, так и синапсам.

Таким же макаром связаны выходные синапсы через выходной буфер.

 

Синапсы:

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

Ошибки у синапсов тоже есть.

Ошибки нейронов предназначены для обучения порогов, ошибки синапсов для обучения синапсов.

Ну и собственно матрица весов (тут еще не хватает по-хорошему матрицы наличия весов, которую можно задавать вручную) и буферы для связи со слоями.

 

Сеть:

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

Примерно так выглядит сеть.

 

Построение и использование в простейшем тесте:

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

Плюс для типовых конфигураций можно сделать шаблоны.

 
TheXpert:

Так не получится :) надо как минимум знать что брать, чему учить и как оценивать. И вот эти вещи надо организовывать ручками.

Вот-вот. И я не знаю. Мало того, есть наборы, которые вообще очень сложно совместить. Нейронки просто инструмент. В умелых руках (Леонида взять хотя бе ) ) очень даже мощный.

Интересно, он поконсультировать не пожелает?

Маленькое имхо пока у вас тут затишье.В конечном итоге надо избежать риска создания продукта полностью удовлетворяющего по функционалу вашим потребностям , но совершенно не пригодного для остальных 99% потенциальных пользователей.

Если стоит задача предоставления аудитории нового инструмента , то он должен быть в идеале расчитан на всех, ну почти на всех , и тех кто первый раз открыл терминал и тех кто годами сидел на квике , и тех у кого два высших и тех у кого цпш .

Интерфейс и сам продукт должен быть прост и понятен как конструктор лего. 

 
Mischek:

Если стоит задача предоставления аудитории нового инструмента , то он должен быть в идеале расчитан на всех, ну почти на всех , и тех кто первый раз открыл терминал и тех кто годами сидел на квике , и тех у кого два высших и тех у кого цпш .

Ну вот для этого и желательно иметь кого-то компетентного, но не программиста.
 
papaklass:
Проведите опрос среди трейдеров. Какие задачи при торговле они решают? Получите то, что нужно большинству.
А трейдерам самим влом подтянуться и чёто сюда написать?