Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Ilang buwan na ang nakalipas, ang aming mga kasamahan mula sa Google nagastos sa Kaggle isang kumpetisyon upang lumikha ng isang classifier para sa mga larawang nakuha sa kahindik-hindik ang laro "Bilis, Draw!" Ang koponan, na kinabibilangan ng developer ng Yandex na si Roman Vlasov, ay nakakuha ng ikaapat na lugar sa kumpetisyon. Sa pagsasanay sa machine learning noong Enero, ibinahagi ni Roman ang mga ideya ng kanyang koponan, ang huling pagpapatupad ng classifier, at mga kagiliw-giliw na kasanayan ng kanyang mga kalaban.


- Kamusta kayong lahat! Ang pangalan ko ay Roma Vlasov, ngayon sasabihin ko sa iyo ang tungkol sa Quick, Draw! Hamon sa Pagkilala sa Doodle.

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Mayroong limang tao sa aming koponan. Sumali ako bago ang deadline ng pagsasama. Malas namin, medyo kinilig kami, pero napailing kami mula sa posisyon ng pera, at nayanig sila mula sa posisyong ginto. At nakuha namin ang isang kagalang-galang na ikaapat na puwesto.

(Sa panahon ng kumpetisyon, naobserbahan ng mga koponan ang kanilang sarili sa isang rating, na nabuo batay sa mga resulta na ipinakita sa isang bahagi ng iminungkahing set ng data. Ang panghuling rating, naman, ay nabuo sa isa pang bahagi ng dataset. Ginagawa ito upang na ang mga kalahok sa kumpetisyon ay hindi nag-aayos ng kanilang mga algorithm sa partikular na data. Samakatuwid, sa finals, kapag nagpalipat-lipat sa pagitan ng mga rating, ang mga posisyon ay nanginginig nang kaunti (mula sa English na nanginginig - upang ihalo): sa ibang data, ang resulta ay maaaring lumabas para maiba. Nauna ang team ni Roman sa top three. Sa kasong ito, ang top three ay money, monetary rating zone, dahil ang unang tatlong pwesto lang ang nabigyan ng cash prize. Pagkatapos ng shake-up, ang team ay nasa ikaapat na puwesto. Sa parehong paraan, natalo ang kabilang koponan sa tagumpay, ang gintong posisyon. - Ed.)

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Ang kumpetisyon ay makabuluhan din na si Evgeniy Babakhnin ay nakatanggap ng isang grandmaster, si Ivan Sosin ay nakatanggap ng isang master, si Roman Soloviev ay nanatiling isang grandmaster, si Alex Parinov ay nakatanggap ng isang master, ako ay naging isang dalubhasa, at ngayon ako ay isang master.

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Ano ito Quick, Draw? Ito ay isang serbisyo mula sa Google. May layunin ang Google na gawing popular ang AI at sa serbisyong ito ay gustong ipakita kung paano gumagana ang mga neural network. Pumunta ka doon, i-click ang Gumuhit tayo, at may lalabas na bagong page kung saan sinabi sa iyo: gumuhit ng zigzag, mayroon kang 20 segundo para gawin ito. Sinusubukan mong gumuhit ng zigzag sa loob ng 20 segundo, tulad dito, halimbawa. Kung magtagumpay ka, sinasabi ng network na ito ay zigzag at magpapatuloy ka. Anim lang ang ganoong larawan.

Kung nabigo ang network ng Google na makilala kung ano ang iyong iginuhit, isang krus ang inilagay sa gawain. Mamaya sasabihin ko sa iyo kung ano ang ibig sabihin sa hinaharap kung ang isang guhit ay kinikilala ng network o hindi.

Ang serbisyong ito ay nakakalap ng isang medyo malaking bilang ng mga gumagamit, at lahat ng mga larawan na iginuhit ng mga gumagamit ay naka-log.

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Nakuha namin ang halos 50 milyong mga imahe. Mula dito, nabuo ang petsa ng tren at pagsubok para sa ating kompetisyon. Sa pamamagitan ng paraan, ang dami ng data sa pagsubok at ang bilang ng mga klase ay naka-highlight sa bold para sa isang dahilan. Sasabihin ko sa iyo ang tungkol sa kanila mamaya.

