Algoritma backpropagation


19

Saya mendapat sedikit kebingungan pada algoritma backpropagation yang digunakan dalam multilayer perceptron (MLP).

Kesalahan disesuaikan dengan fungsi biaya. Dalam backpropagation, kami mencoba untuk menyesuaikan berat lapisan yang tersembunyi. Kesalahan keluaran yang bisa saya mengerti, yaitu, e = d - y[Tanpa subskrip].

Pertanyaannya adalah:

  1. Bagaimana cara mendapatkan kesalahan dari lapisan tersembunyi? Bagaimana cara menghitungnya?
  2. Jika saya melakukan backpropagate, haruskah saya menggunakannya sebagai fungsi biaya dari filter adaptif atau haruskah saya menggunakan pointer (dalam C / C ++) pengertian pemrograman, untuk memperbarui bobot?

NN adalah teknologi yang agak ketinggalan zaman, jadi saya khawatir Anda tidak akan mendapatkan jawaban karena tidak ada orang di sini yang menggunakannya ...

@ MBb: Saya tidak meragukan kata-kata Anda, tetapi bagaimana Anda sampai pada kesimpulan bahwa NN adalah "teknologi usang"?
steffen

1
@steffen Dengan observasi; Maksud saya jelas bahwa tidak ada seorang pun yang signifikan dari komunitas NN yang akan keluar dan berkata, "Hai teman-teman, mari kita lepaskan pekerjaan seumur hidup kita dan bermain dengan sesuatu yang lebih baik!", Tetapi kita memiliki alat yang mencapai akurasi yang sama atau lebih baik tanpa semua ambivalensi ini dan tidak pernah pelatihan -akhir. Dan orang-orang menjatuhkan NN mendukung mereka.

5
Ini memiliki beberapa kebenaran ketika Anda mengatakannya, @ MBQ, tetapi tidak lagi.
jerad

1
@ Jerad Cukup mudah - Saya belum melihat perbandingan yang adil dengan metode lain (Kaggle bukan perbandingan yang adil karena kurangnya interval kepercayaan untuk akurasi - terutama ketika hasil dari semua tim dengan skor tinggi sangat dekat seperti dalam kontes Merck), tidak ada analisis kekokohan optimasi parameter - yang jauh lebih buruk.

Jawaban:


27

Saya pikir saya akan menjawab posting mandiri di sini untuk siapa saja yang tertarik. Ini akan menggunakan notasi yang dijelaskan di sini .

pengantar

Gagasan di balik backpropagation adalah untuk memiliki satu set "contoh pelatihan" yang kami gunakan untuk melatih jaringan kami. Masing-masing memiliki jawaban yang diketahui, sehingga kita dapat menyambungkannya ke jaringan saraf dan menemukan seberapa banyak kesalahannya.

Misalnya, dengan pengenalan tulisan tangan, Anda akan memiliki banyak karakter tulisan tangan di samping apa sebenarnya mereka. Kemudian jaringan saraf dapat dilatih melalui backpropagation untuk "belajar" bagaimana mengenali masing-masing simbol, jadi ketika itu kemudian disajikan dengan karakter tulisan tangan yang tidak dikenal itu dapat mengidentifikasi apa itu dengan benar.

Secara khusus, kami memasukkan beberapa sampel pelatihan ke jaringan saraf, melihat seberapa baik itu, kemudian "menetes ke belakang" untuk menemukan seberapa banyak kita dapat mengubah bobot dan bias masing-masing node untuk mendapatkan hasil yang lebih baik, dan kemudian menyesuaikannya. Ketika kami terus melakukan ini, jaringan "belajar".

Ada juga langkah-langkah lain yang mungkin termasuk dalam proses pelatihan (misalnya, putus sekolah), tetapi saya akan lebih fokus pada backpropagation karena memang itulah pertanyaannya.

Derivatif parsial

Turunan parsial adalah turunan darifsehubungan dengan beberapa variabelx.fxfx

