-1

Я нашел пример онлайн, который содержит метод, который возвращает распространение ошибки и корректирует вес. Мне было интересно, как это работает и какой алгоритм обновления веса используется. Может быть, это градиентный спуск?Обратный алгоритм распространения

/** 
    * all output propagate back 
    * 
    * @param expectedOutput 
    *   first calculate the partial derivative of the error with 
    *   respect to each of the weight leading into the output neurons 
    *   bias is also updated here 
    */ 
    public void applyBackpropagation(double expectedOutput[]) { 

    // error check, normalize value ]0;1[ 
    for (int i = 0; i < expectedOutput.length; i++) { 
     double d = expectedOutput[i]; 
     if (d < 0 || d > 1) { 
      if (d < 0) 
       expectedOutput[i] = 0 + epsilon; 
      else 
       expectedOutput[i] = 1 - epsilon; 
     } 
    } 

    int i = 0; 
    for (Neuron n : outputLayer) { 
     ArrayList<Connection> connections = n.getAllInConnections(); 
     for (Connection con : connections) { 
      double ak = n.getOutput(); 
      double ai = con.leftNeuron.getOutput(); 
      double desiredOutput = expectedOutput[i]; 

      double partialDerivative = -ak * (1 - ak) * ai 
        * (desiredOutput - ak); 
      double deltaWeight = -learningRate * partialDerivative; 
      double newWeight = con.getWeight() + deltaWeight; 
      con.setDeltaWeight(deltaWeight); 
      con.setWeight(newWeight + momentum * con.getPrevDeltaWeight()); 
     } 
     i++; 
    } 

    // update weights for the hidden layer 
    for (Neuron n : hiddenLayer) { 
     ArrayList<Connection> connections = n.getAllInConnections(); 
     for (Connection con : connections) { 
      double aj = n.getOutput(); 
      double ai = con.leftNeuron.getOutput(); 
      double sumKoutputs = 0; 
      int j = 0; 
      for (Neuron out_neu : outputLayer) { 
       double wjk = out_neu.getConnection(n.id).getWeight(); 
       double desiredOutput = (double) expectedOutput[j]; 
       double ak = out_neu.getOutput(); 
       j++; 
       sumKoutputs = sumKoutputs 
         + (-(desiredOutput - ak) * ak * (1 - ak) * wjk); 
      } 

      double partialDerivative = aj * (1 - aj) * ai * sumKoutputs; 
      double deltaWeight = -learningRate * partialDerivative; 
      double newWeight = con.getWeight() + deltaWeight; 
      con.setDeltaWeight(deltaWeight); 
      con.setWeight(newWeight + momentum * con.getPrevDeltaWeight()); 
     } 
    } 
} 
+1

Насколько я могу судить, это MLP с одним скрытым слоем. И, не имея возможности следовать этому коду, я думаю, что backpropagation приведет к градиентному спуску. В чем ваш вопрос? Если вы можете использовать этот код или что такое градиентный спуск? – Tim

ответ

1

Это некрасиво ищет статью, кажется, описывающее точно такой же вариант алгоритма: http://www.speech.sri.com/people/anand/771/html/node37.html. У меня есть те же формулы в моих университетских документах, но с сожалением: а) они недоступны в Интернете; б) они на языке, который вы не поймете.

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

2

Мне кажется, что это решение использует stochastic gradient descent. Основное различие между ним и обычным градиентом прилично, так это то, что градиент аппроксимируется для каждого примера, а не вычисляет его для всех примеров, а затем выбирает наилучшее направление. Это обычный подход к реализации backpropagtion и даже имеет некоторые преимущества для градиента приличный (можно избежать некоторых локальных минимумов). Я считаю, что статья также преувеличивает, какова идея, и есть также множество других статей, которые объясняют основную идею обратного распространения.

+0

Если это SGD, то где петля над образцами обучения? На выходных единицах есть цикл, который увеличивает «i», как если бы количество единиц вывода было равно количеству обучающих выборок, что кажется абсолютно абсурдным. –

+1

Я думаю, что должен быть цикл, который вызывает эту функцию, и на самом деле функция адаптирует веса только к одному образцу. Это можно устранить из-за того, что единственным входом функции являются ожидаемые значения всех выходных персептронов (только одно значение для нейрона). –

+0

Ах, верно! Я ожидал, что 'expectedOutput' будет иметь длину' n_samples'. –

Смежные вопросы