Ang format ng data ay ang mga sumusunod. Ang mga ito ay hindi lamang RGB na mga imahe, ngunit, halos nagsasalita, isang log ng lahat ng ginawa ng gumagamit. Word ang target natin, countrycode ang pinanggalingan ng author ng doodle, timestamp ang time. Ipinapakita lang ng kinikilalang label kung nakilala ng network ang larawan mula sa Google o hindi. At ang drawing mismo ay isang sequence, isang approximation ng isang curve na iginuhit ng user gamit ang mga puntos. At mga timing. Ito ang oras mula sa simula ng pagguhit ng larawan.

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Ang data ay ipinakita sa dalawang format. Ito ang unang format, at ang pangalawa ay pinasimple. Pinutol nila ang mga timing mula doon at tinantiya ang hanay ng mga puntos na ito na may mas maliit na hanay ng mga puntos. Para dito ginamit nila Algoritmo ng Douglas-Pecker. Mayroon kang malaking hanay ng mga punto na tinatantya lamang ang isang tuwid na linya, ngunit sa katunayan maaari mong tantiyahin ang linyang ito sa dalawang puntos lamang. Ito ang ideya ng algorithm.

Ang data ay ipinamahagi bilang mga sumusunod. Ang lahat ay pare-pareho, ngunit may ilang mga outlier. Nang malutas namin ang problema, hindi namin ito tiningnan. Ang pangunahing bagay ay walang mga klase na talagang kakaunti, hindi namin kailangang gumawa ng mga weighted sampler at oversampling ng data.

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Ano ang hitsura ng mga larawan? Ito ang klase ng "eroplano" at mga halimbawa mula rito na may mga label na kinikilala at hindi kinikilala. Ang kanilang ratio ay nasa isang lugar sa paligid ng 1 hanggang 9. Tulad ng nakikita mo, ang data ay medyo maingay. Hulaan ko ito ay isang eroplano. Kung titingnan mo ay hindi kinikilala, sa karamihan ng mga kaso ito ay ingay lamang. Sinubukan pa nga ng isang tao na magsulat ng "eroplano," ngunit tila sa Pranses.

Karamihan sa mga kalahok ay kumuha lamang ng mga grids, gumuhit ng data mula sa pagkakasunud-sunod ng mga linya na ito bilang RGB na mga larawan, at inihagis ang mga ito sa network. Iginuhit ko ang humigit-kumulang sa parehong paraan: Kumuha ako ng isang palette ng mga kulay, iginuhit ang unang linya na may isang kulay, na nasa simula ng palette na ito, ang huling linya sa isa pa, na nasa dulo ng palette, at sa pagitan nila. Nag-interpolated ako sa lahat ng dako gamit ang palette na ito. Sa pamamagitan ng paraan, nagbigay ito ng isang mas mahusay na resulta kaysa sa kung gumuhit ka tulad ng sa pinakaunang slide - sa itim lamang.

Ang ibang mga miyembro ng koponan, tulad ni Ivan Sosin, ay sumubok ng bahagyang magkakaibang mga diskarte sa pagguhit. Sa isang channel, gumuhit lang siya ng gray na larawan, sa isa pang channel ay iginuhit niya ang bawat stroke na may gradient mula simula hanggang 32, at sa ikatlong channel ay gumuhit siya ng gradient sa lahat ng stroke mula 255 hanggang 32.

