O "New Neural" é um projecto de motor de rede neural Open Source para a plataforma MetaTrader 5. - página 86

 
Serj_Che:

O que há de tão embaraçoso nisso?

Bem, aqui estão mais provas - eu não cuspi por nada :) e na verdade - as regras de persepromisso de Rosenblatt ))
 

Pronto para se envolver - com soluções prontas, experiência, e até codificação.

Precisamos de um fio fechado onde possamos discutir adequadamente a arquitetura, perspectivas e direções

 
yu-sha:

Pronto para se envolver - com soluções prontas, experiência, e até codificação.

Muita gente está pronta há muito tempo. Mas as MetaQuotes não podem passar das palavras aos actos, pois não?

yu-sha:

Precisa de um tópico fechado onde você possa discutir adequadamente a arquitetura, perspectivas e direções

Quanto mais discussão podemos ter? Só 86 páginas deste fio.

O fato de que todos os alagadores deste tópico se moverão para um ramo privado, é claro, o resto dos visitantes do fórum será melhor, pois a leitura de dezenas de páginas de inundação não será necessária.

Na realidade tudo é muito mais fácil, porque quem precisa e quem sabe como fazer isso há muito tempo desenhou uma grelha. O resto de nós lemos 86 páginas de inundações neste fórum.

A questão é que alguns visitantes deste fórum também têm alguma experiência e know-how sobre o assunto.

Por exemplo, eu tenho um projeto OOP feito por mim em Java. Não o reconstruí para o mql5, porque não havia necessidade.

Fi-lo por mim mesmo com o meu próprio algoritmo de aprendizagem. A principal vantagem é que você não sabe com antecedência quantos neurônios são necessários em uma camada oculta. A grade pode remover neurônios extras da camada oculta e coeficientes de ponderação extras do neurônio de saída, respectivamente.

Isto é o aspecto de um neurónio artificial:

package neuronet;
import java.util.*;

/**
 * Искусственный нейрон
 * @author Yury V. Reshetov
 */
public class Neuron {
    /**
     * Весовые коэффициенты
     */
    private double[] weights = null;
    
    /**
     * Пороговое значение
     */
    private double threshold = 0 d;
    
    private int[] result = null; 
    
    /**
     * Конструктор нейрона
     * @param w весовые коэффициенты
     * @param t пороговое значение
     */
    public Neuron(double[] w, double t) {
        this.weights = w;
        this.threshold = t;
    }
    
    /**
     * Конструктор случайного нейрона
     * @param inputs количество весовых коэффициентов
     * @param rand генератор псевдослучайных чисел
     */
    public Neuron(int inputs, Random rand) {
        this.threshold = rand.nextDouble() * 2 d - 1 d;
        this.weights = new double[inputs];
        for (int i = 0; i < inputs; i++) {
            this.weights[i] = rand.nextDouble() * 2 d - 1 d;
        }
    }

    /**
     * Вычисление
     * @param inputs входные значения
     * @return результат на выходе нейрона
     */
    public double getOutput(double[] inputs) {
        double sum = this.threshold;
        for (int i = 0; i < this.weights.length; i++) {
            sum = sum + inputs[i] * this.weights[i];
        }
        return this.getSigmoidValue(sum);
    }
    
    /**
     * Возвращает значения весовых коэффициентов
     * @return весовые коэффициенты
     */
    public double[] getWeights() {
        return this.weights;
    }
    
    /**
     * Возвращает пороговое значение
     * @return пороговое значение
     */
    public double getThreshold() {
        return this.threshold;
    }
    
    /**
     * Возвращает результаты
     * @return результаты
     */
    public int[] getResult() {
        return this.result;
    }
    