Misalnya, jika , f(x,y)=x2+y2, karenay2hanyalah sebuah konstanta sehubungan denganx. Demikian juga,ffx=2xy2x, karenax2hanyalah sebuah konstanta sehubungan denganfy=2yx2 .y

Gradien suatu fungsi, yang ditunjuk f , adalah fungsi yang mengandung turunan parsial untuk setiap variabel dalam f. Secara khusus:

,

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

di mana adalah vektor satuan yang menunjuk ke arah variabel vei .v1

Sekarang, setelah kami telah dihitung dengan untuk beberapa fungsi f , jika kita berada di posisi ( v 1 , v 2 , . . . , V n ) , kita bisa "slide down" f dengan pergi ke arah - f ( v 1 , v 2 , . . . , v n ) .ff(v1,v2,...,vn)ff(v1,v2,...,vn)

Dengan contoh , vektor satuan adalah e 1 = ( 1 , 0 ) dan e 2 = ( 0 , 1 ) , karena v 1 = x dan v 2 = y , dan vektor-vektor itu menunjuk ke arah sumbu x dan y . Dengan demikian, f ( x , yf(x,y)=x2+y2e1=(1,0)e2=(0,1)v1=xv2=yxy .f(x,y)=2x(1,0)+2y(0,1)

Sekarang, untuk "geser ke bawah" fungsi kita , katakanlah kita berada pada suatu titik ( - 2 , 4 ) . Maka kita perlu bergerak ke arah - 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)

Besarnya vektor ini akan memberi kita seberapa curam bukit itu (nilai yang lebih tinggi berarti bukit lebih curam). Dalam hal ini, kami punya42+(8)28.944 .

Gradient Descent

Produk Hadamard

Produk Hadamard dari dua matriks A,BRn×m , sama seperti penambahan matriks, kecuali alih-alih menambahkan elemen matriks, kami mengalikannya dengan elemen.

Secara formal, sedangkan penambahan matriks adalah , di mana C R n × mA+B=CCRn×m sedemikian rupa

Cji=Aji+Bji
,

Produk Hadamard , di mana C R n × m sedemikian rupaAB=CCRn×m

Cji=AjiBji

Komputasi gradien

(sebagian besar bagian ini dari buku Neilsen ).

Kami memiliki satu set sampel pelatihan, , dimana S r adalah contoh pelatihan input tunggal, dan E r adalah nilai output yang diharapkan dari sampel pelatihan. Kami juga memiliki jaringan kami saraf, terdiri dari bias W , dan bobot B . r digunakan untuk mencegah kebingungan dari i , j , dan k(S,E)SrErWBrijk digunakan dalam definisi jaringan feedforward.

Selanjutnya, kita mendefinisikan fungsi biaya, C(W,B,Sr,Er) yang mengambil jaringan saraf kita dan contoh pelatihan tunggal, dan menampilkan seberapa baik .

Biasanya yang digunakan adalah biaya kuadratik, yang didefinisikan oleh

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

di mana adalah output ke jaringan saraf kami, mengingat masukan sampel S raLSr

Kemudian kami ingin mencari danCCwjiCbji untuk setiap node dalam jaringan saraf umpan maju kami.

Kita bisa menyebutnya gradien pada setiap neuron karena kita menganggap S r dan E r sebagai konstanta, karena kita tidak bisa mengubah mereka ketika kita mencoba untuk belajar. Dan ini masuk akal - kami ingin bergerak ke arah relatif ke W dan B yang meminimalkan biaya, dan bergerak ke arah negatif gradien sehubungan dengan W dan B akan melakukan ini.CSrErWBWB

Untuk melakukan ini, kita mendefinisikan sebagai kesalahan neuronjdi lapisaniδji=Czjiji .

Kita mulai dengan menghitung dengan cara menghubungkan S raLSr ke jaringan saraf kita.

Kemudian kami menghitung kesalahan dari layer output kami, , viaδL

.

δjL=CajLσ(zjL)

Yang juga bisa ditulis sebagai

δ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)

Sekarang kita memiliki kesalahan dari setiap node di jaringan saraf kita, menghitung gradien sehubungan dengan bobot dan bias kita mudah:

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.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.