Ang isa pang kawili-wiling bagay ay ang pag-upload ni Alex Parinov ng impormasyon sa network gamit ang countrycode.

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Ang sukatan na ginamit sa kompetisyon ay Mean Average Precision. Ano ang kakanyahan ng panukat na ito para sa kumpetisyon? Maaari kang magbigay ng tatlong hula, at kung walang tamang predic sa tatlong ito, makakakuha ka ng 0. Kung mayroong tama, kung gayon ang pagkakasunud-sunod nito ay isinasaalang-alang. At ang target na resulta ay mabibilang bilang 1 na hinati sa pagkakasunud-sunod ng iyong hula. Halimbawa, gumawa ka ng tatlong predictor, at ang tama ay ang una, pagkatapos ay hatiin mo ang 1 sa 1 at makakuha ng 1. Kung ang predictor ay tama at ang pagkakasunod-sunod nito ay 2, pagkatapos ay hatiin ang 1 sa 2, makakakuha ka ng 0,5. Well, atbp.

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Sa preprocessing ng data - kung paano gumuhit ng mga larawan at iba pa - nakapagpasya kami ng kaunti. Anong mga arkitektura ang ginamit namin? Sinubukan naming gumamit ng mga matatabang arkitektura gaya ng PNASNet, SENet, at mga klasikong arkitektura na gaya ng SE-Res-NeXt, lalo silang pumapasok sa mga bagong kumpetisyon. Mayroon ding ResNet at DenseNet.

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Paano natin ito itinuro? Ang lahat ng mga modelong kinuha namin ay pre-trained sa imagenet. Kahit na mayroong maraming data, 50 milyong mga imahe, ngunit gayon pa man, kung kukuha ka ng isang network na pre-trained sa imagenet, ito ay nagpakita ng mas mahusay na mga resulta kaysa kung sinanay mo lamang ito mula sa simula.

Anong mga pamamaraan sa pagtuturo ang ginamit natin? Ito ang Cosing Annealing na may Warm Restart, na tatalakayin ko sa ibang pagkakataon. Ito ay isang pamamaraan na ginagamit ko sa halos lahat ng aking kamakailang mga kumpetisyon, at kasama nila ito ay lumiliko upang sanayin ang mga grids nang maayos, upang makamit ang isang mahusay na minimum.

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Susunod Bawasan ang Learning Rate sa Plateau. Sinimulan mo ang pagsasanay sa network, magtakda ng isang tiyak na rate ng pagkatuto, patuloy na ituro ito, at ang iyong pagkawala ay unti-unting nag-uugnay sa isang tiyak na halaga. Suriin mo ito, halimbawa, para sa sampung panahon ang pagkawala ay hindi nagbago sa lahat. Binabawasan mo ang iyong rate ng pagkatuto ng ilang halaga at magpatuloy sa pag-aaral. Ito ay bumababa muli, nagtatagpo sa ilang minimum, at muli mong babaan ang rate ng pagkatuto, at iba pa, hanggang sa tuluyang magtagpo ang iyong network.

Susunod ay isang kawili-wiling pamamaraan: Huwag sirain ang rate ng pagkatuto, dagdagan ang laki ng batch. Mayroong isang artikulo na may parehong pangalan. Kapag nagsasanay ka ng isang network, hindi mo kailangang bawasan ang rate ng pagkatuto, maaari mo lamang dagdagan ang laki ng batch.

Ang pamamaraan na ito, sa pamamagitan ng paraan, ay ginamit ni Alex Parinov. Nagsimula siya sa isang batch na katumbas ng 408, at nang umabot ang kanyang network sa isang talampas, nadoble lang niya ang laki ng batch, atbp.

Sa katunayan, hindi ko matandaan kung anong halaga ang naabot ng kanyang batch size, ngunit ang nakakatuwa ay mayroong mga team sa Kaggle na gumamit ng parehong pamamaraan, ang kanilang batch size ay humigit-kumulang 10000. Siyanga pala, ang mga modernong framework para sa malalim na pag-aaral, gaya ng Ang PyTorch, halimbawa, ay nagpapahintulot sa iyo na gawin ito nang napakadali. Binubuo mo ang iyong batch at isumite ito sa network hindi kung ano ito, sa kabuuan nito, ngunit hatiin ito sa mga chunks upang ito ay magkasya sa iyong video card, kalkulahin ang mga gradient, at pagkatapos mong kalkulahin ang gradient para sa buong batch, i-update ang mga timbang.

Sa pamamagitan ng paraan, ang malalaking batch na laki ay kasama pa rin sa kumpetisyon na ito, dahil ang data ay medyo maingay, at isang malaking batch na laki ay nakatulong sa iyo na mas tumpak na tantiyahin ang gradient.

Ginamit din ang pseudo-labeling, kadalasang ginagamit ni Roman Soloviev. Nagsample siya ng halos kalahati ng data mula sa pagsubok sa mga batch, at sinanay ang grid sa naturang mga batch.