    public void changeWeights(double[] w) {
        this.weights = w;
    }
    
    
    /**
     * Обучение нейрона
     * @param samples обучающая выборка. Последний элемент столбца - выходное значение
     */
    public void learning(double[][] samples) {
        // Заменяем выходное значение на обратную функцию сигмоида из этого значения
        for (int i = 0; i < samples.length; i++) {
            samples[i][samples[0].length - 1] = this.getArcSigmoidValue(samples[i][samples[0].length - 1]);
        }
        
        double[][] tempsamples = new double[samples.length][samples[0].length * 2];

        int count = samples[0].length;

        for (int i = 0; i < tempsamples.length; i++) {
            for (int j = 0; j < count; j++) {
                tempsamples[i][j] = samples[i][j]; 
                tempsamples[i][j + count] = - tempsamples[i][j];
            }
        }
        
        // Создаем объект оптимизатора
        Optimizator opt = new Optimizator(new Random());
        
        // Получаем результаты
        this.result = opt.getDataForColls(tempsamples, tempsamples[0].length);
        
        // Переводим результаты в вещественный формат
        double[] res = new double[this.result.length];
        
        for (int i = 0; i < res.length; i++) {
            res[i] = this.result[i];
        }

        
        // Получаем значения количества использований оптимизатором для примеров
        int[] getP = opt.getP();
        // Максимальное значение количества использований
        int maximum = getP[0];
        // Индекс примера с максимальным количеством использований
        int maxindex = 0;
        // Ищем индекс примера с максимальным количеством использований
        for (int i = 1; i < getP.length; i++) {
            if (getP[i] > maximum) {
                maximum = getP[i];
                maxindex = i;
            }
        }
    
    
       // Максимальное значение весового коэффициента
        double maxi = Math.abs(res[0]);
    
        // Ищем максимальное значение весового коэффициента
        for (int i = 1; i < res.length; i++) {
            if (Math.abs(res[i]) > maxi) {
                maxi = Math.abs(res[i]);
            }
        }
        
        // Стабильное абсолютное значение константы 
        double bestsum = 0;
        // Вычисляем стабильное значение константы 
        for (int j = 0; j < samples[0].length; j++) {
            bestsum = bestsum + res[j] * samples[maxindex][j];
        }
        // Получаем стабильное абсолютное значение константы 
        bestsum = Math.abs(bestsum);
    
        // Корректируем результаты на стабильное абсолютное значение константы
        for (int i = 0; i < res.length; i++) {
            res[i] = res[i] / bestsum;
        }
        
        // Вычисляем пороговое значение
        this.threshold = 1 d / res[res.length - 1];
        
        // Вычисляем весовые коэффициенты
        for (int i = 0; i < this.weights.length; i++) {
            this.weights[i] = -res[i] / res[res.length - 1];
        }
        
    }
    
    /**
     * Вычисляет значение сигмоидальной функции
     * @return значение сигмоидальной функции
     */
    private double getSigmoidValue(double x) {
        return Math.atan(x);
    }
    
    /**
     * Вычисляет обратное значение сигмоидальной функции
     * @return обратное значение сигмоидальной функции
     */
    private double getArcSigmoidValue(double x) {
        return Math.tan(x);
    }
}

Isto é o que parece uma camada escondida:

package neuronet;

import java.util.*;

/**
 * Скрытый слой 
 * @author Yury V. Reshetov
 */
public class HiddenLayer {
    
    // Массив нейронов скрытого слоя
    private Neuron[] neurons = null;
    
    /**
     * Создание скрытого слоя нейронов
     * @param neuronscount количество нейронов в скрытом слое
     * @param inputscount количество входов у нейронов
     * @param rand генератор склучайных чисел
     */
    public HiddenLayer(int inputscount, Random rand) {
        this.neurons = new Neuron[inputscount * 5];
        System.out.println("Количество нейронов скрытого слоя = " + this.neurons.length);
        for (int i = 0; i < this.neurons.length; i++) {
            this.neurons[i] = new Neuron(inputscount, rand);
        }
    }
    
    /**
     * Возвращает массив нейронов
     * @return массив нейронов скрытого слоя
     */
    public Neuron[] getNeurons() {
        return this.neurons;
    }
    
    /**
     * Возвращает результаты входного слоя
     * @param inputs массив входных значений
     * @return массив результатов
     */
    public double[] getOutputs(double[] inputs) {
        double[] results = new double[this.neurons.length];
        for (int i = 0; i < this.neurons.length; i++) {
            results[i] = this.neurons[i].getOutput(inputs);
        }
        return results;
    }
    
