Страницы

Поиск по вопросам

пятница, 12 октября 2018 г.

Как обучить нейронную сеть с несколькими выходящими нейронами?

Всем привет.
Визуализация нейронной сети, которую я пытаюсь создать:
Вот что получилось:
private static final int LAYERS = 5;
private static final int INPUT_NEURONS = 3; private static final int HIDDEN_NEURONS = 4; private static final int OUTPUT_NEURONS = 3;
private static final Random random = new Random();
// inputNeurons
private static final float[][] weights1 = new float[INPUT_NEURONS][HIDDEN_NEURONS]; private static final float[] hiddenNeurons1 = new float[HIDDEN_NEURONS];
private static final float[][] weights2 = new float[HIDDEN_NEURONS][HIDDEN_NEURONS]; private static final float[] hiddenNeurons2 = new float[HIDDEN_NEURONS];
private static final float[][] weights3 = new float[HIDDEN_NEURONS][HIDDEN_NEURONS]; private static final float[] hiddenNeurons3 = new float[HIDDEN_NEURONS];
private static final float[][] weights4 = new float[HIDDEN_NEURONS][OUTPUT_NEURONS]; private static final float[] outputNeurons = new float[OUTPUT_NEURONS];
// Каждый bias нейрон равен 1, поэтому мы учитываем только вес при подсчете private static final float[][] biasWeights = new float[LAYERS - 1][];
private static final int MAX_EPOCH = 10000; private static final float LEARNING_RATE = 0.7F;
public static void main(String[] args) { initWeights(weights1); initWeights(weights2); initWeights(weights3); initWeights(weights4); initWeights(biasWeights);
}
private static void initWeights(float[][] weights) { for (int i = 0; i < weights.length; i++) { for (int j = 0; j < weights[i].length; j++) { weights[i][j] = randFloat(0.1F, 0.5F); } } }
public static float randFloat(float min, float max) { return random.nextFloat() * (max - min) + min; }
private static void train(float[][] inputs, float[][] outputs) { for (int i = 0; i < MAX_EPOCH; i++) { for (int j = 0; j < inputs.length; j++) { float[] result = getResult(inputs[j]);
float[] errors = new float[result.length];
for (int k = 0; k < result.length; k++) { float actual = result[k]; float expected = outputs[j][k]; errors[k] = expected - actual; }
} } }
private static float[] getResult(float[] inputNeurons) { if (inputNeurons.length != INPUT_NEURONS) { throw new IllegalArgumentException(); }
calculate(inputNeurons, weights1, hiddenNeurons1, biasWeights[0]); calculate(hiddenNeurons1, weights2, hiddenNeurons2, biasWeights[1]); calculate(hiddenNeurons2, weights3, hiddenNeurons3, biasWeights[2]); calculate(hiddenNeurons3, weights4, outputNeurons, biasWeights[3]);
return outputNeurons.clone(); }
private static void calculate(float[] neurons, float[][] weights, float[] nextNeurons, float[] biasWeights) { for (int i = 0; i < neurons.length; i++) { for (int w = 0; w < weights[i].length; w++) { nextNeurons[w] = nextNeurons[w] + neurons[i] * weights[i][w]; } }
for (int i = 0; i < nextNeurons.length; i++) { nextNeurons[i] = sigmoid(nextNeurons[i] + biasWeights[i]); } }
private static float sigmoid(float value) { return (float) (1 / (1 + Math.exp(-value))); }
Моя проблема заключается в том, что я не могу понять как ее правильно обучить используя метод обратного распространения ошибки. Я не нашел понятной мне информации о том как использовать этот метод на нескольких выходящих нейронах, в большинстве случаев все примеры и объяснения показываются на одном выходящем нейроне.
Основываясь на полученной информации об обучении на одном выходящем нейроне, я предположил, что формулы для меня будут выглядеть так:
После вычисления ошибок составлю формулы получения нового веса:
Правильно ли я сделал формулы? Так же я не уверен в правильности текущего кода.
Спасибо!


Ответ

Вообщем, не долго думая я решил перенести мои предположения в код. На мое удивление все начало работать замечательно, я проверил нейронную сеть на нескольких простых задача и результаты не стали себя долго ждать!
Спасибо всем, кто пытался помочь!

Комментариев нет:

Отправить комментарий