Ang laki ng mga larawan ay mahalaga, ngunit ang katotohanan ay mayroon kang maraming data, kailangan mong magsanay ng mahabang panahon, at kung ang laki ng iyong larawan ay medyo malaki, pagkatapos ay magsasanay ka nang napakatagal. Ngunit hindi ito nagdagdag ng malaki sa kalidad ng iyong panghuling classifier, kaya sulit ang paggamit ng ilang uri ng trade-off. At sinubukan lang namin ang mga larawan na hindi masyadong malaki ang sukat.

Paano natutunan ang lahat ng ito? Una, ang mga maliliit na larawan ay kinuha, maraming mga panahon ang pinatakbo sa kanila, ito ay tumagal ng maraming oras. Pagkatapos ay ibinigay ang malalaking sukat na mga larawan, ang network ay sinanay, pagkatapos ay higit pa, kahit na higit pa, upang hindi ito sanayin mula sa simula at hindi mag-aksaya ng maraming oras.

Tungkol sa mga optimizer. Ginamit namin ang SGD at Adam. Sa ganitong paraan posible na makakuha ng isang solong modelo, na nagbigay ng bilis na 0,941-0,946 sa pampublikong leaderboard, na medyo maganda.

Kung pinagsama-sama mo ang mga modelo sa ilang paraan, makakarating ka sa isang lugar sa paligid ng 0,951. Kung gumamit ka ng isa pang diskarte, makakakuha ka ng panghuling marka na 0,954 sa pampublikong board, tulad ng nakuha namin. Ngunit higit pa sa na mamaya. Susunod na sasabihin ko sa iyo kung paano namin binuo ang mga modelo, at kung paano namin nagawang makamit ang gayong pangwakas na bilis.

Susunod, gusto kong pag-usapan ang tungkol sa Cosing Annealing na may Warm Restart o Stochastic Gradient Descent na may Warm Restart. Sa halos pagsasalita, sa prinsipyo, maaari kang gumamit ng anumang optimizer, ngunit ang punto ay ito: kung sanayin mo lamang ang isang network at unti-unti itong nagko-converge sa ilang minimum, kung gayon ang lahat ay okay, makakakuha ka ng isang network, ito ay gumagawa ng ilang mga pagkakamali, ngunit ikaw maaaring sanayin ito nang medyo naiiba. Magtatakda ka ng ilang paunang rate ng pagkatuto, at unti-unting ibababa ito ayon sa formula na ito. Ibinababa mo ito, ang iyong network ay umabot sa ilang minimum, pagkatapos ay i-save mo ang mga timbang, at muling itinakda ang rate ng pagkatuto na nasa simula ng pagsasanay, at sa gayon ay pupunta sa isang lugar pataas mula sa minimum na ito, at muling ibinababa ang iyong rate ng pagkatuto.

Kaya, maaari mong bisitahin ang ilang mga minimum nang sabay-sabay, kung saan ang iyong pagkawala ay magiging, plus o minus, pareho. Ngunit ang katotohanan ay ang mga network na may ganitong mga timbang ay magbibigay ng iba't ibang mga error sa iyong petsa. Sa pamamagitan ng pag-average sa mga ito, makakakuha ka ng ilang uri ng pagtatantya, at magiging mas mataas ang iyong bilis.

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Tungkol sa kung paano namin binuo ang aming mga modelo. Sa simula ng pagtatanghal, sinabi kong bigyang pansin ang dami ng datos sa pagsusulit at ang bilang ng mga klase. Kung magdagdag ka ng 1 sa bilang ng mga target sa set ng pagsubok at hatiin sa bilang ng mga klase, makukuha mo ang numerong 330, at ito ay isinulat sa forum - na ang mga klase sa pagsusulit ay balanse. Ito ay maaaring gamitin.

Batay dito, nakabuo si Roman Soloviev ng isang sukatan, tinawag namin itong Proxy Score, na lubos na nauugnay sa leaderboard. Ang punto ay: gagawa ka ng isang hula, kunin ang nangungunang 1 ng iyong mga predictor at bilangin ang bilang ng mga bagay para sa bawat klase. Susunod, ibawas ang 330 mula sa bawat halaga at idagdag ang mga resultang ganap na halaga.