    /**
     * Получает обучающую выборку для следующего нейрона из входной обучающей выборки
     * @param samples обучающая выборка
     * @return обучающая выборка для следующего нейрона
     */
    public double[][] getOutputs(double[][] samples) {
        double[][] results = new double[samples.length][this.neurons.length + 1];
        for (int i = 0; i < samples.length; i++) {
            for (int j = 0; j < this.neurons.length; j++) {
                results[i][j] = this.neurons[j].getOutput(samples[i]);
            }
            results[i][this.neurons.length] = samples[i][samples[0].length - 1];
        }
        return results;
    }
    
    /**
     * Изменение архитектуры скрытого слоя.
     * Удаляет лишние нейроны из скрытого слоя и лишние весовые 
     * коэффициенты из следующего за данным слоем нейрона.
     * @param nextneuron нейрон после скрытого слоя
     */
    public void reorganization(Neuron nextneuron) {
        int counter = 0;
        int[] result = nextneuron.getResult();
        for (int i = 0; i < result.length - 1; i++) {
            if (result[i] != 0) {
                counter++;
            }
        }
        Neuron[] temp = new Neuron[counter];
        double[] weights = new double[counter];
        counter = 0;
        for (int i = 0; i < result.length - 1; i++) {
            if (result[i] != 0) {
                weights[counter] = nextneuron.getWeights()[i];
                temp[counter] = this.neurons[i];
                counter++;
            }
        }
        nextneuron.changeWeights(weights);
        this.neurons = temp;
    }
    
}

É assim que a grelha de três camadas é implementada:

package neuronet;

import java.util.*;

/**
 * Трехслойная нейронная сеть с одним выходом
 * @author Yury V. Reshetov
 */
public class NN {
    
    private Random rand = null;
    private HiddenLayer hiddenlayer = null;
    private Neuron tailneuron = null;
    
    /**
     * Конструктор нейронной сети
     * @param inputs
     */
    public NN() {
    }
    
    /**
     * Результат нейронной сети
     * @param sample значения входов
     * @return результат
     */
    public double getOutput(double[] sample) {
        double[] sample1 = this.hiddenlayer.getOutputs(sample);
        return this.tailneuron.getOutput(sample1);
    }
    
    /**
     * Обучение нейронной сети
     * @param samples обучающая выборка
     */
    public void learning(double[][] samples) {
        this.rand = new Random();
        this.hiddenlayer = new HiddenLayer(samples[0].length - 1, this.rand);
        double[][] samples1 = this.hiddenlayer.getOutputs(samples);
        this.tailneuron = new Neuron(samples1[0].length - 1, this.rand);
        this.tailneuron.learning(samples1);
        this.hiddenlayer.reorganization(tailneuron);
    }
    
}
 
até mesmo o algoritmo de grid está pronto, tudo o que resta é moldá-lo em arquivos mqh
 

Escrever uma rede não é um problema

A questão principal é como e sob que molho integrá-lo no terminal

 
Vamos manter as coisas simples ou vamos ter muito flub, sugiro que prevejamos o próximo bar.
 
companheiro:
Não nos vamos complicar muito ou vai haver muito flub, proponho-me prever apenas o próximo bar.

Dito isto, risca-me))))

 
O código que Reshetov sugeriu está mais próximo da teoria para a prática, mas ainda não entendo porque pesos aleatórios são necessários quando podem ser determinados empiricamente.
 
yu-sha:

Não, bem, se é assim que a questão é colocada, então não me mencione))))

Geração nekst tempestades neroyproekt :) os mesmos erros, o caranguejo e o lúcio.

A prática mostra que projetos Open Source são desenvolvidos se e somente se houver uma implementação inicial (núcleo) e no Open Source o polimento (adicionando todo tipo de bugigangas e facilidade de uso) é feito.

 

Aqueles que sabem "fazer" já o fizeram.Para eles próprios, naturalmente.

Renat2013.05.04 14:45

Você quer participar diretamente?

Nós vamos colocar o financiamento e a gestão geral. Vamos iniciar o projeto comum noMQL5 Storage e podemos começar.

Há dois pré-requisitos que devemos cumprir:

- financiamento

- gestão comum

Há outra vantagem importante: o iniciador do projeto é o "velho" gerente de MetaQuotes.

Assim, as chances deste empreendimento desmoronar antes mesmo de ter começado são mínimas.

P.S.

Que seja um Código Aberto - qual é o problema?