2016-12-09 7 views
2

Я создал простую нейронную сеть с 3 слоями в соответствии с этим питона, например: Link (PS: Вы должны прокрутить вниз, пока вы не достигнете Часть 2)обратного распространения не работает: Neural Network Java

Это моя реализация Java кода:

private void trainNet() 
{ 
    // INPUT is a 4*3 matrix 
    // SYNAPSES is a 3*4 matrix 
    // SYNAPSES2 is a 4*1 matrix 
    // 4*3 matrix DOT 3*4 matrix => 4*4 matrix: unrefined test results 
    double[][] layer1 = sigmoid(dot(inputs, synapses), false); 

    // 4*4 matrix DOT 4*1 matrix => 4*1 matrix: 4 final test results 
    double[][] layer2 = sigmoid(dot(layer1, synapses2), false); 

    // 4*1 matrix - 4*1 matrix => 4*1 matrix: error of 4 test results 
    double[][] layer2Error = subtract(outputs, layer2); 

    // 4*1 matrix DOT 4*1 matrix => 4*1 matrix: percentage of change of 4 test results 
    double[][] layer2Delta = dot(layer2Error, sigmoid(layer2, true)); 

    // 4*1 matrix DOT 3*1 matrix => 4*1 matrix 
    double[][] layer1Error = dot(layer2Delta, synapses2); 

    // 4*1 matrix DOT 4*4 matrix => 4*4 matrix: percentage of change of 4 test results 
    double[][] layer1Delta = dot(layer1Error, sigmoid(layer1, true)); 

    double[][] transposedInputs = transpose(inputs); 
    double[][] transposedLayer1 = transpose(layer1); 

    // 4*4 matrix DOT 4*1 matrix => 4*1 matrix: the updated weights 
    // Update the weights 
    synapses2 = sum(synapses2, dot(transposedLayer1, layer2Delta)); 

    // 3*4 matrix DOT 4*4 matrix => 3*4 matrix: the updated weights 
    // Update the weights 
    synapses = sum(synapses, dot(transposedInputs, layer1Delta)); 

    // Test each value of two 4*1 matrices with each other 
    testValue(layer2, outputs); 
} 

точка, сумма, вычитать и транспонировать функции, которые я создал сам, и я уверен, что они делают свою работу отлично.

Первая партия входов дает мне ошибку около 0,4, что хорошо, потому что весы имеют случайное значение. Во втором прогоне размер ошибки меньше, но только на очень тонкое количество (0,001)

После 500 000 партий (так всего 2 000 000 тестов) сеть по-прежнему не выдала правильного значения! Поэтому я попытался использовать еще большее количество партий. Используя 1,000,000 пакетов (всего 4 000 000 тестов), сеть генерирует колоссальные 16,900 правильных результатов.

Не могли бы вы рассказать мне, что происходит?

Это были использованы веса:

Первый слой:

  • 2,038829298171684 2,816232761170282 1,6740269469812146 1,634422766238497
  • 1,5890997594993828 1,7909325329112222 2,101840236824494 1,063579126586681
  • 3,761238407071311 3,757148454039234 3,7557450538398176 3,6715972104291605

Второй слой:

  • -0,019603811941904248
  • +218,38253323323553
  • 53.70133275445734
  • -272,83589796861514

    EDIT: Благодаря lsnare за указание мне с использованием библиотеки будет намного легче!

Для тех, кто заинтересован здесь рабочего кода с использованием math.nist.gov/javanumerics библиотеки:

private void trainNet() 
{ 
    // INPUT is a 4*3 matrix 
    // SYNAPSES is a 3*4 matrix 
    // SYNAPSES2 is a 4*1 matrix 
    // 4*3 matrix DOT 3*4 matrix => 4*4 matrix: unrefined test results 
    Matrix hiddenLayer = sigmoid(inputs.times(synapses), false); 

    // 4*4 matrix DOT 4*1 matrix => 4*1 matrix: 4 final test results 
    Matrix outputLayer = sigmoid(hiddenLayer.times(synapses2), false); 

    // 4*1 matrix - 4*1 matrix => 4*1 matrix: error of 4 test results 
    Matrix outputLayerError = outputs.minus(outputLayer); 

    // 4*1 matrix DOT 4*1 matrix => 4*1 matrix: percentage of change of 4 test results 
    Matrix outputLayerDelta = outputLayerError.arrayTimes(sigmoid(outputLayer, true)); 

    // 4*1 matrix DOT 1*4 matrix => 4*4 matrix 
    Matrix hiddenLayerError = outputLayerDelta.times(synapses2.transpose()); 

    // 4*4 matrix DOT 4*4 matrix => 4*4 matrix: percentage of change of 4 test results 
    Matrix hiddenLayerDelta = hiddenLayerError.arrayTimes(sigmoid(hiddenLayer, true)); 

    // 4*4 matrix DOT 4*1 matrix => 4*1 matrix: the updated weights 
    // Update the weights 
    synapses2 = synapses2.plus(hiddenLayer.transpose().times(outputLayerDelta)); 

    // 3*4 matrix DOT 4*4 matrix => 3*4 matrix: the updated weights 
    // Update the weights 
    synapses = synapses.plus(inputs.transpose().times(hiddenLayerDelta)); 

    // Test each value of two 4*1 matrices with each other 
    testValue(outputLayer.getArrayCopy(), outputs.getArrayCopy()); 
} 
+0

Можете ли вы добавить в свои точки, суммы, вычесть, транспонировать и сигмоидные функции только для уточнения? – CraigR8806

ответ

0

В общем, при написании кода, который включает в себя математическое или численное вычисление (например, линейная алгебра), лучше использовать существующие библиотеки, написанные экспертами в этой области, вместо того, чтобы писать свои собственные функции. Стандартные библиотеки будут давать более точные результаты и, скорее всего, более эффективны. Например, в блоге, который вы ссылаетесь, автор использует библиотеку numpy для вычисления точечных продуктов и транспонирования матриц.Для Java, вы можете использовать Java Matrix Package (JAMA), который был разработан NIST: http://math.nist.gov/javanumerics/jama/
Например, транспонировать матрицу:

double[4][3] in = {{0,0,1},{0,1,1},{1,0,1},{1,1,1}}; 
Matrix input = new Matrix(in); 
input = input.transpose(); 

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

+1

Я не могу поблагодарить вас за то, что вы указали мне это! Проблема заключалась в том, что мои методы работали, но они недостаточно проверяли ошибку, поэтому матрицу m * n можно было умножить на матрицу p * q (p ≠ n). – Caske2000

+0

Рад помочь! Я столкнулся с подобными проблемами при попытке реализовать матричные операции самостоятельно :) – lsnare