Ang mga sumusunod na halaga ay nakuha. Nakatulong ito sa amin na hindi lumikha ng isang probing leaderboard, ngunit upang mapatunayan nang lokal at pumili ng mga coefficient para sa aming mga ensemble.

Sa isang ensemble maaari kang makakuha ng ganoong bilis. Ano pa bang magagawa ko? Ipagpalagay na ginamit mo ang impormasyon na ang mga klase sa iyong pagsusulit ay balanse.

Iba ang pagbabalanse. Isang halimbawa ng isa sa kanila β€” pagbabalanse mula sa mga lalaki na kumuha ng unang lugar.

Anong ginawa natin? Ang aming pagbabalanse ay medyo simple, iminungkahi ito ni Evgeny Babakhnin. Una naming pinagbukud-bukod ang aming mga hula ayon sa nangungunang 1 at mga napiling kandidato mula sa kanila - upang ang bilang ng mga klase ay hindi lalampas sa 330. Ngunit para sa ilang mga klase ay magkakaroon ka ng mas kaunti sa 330 na predictor. Okay, pag-uri-uriin din natin ayon sa nangungunang 2 at nangungunang 3 , at pipili din tayo ng mga kandidato.

Paano naiiba ang aming pagbabalanse mula sa pagbabalanse sa unang lugar? Gumamit sila ng isang umuulit na diskarte, kinuha ang pinakasikat na klase at binabawasan ang mga probabilidad para sa klase na iyon ng ilang maliit na bilang hanggang sa ang klase na iyon ay hindi na pinakasikat. Kinuha namin ang susunod na pinakasikat na klase. Kaya't patuloy nilang ibinababa ang mga ito hanggang sa maging pantay ang bilang ng lahat ng klase.

Gumamit ang lahat ng plus o minus one na diskarte para sanayin ang mga network, ngunit hindi lahat ay gumamit ng pagbabalanse. Gamit ang pagbabalanse, maaari kang pumunta sa ginto, at kung ikaw ay mapalad, pagkatapos ay sa pera.

Paano i-preprocess ang isang petsa? Ang bawat tao'y naunang nagproseso ng petsa, plus o minus, sa parehong paraan - paggawa ng mga handcrafted na tampok, sinusubukang i-encode ang mga timing na may iba't ibang kulay ng stroke, atbp. Si Alexey Nozdrin-Plotnitsky, na nakakuha ng ika-8 na lugar, ay nagsalita tungkol dito.

Pag-uuri ng mga guhit na sulat-kamay. Mag-ulat sa Yandex

Iba ang ginawa niya. Sinabi niya na ang lahat ng mga handcrafted na feature na ito ay hindi gumagana, hindi mo kailangang gawin iyon, dapat matutunan ng iyong network ang lahat ng ito sa sarili nitong. At sa halip, gumawa siya ng mga module sa pag-aaral na nag-preprocess sa iyong data. Inihagis niya ang orihinal na data sa mga ito nang walang preprocessing - point coordinates at timing.

Pagkatapos ay kinuha niya ang pagkakaiba batay sa mga coordinate, at na-average ang lahat ng ito batay sa mga timing. At nakabuo siya ng medyo mahabang matrix. Ilang beses niyang inilapat ang 1D convolution dito upang makakuha ng isang matrix na may sukat na 64xn, kung saan ang n ay ang kabuuang bilang ng mga puntos, at 64 ang ginawa upang maipakain ang resultang matrix sa layer ng anumang convolutional network, na tumatanggap ng bilang ng mga channel. - 64. nakakuha siya ng isang 64xn matrix, pagkatapos mula dito kinakailangan na lumikha ng isang tensor ng ilang laki upang ang bilang ng mga channel ay katumbas ng 64. Na-normalize niya ang lahat ng mga puntos na X, Y sa saklaw mula 0 hanggang 32 upang lumikha ng isang tensor ng laki 32x32. Hindi ko alam kung bakit gusto niya ang 32x32, nangyari lang iyon. At sa coordinate na ito ay inilagay niya ang isang fragment ng matrix na ito na may sukat na 64xn. Kaya napunta lang ito sa isang 32x32x64 tensor na maaari mong ilagay pa sa iyong convolutional neural network. Yun lang ang gusto kong sabihin.

Pinagmulan: www.habr.com

Magdagdag ng komento