Ready to get involved - with ready-made solutions, experience, and even coding.
A lot of people have been ready for a long time. But MetaQuotes can't move from words to deeds, can they?
yu-sha:
We need a closed thread where we can adequately discuss architecture, perspectives, and directions
How much more discussion can we have? 86 pages of this thread alone.
The fact that all the flooders in this thread will move to a private branch, of course, the rest of the forum visitors will be better, because read dozens of pages of flooding will not be necessary.
In reality everything is much easier, because who needs and who knows how to do it has long designed a grid. The rest of us read 86 pages of forum flooding.
The point is that a few visitors to this forum also have some experience and developments on the subject.
For example, I have a self-made OOP project in Java. I haven't converted it to mql5, because there was no need.
I made it for myself with my own learning algorithm. The main advantage is that you don't know in advance how many neurons are needed in the hidden layer. The grid can remove extra neurons from the hidden layer, and accordingly extra weighting coefficients from the output neuron.
This is what an artificial neuron looks like:
package neuronet;
import java.util.*;
/**
* Искусственный нейрон
* @author Yury V. Reshetov
*/publicclass Neuron {
/**
* Весовые коэффициенты
*/privatedouble[] weights = null;
/**
* Пороговое значение
*/privatedouble threshold = 0 d;
privateint[] 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 = newdouble[inputs];
for (int i = 0; i < inputs; i++) {
this.weights[i] = rand.nextDouble() * 2 d - 1 d;
}
}
/**
* Вычисление
* @param inputs входные значения
* @return результат на выходе нейрона
*/publicdouble getOutput(double[] inputs) {
double sum = this.threshold;
for (int i = 0; i < this.weights.length; i++) {
sum = sum + inputs[i] * this.weights[i];
}
returnthis.getSigmoidValue(sum);
}
/**
* Возвращает значения весовых коэффициентов
* @return весовые коэффициенты
*/publicdouble[] getWeights() {
returnthis.weights;
}
/**
* Возвращает пороговое значение
* @return пороговое значение
*/publicdouble getThreshold() {
returnthis.threshold;
}
/**
* Возвращает результаты
* @return результаты
*/publicint[] getResult() {
returnthis.result;
}
publicvoid changeWeights(double[] w) {
this.weights = w;
}
/**
* Обучение нейрона
* @param samples обучающая выборка. Последний элемент столбца - выходное значение
*/publicvoid 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 = newdouble[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 = newdouble[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 значение сигмоидальной функции
*/privatedouble getSigmoidValue(double x) {
return Math.atan(x);
}
/**
* Вычисляет обратное значение сигмоидальной функции
* @return обратное значение сигмоидальной функции
*/privatedouble getArcSigmoidValue(double x) {
return Math.tan(x);
}
}
This is what the hidden layer looks like:
package neuronet;
import java.util.*;
/**
* Скрытый слой
* @author Yury V. Reshetov
*/publicclass 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() {
returnthis.neurons;
}
/**
* Возвращает результаты входного слоя
* @param inputs массив входных значений
* @return массив результатов
*/publicdouble[] getOutputs(double[] inputs) {
double[] results = newdouble[this.neurons.length];
for (int i = 0; i < this.neurons.length; i++) {
results[i] = this.neurons[i].getOutput(inputs);
}
return results;
}
/**
* Получает обучающую выборку для следующего нейрона из входной обучающей выборки
* @param samples обучающая выборка
* @return обучающая выборка для следующего нейрона
*/publicdouble[][] getOutputs(double[][] samples) {
double[][] results = newdouble[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 нейрон после скрытого слоя
*/publicvoid 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 = newdouble[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;
}
}
This is how the three-layer grid is implemented:
package neuronet;
import java.util.*;
/**
* Трехслойная нейронная сеть с одним выходом
* @author Yury V. Reshetov
*/publicclass NN {
private Random rand = null;
private HiddenLayer hiddenlayer = null;
private Neuron tailneuron = null;
/**
* Конструктор нейронной сети
* @param inputs
*/public NN() {
}
/**
* Результат нейронной сети
* @param sample значения входов
* @return результат
*/publicdouble getOutput(double[] sample) {
double[] sample1 = this.hiddenlayer.getOutputs(sample);
returnthis.tailneuron.getOutput(sample1);
}
/**
* Обучение нейронной сети
* @param samples обучающая выборка
*/publicvoid 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);
}
}
The code that Reshetov suggested is closer from theory to practice, but I still do not understand why weights are random, if they can be determined empirically
No, well, if that's the way the question is posed, then don't ask me)))
Generation next storms neroyproekt :) the same mistakes, the crab and the pike.
Practice shows that Open Source projects are developed if and only if there is an initial realization (the core) and in Open Source the polishing (adding all sorts of trinkets and user friendliness) is done.
Urain says it right: we need to make a kernel, that's where we start. There have been a lot of templates written here, we need specifics. And we need to start with the elementary: making a neuron. Enough theories and mathematical explanations. We need a neuron in MQL5!
Ready to get involved - with ready-made solutions, experience, and even coding.
We need a closed thread where we can adequately discuss architecture, perspectives, and directions
Ready to get involved - with ready-made solutions, experience, and even coding.
yu-sha:
We need a closed thread where we can adequately discuss architecture, perspectives, and directions
How much more discussion can we have? 86 pages of this thread alone.
The fact that all the flooders in this thread will move to a private branch, of course, the rest of the forum visitors will be better, because read dozens of pages of flooding will not be necessary.
In reality everything is much easier, because who needs and who knows how to do it has long designed a grid. The rest of us read 86 pages of forum flooding.
The point is that a few visitors to this forum also have some experience and developments on the subject.
For example, I have a self-made OOP project in Java. I haven't converted it to mql5, because there was no need.
I made it for myself with my own learning algorithm. The main advantage is that you don't know in advance how many neurons are needed in the hidden layer. The grid can remove extra neurons from the hidden layer, and accordingly extra weighting coefficients from the output neuron.This is what an artificial neuron looks like:
This is what the hidden layer looks like:
This is how the three-layer grid is implemented:
Writing a network is not a problem
The main question is how and under what sauce to integrate it into the terminal
Let's not complicate things, or there will be a lot of flub, I propose to predict just the next bar
If you put it that way, cross me out ))))
No, well, if that's the way the question is posed, then don't ask me)))
Generation next storms neroyproekt :) the same mistakes, the crab and the pike.
Practice shows that Open Source projects are developed if and only if there is an initial realization (the core) and in Open Source the polishing (adding all sorts of trinkets and user friendliness) is done.
Those who know how to "do" have already done so.For themselves, of course.
Do you want to directly participate?
We will take care of the funding and general management. We will start the common project inMQL5 Storage and we can start.
There are two prerequisites we must meet:
- funding
- general management
There is another important advantage: the initiator of this project is the "old" MetaQuotes manager.
Therefore, the chances that this project will fall apart before it has even started are minimal.
P.S.
Let it be an Open Source - what's the problem?