Где и как мне ввести функцию потерь для моих нейронных сетей - PullRequest
0 голосов
/ 26 января 2020

Я делаю свою первую сверточную нейронную сеть и пытаюсь узнать, как работает обратное распространение. Я нашел страницу википедии о обратном распространении: https://en.wikipedia.org/wiki/Backpropagation и ввел формулы в конце «Поиск производной от ошибки» в моем коде, и, похоже, он работает с нейронной сетью с 1 выходной слой, но не более 1 выходного слоя.

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

Я использую База данных MNIST в качестве тренировочный набор, поэтому у меня есть нейронная сеть с 28 * 28 входными нейронами, скрытым слоем 28 нейронов и выходным слоем 10, (0-9).

Это то, что мое обратное распространение код выглядит для каждого нейрона:

if (layer == structure.size() - 1) {
    // This must be the differentiated error / loss function (I think)
    // I think this is the problem. I have tried to replace "loss" with the expected output of each neuron,
    //but it did not work either.
    double derivative = (currentNeuron.out - loss) * currentNeuron.out
            * (1 - currentNeuron.out);
    currentNeuron.derivatives = new double[] { derivative };
} else {
    // Set the derivative for every weigth of a neuron
    double[] derivatives = new double[currentNeuron.weights.length];
    for (int weight = 0; weight < currentNeuron.weights.length; weight++) {
        // Calculate the derivative of one weight
        // Calculate the weighted sum including all derivatives of the neuron in l + 1
        double weightedSumDerivatives = 0;
        for (int nextNeuronDerivative = 0; nextNeuronDerivative < structure.get(layer + 1)
            .get(weight).derivatives.length; nextNeuronDerivative++) {
            weightedSumDerivatives += currentNeuron.weights[nextNeuronDerivative]
                * structure.get(layer + 1).get(weight).derivatives[nextNeuronDerivative];
        }
        double derivative = weightedSumDerivatives * currentNeuron.out * (1 - currentNeuron.out);
        derivatives[weight] = derivative;
    }
    currentNeuron.derivatives = derivatives;
}

Вот так выглядит мой класс нейронов:

public class Neuron {

    protected double[] weights;
    protected double out;
    protected double derivatives[];

    public Neuron(double[] weights) {
        this.weights = weights;
    }

}

Потери рассчитываются следующим образом:

double loss = 0;
for(int i = 0; i < out.length; i++) {
    loss += Math.pow(out[i] - correctAnswer[i], 2);
}
loss /= out.length;

correctAnswer - это массив длиной 10, где каждый элемент равен 0, за исключением правильного ответа 1

Как мне изменить функцию потери?

Заранее спасибо

Редактировать : Как вы можете видеть в моем коде, я не изменяю веса нейронов непосредственно после их вычисления, но я применяю все изменения после того, как все производные вычислены. Если это тоже не так, пожалуйста, скажите мне.

Я даже пытался тренировать нейронную сеть по всему набору (60000 изображений), но он все равно дал ту же тра sh, что и раньше

...