Страницы

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

воскресенье, 8 декабря 2019 г.

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

#java #нейронные_сети #машинное_обучение


Всем привет.

Визуализация нейронной сети, которую я пытаюсь создать: 


Вот что получилось:

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


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

Основываясь на полученной информации об обучении на одном выходящем нейроне, я предположил,
что формулы для меня будут выглядеть так:


После вычисления ошибок составлю формулы получения нового веса:


Правильно ли я сделал формулы? Так же я не уверен в правильности текущего кода.

Спасибо!
    


Ответы

Ответ 1



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

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

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