#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
Вообщем, не долго думая я решил перенести мои предположения в код. На мое удивление все начало работать замечательно, я проверил нейронную сеть на нескольких простых задача и результаты не стали себя долго ждать! Спасибо всем, кто пытался помочь!
Комментариев нет:
Отправить комментарий