Како повратно размножавање функционише и како можете да користите Питхон за изградњу неуронске мреже

Неуронске мреже могу бити застрашујуће, посебно за људе који су нови у машинском учењу. Међутим, овај водич ће разложити како тачно функционише неуронска мрежа и до краја ћете имати функционалну флексибилну неуронску мрежу. Хајде да почнемо!

Разумевање процеса

Са приближно 100 милијарди неурона, људски мозак обрађује податке брзином од 268 мпх! У суштини, неуронска мрежа је колекција неурона повезаних синапсама .

Ова колекција је организована у три главна слоја: улазни касније, скривени слој и излазни слој.

Можете имати много скривених слојева, што је место где термин дубоко учење улази у игру. У вештачкој неуронској мрежи постоји неколико улаза, који се називају особинама , а који производе најмање један излаз - који се назива ознака .

На горњем цртежу кругови представљају неуроне, док линије представљају синапсе.

Улога синапсе је да узима и умножава улазе и тежине .

Тегове можете сматрати „снагом“ везе између неурона. Пондери првенствено дефинишу излаз неуронске мреже. Међутим, они су врло флексибилни. Након тога се примењује функција активирања за враћање излаза.

Ево кратког прегледа како функционише једноставна повратна неуронска мрежа:

  1. Узми улазе као матрицу (2Д низ бројева)
  2. Помножите улазе са скупом пондера (то се ради множењем матрице, ака узимајући 'тачкасти производ')
  3. Примените функцију активирања
  4. Врати излаз
  5. Грешка се израчунава узимајући разлику између жељеног излаза из модела и предвиђеног излаза. Ово је процес који се назива градијентно спуштање и који можемо користити за промену тежине.
  6. Пондери се затим прилагођавају, према грешци пронађеној у кораку 5.
  7. Да би се тренирао, овај поступак се понавља више од 1000 пута. Што се више података обучава, то ће наши излази бити тачнији.

У својој основи, неуронске мреже су једноставне.

Они само изводе умножавање матрице са улазом и тежином и примењују функцију активирања.

Када се пондери прилагођавају помоћу функције градијента губитка, мрежа се прилагођава променама да би произвела тачније резултате.

Наша неуронска мрежа ће моделирати један скривени слој са три улаза и једним излазом. У мрежи ћемо предвидети резултат нашег испита на основу података о томе колико сати смо учили и колико сати смо спавали дан раније. Резултат је „тест тест“.

Ево наших примера података о ономе на чему ћемо обучавати нашу неуронску мрежу:

Као што сте можда приметили, ?у овом случају представља оно што желимо да наша неуронска мрежа предвиди. У овом случају предвиђамо тест резултат некога ко је учио четири сата и спавао осам сати на основу претходних резултата.

Прослеђивање

Почнимо да кодирамо овог лошег дечка! Отворите нову датотеку питхон. Желећете да увезете numpy, јер ће нам помоћи у одређеним прорачунима.

Прво, хајде да увозимо наше податке у облику нумпи низова помоћу np.array. Такође ћемо желети да нормализујемо наше јединице јер су наши уноси у сатима, али наш резултат је тест резултат од 0-100. Због тога морамо да прилагодимо своје податке дељењем са максималном вредношћу за сваку променљиву.

Даље, дефинишемо питхон classи напишите initфункцију у којој ћемо одредити наше параметре као што су улазни, скривени и излазни слојеви.

Време је за нашу прву калкулацију. Запамтите да наше синапсе изводе тачкасти продукт или матрично умножавање улазних података и тежине. Имајте на уму да се пондери генеришу насумично и између 0 и 1.

Калкулације иза наше мреже

У скупу података, наши улазни подаци, Xпредстављају матрицу 3к2. Наши излазни подаци су yматрица 3к1. Сваки елемент у матрици Xтреба помножити са одговарајућом тежином, а затим додати заједно са свим осталим резултатима за сваки неурон у скривеном слоју. Ево како би први елемент улазних података (2 сата учења и 9 сати спавања) израчунао излаз у мрежи:

Ова слика разлаже оно што наша неуронска мрежа заправо ради да би произвела излаз. Прво се производи случајно генерисаних пондера (.2, .6, .1, .8, .3, .7) на свакој синапси и одговарајући улази сумирају да би стигли као прве вредности скривеног слоја. Ове суме су у мањем фонту јер нису коначне вредности за скривени слој.

Да бисмо добили коначну вредност за скривени слој, морамо да применимо функцију активирања.

Улога функције активирања је увођење нелинеарности. Предност овога је што се излаз мапира из опсега 0 и 1, што олакшава промену пондера у будућности.

Постоји много функција за активирање, за много различитих случајева употребе. У овом примеру ћемо се држати једне од најпопуларнијих - сигмоидне функције.

Сада треба поново да користимо множење матрице, са другим скупом случајних пондера, да бисмо израчунали вредност излазног слоја.

И на крају, да бисмо нормализовали излаз, само поново примењујемо функцију активирања.

И, ето ти! Теоретски, са тим пондерима, вањска неуронска мрежа ће израчунати .85као наш тест резултат! Међутим, наша мета је била .92. Наш резултат није био лош, једноставно није најбољи који може бити. Управо смо имали мало среће када сам изабрао случајне пондере за овај пример.

