Algoritmo di backpropagation


19

Ho avuto una leggera confusione sull'algoritmo di backpropagation utilizzato nel perceptron multistrato (MLP).

L'errore viene corretto dalla funzione di costo. In backpropagation, stiamo cercando di regolare il peso degli strati nascosti. L'errore di output che posso capire, vale a dire, e = d - y[senza gli abbonati].

Le domande sono:

  1. Come si ottiene l'errore del livello nascosto? Come si calcola?
  2. Se lo ripropongo, dovrei usarlo come una funzione di costo di un filtro adattivo o dovrei usare un senso di programmazione puntatore (in C / C ++), per aggiornare il peso?

NN è piuttosto una tecnologia obsoleta, quindi temo che non otterrai una risposta perché nessuno qui li sta usando ...

@mbq: non dubito delle tue parole, ma come giungi alla conclusione che NN è "tecnologia obsoleta"?
Steffen,

1
@steffen Per osservazione; Voglio dire, è ovvio che nessuno della comunità della NN uscirà e dirà "Ehi ragazzi, lasciamo il lavoro e giochiamo con qualcosa di meglio!", Ma abbiamo strumenti che raggiungono la stessa o migliore precisione senza tutta questa ambivalenza e mai formazione permanente. E le persone rilasciano NN in loro favore.

5
Questo aveva un po 'di verità quando l'hai detto, @mbq, ma non più.
Jerad

1
@jerad Abbastanza facile: semplicemente non ho ancora visto un confronto equo con altri metodi (Kaggle non è un confronto equo a causa della mancanza di intervalli di confidenza per le accuratezze, specialmente quando i risultati di tutti i team con punteggi più alti sono così vicini come nel concorso Merck), né alcuna analisi della solidità dell'ottimizzazione dei parametri, il che è molto peggio.

Risposte:


27

Ho pensato di rispondere a un post indipendente qui per chiunque fosse interessato. Questo utilizzerà la notazione descritta qui .

introduzione

L'idea alla base della backpropagation è quella di avere una serie di "esempi di formazione" che utilizziamo per formare la nostra rete. Ognuno di questi ha una risposta nota, quindi possiamo collegarli alla rete neurale e scoprire quanto era sbagliato.

Ad esempio, con il riconoscimento della grafia, avresti molti personaggi scritti a mano insieme a quello che erano in realtà. Quindi la rete neurale può essere addestrata tramite backpropagation per "imparare" a riconoscere ogni simbolo, quindi quando in seguito viene presentato con un carattere scritto a mano sconosciuto può identificare ciò che è correttamente.

In particolare, inseriamo un campione di allenamento nella rete neurale, vediamo quanto è stato buono, quindi "goccioliamo all'indietro" per scoprire quanto possiamo cambiare i pesi e la distorsione di ciascun nodo per ottenere un risultato migliore, e quindi regolarli di conseguenza. Mentre continuiamo a farlo, la rete "impara".

Ci sono anche altri passaggi che possono essere inclusi nel processo di formazione (ad esempio, abbandono), ma mi concentrerò principalmente sulla backpropagazione poiché è questa la questione.

Derivati ​​parziali

Un derivato parziale fx è una derivata difrispetto ad alcune variabilix.

Ad esempio, se f(x,y)=x2+y2 , fx=2x, perchéy2è semplicemente una costante rispetto ax. Allo stesso modo,fy=2y, perchéx2è semplicemente una costante rispetto ay .

Un gradiente di una funzione, designato f , è una funzione che contiene la derivata parziale per ogni variabile in f. In particolare:

,

f(v1,v2,...,vn)=fv1e1++fvnen

dove è un vettore unitario che punta nella direzione della variabile v 1 .eiv1

Ora, una volta che abbiamo calcolato il per qualche funzione f , se siamo nella posizione ( v 1 , v 2 , . . . , V n ) , possiamo "slide down" f andando in direzione - f ( v 1 , v 2 , . . . , v n ) .ff(v1,v2,...,vn)ff(v1,v2,...,vn)