Како тренирамо свој модел за учење? Па, сазнаћемо врло брзо. За сада, наставимо да кодирамо нашу мрежу.

Ако сте и даље збуњени, топло препоручујем да погледате овај информативни видео који на истом примеру објашњава структуру неуронске мреже.

Спровођење прорачуна

Сада, хајде да генеришемо своје тежине насумично користећи np.random.randn(). Запамтите, требаће нам два комплета тегова. Један да пређе са улазног на скривени слој, а други да пређе са скривеног на излазни слој.

Једном када поставимо све променљиве, спремни смо да напишемо нашу forwardфункцију ширења. Препустимо свој улаз, Xи у овом примеру можемо користити променљиву zда симулирамо активност између улазног и излазног слоја.

Као што је објашњено, морамо узети тачкасти умножак улаза и пондера, применити функцију активације, узети још један тачкасти производ скривеног слоја и другог скупа пондера и на крају применити коначну функцију активације да бисмо добили наш излаз:

На крају, морамо дефинисати нашу сигмоидну функцију:

И, ето га! (Необучена) неуронска мрежа способна да произведе излаз.

Као што сте можда приметили, морамо да оспособимо нашу мрежу за израчунавање тачнијих резултата.

Повратно размножавање - „учење“ наше мреже

Будући да имамо случајни скуп пондера, морамо их изменити да би наши улази били једнаки одговарајућим излазима из нашег скупа података. То се постиже методом која се назива повратно размножавање.

Повратно ширење функционише тако што се помоћу функције губитка израчуна колико је мрежа удаљена од циљног излаза.

Грешка у рачунању

Један од начина представљања функције губитка је коришћење функције функције средњег збира квадрата :

У овој је функцији oнаш предвиђени излаз и yстварни излаз. Сада када имамо функцију губитка, циљ нам је да је приближимо што је могуће ближе 0. То значи да ћемо морати да имамо скоро никакав губитак. Док тренирамо нашу мрежу, све што радимо је минимизирање губитака.

Да бисмо схватили у ком правцу да променимо тежину, морамо да пронађемо брзину промене нашег губитка у односу на нашу тежину. Другим речима, треба да користимо дериват функције губитка да бисмо разумели како пондери утичу на улаз.

У овом случају користићемо делимични дериват који ће нам омогућити да узмемо у обзир другу променљиву.

Ова метода је позната као градијентни спуст . Знајући на који начин да променимо тежину, наши излази могу бити само прецизнији.

Ево како ћемо израчунати инкременталну промену наших тежина:

  1. Пронађите границу грешке излазног слоја (о) узимајући разлику предвиђеног излаза и стварног излаза (и)
  2. Примените дериват наше функције активирања сигмоида на грешку излазног слоја. Овај резултат називамо делта излазним збројем .
  3. Користите делта излазну суму грешке излазног слоја да бисте схватили колико је наш з² (скривени) слој допринео излазној грешци изводећи тачкасти производ са нашом другом матрицом тежине. То можемо назвати грешком з².
  4. Израчунајте делта излазну суму за слој з² применом извода наше функције активирања сигмоида (баш као корак 2).
  5. Подесите тежине за први слој извођењем тачканог производа улазног слоја са скривеном ( з² ) делта излазном сумом . За другу тежину изведите тачкасти умножак скривеног (з²) слоја и излазну (о) делта излазну суму .

Израчунавање излаза делта излаза, а затим примена извода сигмоидне функције су веома важни за повратно размножавање. Дериват сигмоида, познат и као сигмоидни прости број , даће нам брзину промене или нагиб активационе функције на излазном збиру.

Наставимо са кодирањем наше Neural_Networkкласе додавањем функције сигмоидПриме (дериват сигмоид):

Затим ћемо желети да креирамо нашу backwardфункцију ширења која ради све наведено у четири горња корака:

Сада можемо дефинирати свој излаз покретањем ширења унапред и покренути функцију уназад позивањем у trainфункцији:

Да бисмо покренули мрежу, све што треба да урадимо је да покренемо trainфункцију. Наравно, желећемо да то учинимо више пута, или можда хиљадама пута. Дакле, користићемо forпетљу.

Ево пуних 60 линија сјајности:

То је то! Пуноправна неуронска мрежа која може учити на улазима и излазима.

Иако смо своје улазе сматрали сатима учења и спавања, а излазе као резултате теста, слободно их промените у било шта што желите и посматрајте како се мрежа прилагођава!

На крају, све што мрежа види су бројеви. Израчуни које смо направили, колико год изгледали сложени, сви су играли велику улогу у нашем моделу учења.

Ако желите да предвидете излаз на основу наших обучених података, као што је предвиђање резултата теста ако сте учили четири сата и спавали осам, погледајте овде целокупан водич.

Демо и извор

Референце

Стевен Миллер

Велцх Лабс

Кабир Схах

Овај туторијал је првобитно објављен на Енлигхт-у, веб локацији која садржи разне водиче и пројекте за учење кроз изградњу! Погледајте још пројеката попут овог :)