Con il nostro esempio di , i vettori di unità sono e 1 = ( 1 , 0 ) ed e 2 = ( 0 , 1 ) , perché v 1 = x and v 2 = y , e quei vettori puntano nella direzione della x ed y assi. Pertanto, f ( x , yf(x,y)=x2+y2e1=(1,0)e2=(0,1)v1=xv2=yxy.f(x,y)=2x(1,0)+2y(0,1)

Ora, per "far scorrere verso il basso" la nostra funzione , diciamo che siamo in un punto ( - 2 , 4 ) . Quindi avremmo bisogno di spostarci in direzione - f ( - 2 , - 4 ) = - ( 2 - 2 ( 1 , 0 ) + 2 4 ( 0 , 1 ) ) = - ( ( - - 4 , ( 0 ,f(-2,4) .f(2,4)=(22(1,0)+24(0,1))=((4,0)+(0,8))=(4,8)

La grandezza di questo vettore ci darà quanto è ripida la collina (valori più alti indicano che la collina è più ripida). In questo caso, abbiamo .42+(8)28.944

Discesa a gradiente

Prodotto Hadamard

Il prodotto Hadamard di due matrici , è proprio come l'aggiunta di matrici, tranne che invece di aggiungere le matrici elemento-saggio, le moltiplichiamo come elemento.A,BRn×m

Formalmente, mentre l'aggiunta della matrice è , dove C R n × m tale cheA+B=CCRn×m

,

Cji=Aji+Bji

Il prodotto Hadamard , dove C R n × m tale cheAB=CCRn×m

Cji=AjiBji

Calcolo dei gradienti

(la maggior parte di questa sezione è tratta dal libro di Neilsen ).

Abbiamo una serie di campioni di training, , in cui S r è un singolo campione di training di input ed E r è il valore di output atteso di quel campione di training. Abbiamo anche la nostra rete neurale, composta da pregiudizi W , e pesi B . r è usato per evitare confusione da i , j e k usato nella definizione di una rete feedforward.(S,E)SrErWBrijk

Successivamente, definiamo una funzione di costo, C(W,B,Sr,Er) che include la nostra rete neurale e un singolo esempio di addestramento e produce quanto è stato buono.

Normalmente ciò che viene utilizzato è il costo quadratico, che è definito da

C(W,B,Sr,Er)=0.5j(ajLEjr)2

dove è l'output alla nostra rete neurale, dato il campione di input S raLSr

Quindi vogliamo trovare eCCwji per ciascun nodo della nostra rete neurale feedforward.Cbji

Possiamo chiamare questo il gradiente di in ciascun neurone perché consideriamo S r ed E r come costanti, poiché non possiamo cambiarle quando stiamo cercando di imparare. E questo ha senso: vogliamo muoverci in una direzione relativa a W e B che minimizzi i costi e lo faremo nella direzione negativa del gradiente rispetto a W e B.CSrErWBWB

Per fare ciò, definiamo come errore del neuronejnel livelloi.δji=Czjiji

aLSr

δL

δjL=CajLσ(zjL)
.

Which can also be written as

δL=aCσ(zL)
.

Next, we find the error δi in terms of the error in the next layer δi+1, via

δi=((Wi+1)Tδi+1)σ(zi)

Now that we have the error of each node in our neural network, computing the gradient with respect to our weights and biases is easy:

Cwjki=δjiaki1=δi(ai1)T

Cbji=δji

Note that the equation for the error of the output layer is the only equation that's dependent on the cost function, so, regardless of the cost function, the last three equations are the same.

As an example, with quadratic cost, we get

δL=(aLEr)σ(zL)

for the error of the output layer. and then this equation can be plugged into the second equation to get the error of the L1th layer:

δL1=((WL)TδL)σ(zL1)
=((WL)T((aLEr)σ(zL)))σ(zL1)

which we can repeat this process to find the error of any layer with respect to C, which then allows us to compute the gradient of any node's weights and bias with respect to C.

I could write up an explanation and proof of these equations if desired, though one can also find proofs of them here. I'd encourage anyone that is reading this to prove these themselves though, beginning with the definition δji=Czji and applying the chain rule liberally.

For some more examples, I made a list of some cost functions alongside their gradients here.

Gradient Descent

Now that we have these gradients, we need to use them learn. In the previous section, we found how to move to "slide down" the curve with respect to some point. In this case, because it's a gradient of some node with respect to weights and a bias of that node, our "coordinate" is the current weights and bias of that node. Since we've already found the gradients with respect to those coordinates, those values are already how much we need to change.

We don't want to slide down the slope at a very fast speed, otherwise we risk sliding past the minimum. To prevent this, we want some "step size" η.

Then, find the how much we should modify each weight and bias by, because we have already computed the gradient with respect to the current we have

Δwjki=ηCwjki

Δbji=ηCbji

Thus, our new weights and biases are

wjki=wjki+Δwjki
bji=bji+Δbji

Using this process on a neural network with only an input layer and an output layer is called the Delta Rule.

Stochastic Gradient Descent

Now that we know how to perform backpropagation for a single sample, we need some way of using this process to "learn" our entire training set.

One option is simply performing backpropagation for each sample in our training data, one at a time. This is pretty inefficient though.

A better approach is Stochastic Gradient Descent. Instead of performing backpropagation for each sample, we pick a small random sample (called a batch) of our training set, then perform backpropagation for each sample in that batch. The hope is that by doing this, we capture the "intent" of the data set, without having to compute the gradient of every sample.

For example, if we had 1000 samples, we could pick a batch of size 50, then run backpropagation for each sample in this batch. The hope is that we were given a large enough training set that it represents the distribution of the actual data we are trying to learn well enough that picking a small random sample is sufficient to capture this information.

However, doing backpropagation for each training example in our mini-batch isn't ideal, because we can end up "wiggling around" where training samples modify weights and biases in such a way that they cancel each other out and prevent them from getting to the minimum we are trying to get to.

To prevent this, we want to go to the "average minimum," because the hope is that, on average, the samples' gradients are pointing down the slope. So, after choosing our batch randomly, we create a mini-batch which is a small random sample of our batch. Then, given a mini-batch with n training samples, and only update the weights and biases after averaging the gradients of each sample in the mini-batch.

Formally, we do

Δwjki=1nrΔwjkri

and

Δbji=1nrΔbjri

where Δwjkri is the computed change in weight for sample r, and Δbjri is the computed change in bias for sample r.

Then, like before, we can update the weights and biases via:

wjki=wjki+Δwjki
bji=bji+Δbji

This gives us some flexibility in how we want to perform gradient descent. If we have a function we are trying to learn with lots of local minima, this "wiggling around" behavior is actually desirable, because it means that we're much less likely to get "stuck" in one local minima, and more likely to "jump out" of one local minima and hopefully fall in another that is closer to the global minima. Thus we want small mini-batches.

On the other hand, if we know that there are very few local minima, and generally gradient descent goes towards the global minima, we want larger mini-batches, because this "wiggling around" behavior will prevent us from going down the slope as fast as we would like. See here.

One option is to pick the largest mini-batch possible, considering the entire batch as one mini-batch. This is called Batch Gradient Descent, since we are simply averaging the gradients of the batch. This is almost never used in practice, however, because it is very inefficient.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.