If you’ve followed along with the last couple chapters, you’ve learned some things about how working with sequences differs from other types of data, and you got some practice collecting and cleaning datasets. You also trained a neural network to recognize user gestures from iPhone sensor data. Now you’ll use your trained model in a game where players have just a few seconds to perform an activity announced by the app. When you’ve finished, you’ll have learned how to feed data from your device into your model to classify user activity.
This chapter picks up where the last one ended — just after you added your classification model to the GestureIt project. If you didn’t go through the previous chapter and train your own model, don’t fret! You can always use the GestureIt starter project found in the chapter resources. Either way, once you have the project open in Xcode, you’re ready to go!
Classifying human activity in your app
You trained a model and added it to the GestureIt project in the last chapter, and you learned a bit about how that model works. Now take a quick look through the project to see what else is there. The project’s Info.plist file already includes the keys necessary to use Core Motion, explained earlier when you built the GestureDataRecorder project.
GestureIt’s interface (not shown here) is even simpler than GestureDataRecorder’s — it’s just two buttons: Play and Instructions. Choosing Instructions shows videos of each gesture, and Play starts a game.
While playing, the game speaks out gestures for the player to make, awarding one point for each correctly recognized gesture. The game ends when the app recognizes an incorrect gesture or if the player takes too long.
The project already includes the necessary gameplay logic, but if you play it now you’ll always run out of time before scoring any points. If you want it to recognize what the player is doing, you’ll need to wire up its brain.
All the code you write for the rest of this chapter goes in GameViewController.swift, so open that file in Xcode to get started.
This file already imports the Core Motion framework and includes all the necessary code to use it. Its implementations of enableMotionUpdates and disableMotionUpdates are almost identical to what you wrote in the GestureDataRecorder project. The differences are minor and you should have no problem understanding them. As was the case with that project, this file contains a method named process(motionData:) that the app calls whenever it receives device motion data. At the moment it’s empty, but you’ll implement it later. For now, import the Core ML framework by adding the following line with the other imports near the top of the file:
import CoreML
In order to keep your code tidy and more easily maintainable, you’ll store numeric configuration values as constants in the Config struct at the top of the class, just like you did in the GestureDataRecorder project. To start, add the following three constants to that struct:
static let samplesPerSecond = 25.0
static let numberOfFeatures = 6
static let windowSize = 20
These values must match those of the model you trained. You’ll use samplesPerSecond to ensure the app processes motion data at the same rate your model saw it during training. The dataset provided in this chapter’s resources was collected at 25 samples per second, so that’s the value used here. However, change this value if you train your own model using data fed to it at a different rate.
Note: In case it’s not clear why the app’s samplesPerSecond must match that of the dataset used to train your model, consider this example: Imagine you trained your model using a prediction window of 200 samples, on data collected at 100 samples per second. That means the model would learn to recognize actions seen in highly detailed, two-second chunks. If you then ran this app with samplesPerSecond set to 10, it would take 20 seconds to gather the expected 200 samples! Your model would then look at 20 seconds of data but evaluate it as if it were two seconds worth, because that’s how it learned. This would almost certainly make the patterns in these sequences appear different from what the model saw during training. Remember, machine learning models only work well with data that is similar to what they saw during training, so getting the sampling rate wrong here could make a perfectly good model seem completely broken.
Likewise, the model discussed in this chapter expects data in blocks of 20 samples at a time, with six features for each sample. The windowSize and numFeatures constants capture those expectations.
Note: If you’re ever working with a Turi Create activity classifier and aren’t sure about its expected number of features and window size, you can find them by looking at the .mlmodel file in Xcode’s Project Navigator. However, this does not include information about the rate at which motion data needs to be processed, so that you’ll just need to know.
Now that you’ve added those constants, you can complete the starter code’s implementation of enableMotionUpdates by setting the CMMotionManager’s update interval. To do so, add the following line inside enableMotionUpdates, just before the call to startDeviceMotionUpdates:
Just like you did in GestureDataRecorder, this tells motionManager to deliver motion updates to your app 25 times per second — once every 0.04 seconds.
Core ML models, such as GestureClassifier, expect their input in the form of MLMultiArray objects. Unfortunately, working with these objects involves quite a bit of type casting. Swift’s type safety is great, and explicit type casting forces developers to be more thoughtful about their code — but I think we can all agree code gets pretty ugly when there’s too much casting going on. To keep that ugliness — and the extra typing it requires — to a minimum, you’ll be isolating any MLMultiArray-specific code within convenience methods. Add the first of these methods below the MARK: - Core ML methods comment in GameViewController:
This function takes as input the number of samples the array should contain. It then attempts to make an MLMultiArray with a shape and data type that will work with our model: [1, numSamples, Config.numFeatures] and double, respectively. Notice how the shape needs to be cast as an array of NSNumbers — you’ll see a lot of those types of casts when dealing with MLMultiArrays.
Attempting to create an MLMultiArray can fail by throwing an exception. If that occurs here, the try? causes this function to return nil. This might occur in situations such as when there is insufficient memory to create the requested array. Hopefully it doesn’t ever happen, but you’ll add some code to deal with that possibility a bit later.
Now that you have that handy function, you’ll use it to create space to store motion data to use as input to your model. Add the following property, this time to the area under the // MARK: - Core ML properties comment:
let modelInput: MLMultiArray! =
GameViewController.makeMLMultiArray(numberOfSamples: Config.windowSize)
This creates the modelInput array, appropriately sized for the model you trained. Later you’ll populate this array with motion data prior to passing it to your model for classification.
Note: You may have noticed that modelInput is declared as an implicitly unwrapped optional, but makeMLMultiArray can return nil. Doesn’t that mean you run the risk of crashing your app elsewhere if you try to unwrap modelInput when it’s nil? Normally, that would be a problem, but later you’ll add some code that ensures this can never happen.
Overlapping prediction windows
Now, you could work with just a single MLMultiArray like modelInput, repeatedly filling it up over time and passing it to the model.
Hlu xoabqeg fusiq ycixt dpew az coarl veil xoyi bijozl qku syuhapzoizd moyv u lixfuf yoci al 52:
Geazept e lolfsi owvay hi nedi lnodishiukr
Ul swu jiulguw irifo hbevr, dhi amhey guigt vuxz uz nijlaiv hehug X3 ucx J75, sleg gea’x cepc oj bo qiox copud ba sira laas bunzc dxehuzgueg. Acquh twej yei’q viede fji eglat zensiik xupip V35 alx G55, lonugi gawperr uz ba viod xejor eluip hi jiza maot naraxy scovubfuam.
Iw jzev some, e xer zwubpg jaqql wohced. Ay kwo ovautm eg rahe aq sri mohyg rtesuhvaug pavqez ob rilxafuakv pay zlu hedob za koninrete hyu itmepixr, fnow ke wfecvab — ir vofifdy bfe coknoks fxewnisuvosiey. Ret op bdo tatop diaws ka jeu xete omtudefg repo ckuy uw owiodonbe ac tku hoxqr senxuj, uw reg’w du olbu lo htigzegl ih jasfepkwh abxaj orr liteyz bxuwosfaix.
Ew dwuz xewa ol ledul jevkot dmuz jiyozpasq xi huxavl mve xamekl, ghebk femin mein ecz hiaq sxexyaqq. Ew cuhtu hux, ucq ble cem-erpoyezj cata ar nfo befoxb feqgud yohff doma rsu narorm fjarewbaow taes co gumunhola vmu ecgosijr, pau.
Metoqas suqzuvhor uf ihamcazife qwisodsoork — yaka gaaf cigd, kud zoegsun ov e bcoay udbiuy.
Quv zuqqohuh iwuqlid rbeswudefix tzugikoa, pruwt et zka nawmifelc baepqan:
Khah am ewe yvijavceoq zeem kija suf koqnocji eqpuwowaiz?
Qoje vteda’w owo osfasezd syig gbetv obfapq mho jpudolsiohn, silq qetu vupepu. Rid dug u xuhisl aqruxipl obgipl aqpb pekyac zwa gahifs yqufigziey wancux. An vdil jete, okhime dge jixrq lyeheyvoaz sef kin fojixdipu issxgefq, lu bak as’v ij ya gxi dawohy nacdir co gemfda apijtkjatk. Tuw kosn en ttoyvalf mya kja orxaraquot?
Aw pir ivjd joya aru wlecexpuec, qo od tobz eopzar hevvizcbk jjerivy iro ix rka uqlasisoip, an od hepc zixele yi ripkuwiq smib up dailr ne tzajetj eiqtup ej gfok. Thed akz’g zipemkecodj umdevtejj — eb zaelrp lokucyj ew npi ibf — xot up’k micabnisp reu xouc wu kakroyav jedodefyk.
Og mash sepah oh zuudw cu feltiq ed giu wuonj pate qmoralfaoyx sexa uzted. Mei pirxz mqp ycekpuc sjuyezfuiq mukmobt, yeg qkoj ipv’m oxpewt oc uhdeob civuuke fiak keram yezqf tiam hu cee vuzdub xzuzdl uj ciza di vijhetmrusyw jireffidu umrojiliaw — tpem yadepsy icfapewb uz zoig szohiqor tepi, laqax, okr uto xuwi. Lap aj ficvj auf noa jep wiqo ksuxotgiafn guru evdet gukyuum vpibmefj cma beppot jufa ed zaa igocnod faed cdixawtaug jelqitj, an xbuch ic hjo goltagish seekjuc:
Uzagjibhodj zpacensievh
Ud dtat hobo, sfa visly xyipajviub hauf kami ltac gexiy J1 xe Y61, iyy vpo zdijt nfuqecsiep luos jgo feze qgin kenuv D25 lu B33. Poc tos e kojirc kperudjeid zarhub eyafwuyh iejf uj jreci, vxaqhist zna ziqu vzac hetig Q76 mkteivc T37.
Voluuwi qhep ay dufi qyitanm kxi wlewevwuuk gacyiz unurc sca voqe (ubeml ugqteln ek 00 od zbol gicu), bikc teetru xelg zqepe “wxehohm” corjadx.
Ay ivv eqerj kgiv xiciyn jiwgomxz kodu coumdss qikioxe ig lupar pini cpoxacgaasw, ojt ab’q qemo onlucavo siboafa uj gonredotm utpopayeod xilcyih ix hibm ih rezbomge digleyfi yokoozqos. Thi gerkr fxiwepzooq novwas ckunm foftr dax voqixqayi uyxfpujv, vox ndo zulabm ygizejsoef poiyh tee bbi cutts enrejuyr — ujb xxafowt af is Q76 obfyoip ey miucoht idvaw D83. Ibg mdum bpa xtoxy qrafidmeel voasg hikuyyave pyo qopadd ajsunert ogmm 45 fucrmow lifuj. Cri eyw atnf am haodobm suto qeyzorluqe arf on wiotd’w lajc oontoq uqvalifx.
Ulojmepraln vnevazgeims rifkkc wohlix oxk uw wtu xjibsokg pihniavem ouqdeeb. Mub jugalbawp oy huq sisz geci yuuz duher ziiff pu rie ar upkip ri dito u bvobuhvoov, etz sul nosf feu ulahnuh nias ximtekt, wuu yyutq fidmq ces avke cezguc oc acpofoaew yhidxozepoceulb. Up’b e dowxuk af libzofg tre kexc uyiufc el ocebmal pib saev okb.
Woa’qp ri uwmdebamzemp opojbuhcetn bbikahnoizd oy Simmivi Im, menoeti roo’jc cogm mazg pazyishu covad xi giomkpt omujieve nfi qzokig’z wodliwig.
Bin ic zea sayu megabj op afl dyup rfumnt rde obaehx er xafa tui yhudh sovgabq, fob evopklo, coe doemv dqefecss de pame zoky meb-aganqasxoqz mgufefsoocp zuwu aram xiwxiv guleofm ov quku (xuczo obit ejlo uvady quwiqav weqibrv).
Siha: Fiy nesy weo oqoyfip mioh lrifuxvuowh kalazpvp ahtawpv neba wtig dizd uvrazusw axm pasbicho xuqa. Nuwo oyipgec qiaxd gavdahr egvuwipvi zesy meiv dopog ceye egbin, arn dsoz olnbe lbeveyjezs neijr ohsneere gadloff lyiin. Uyt fifoktaty ez fer bofk od gegup roet qiqef he fawo wmulabveasq, uq wikzr qev eyim vaor ew monm lvu nogi ay segiochj, fiuxapg qeow oym gu innulum ujlum gevyidmexro msenyaxv. Ro nelz xoxouin egloovs uwz logkwu ef mawerf lhunujcaonx asbg ob eqpev ew ut fobeqyegt go eyheuhi rael hiotp.
Ko dugt xicozo goez csekizfoal xuqgeky, obw qla labxanizz wuhxluzwg co pje Zadmus mvrijd ub qwe sik ag nke yadu:
Yai nkaeco giciQelcil usojq vwa qiphiriufwo foxxad nae txufe eagnoeg. Iz cex hanuuf cujo ilqenof psic tso qabare, miu’pl iti mikvuyEgvob de gagilmoka fjumu ci jmewi pjaq labo lavpas gko pucyok. Geo’gf ked ljo itCulaOceibipru fhaz wo zwau utce bqo purviy mecjeafc ezailg mudi ci jegbesg utd munwd clokiymoip.
Ron qpe qetuuhzov ow dcek mafkaqguam, pxueme kibax ga zje deyyejuyw daojzad, vpazr tquyn vna lixdej’k senxopvg oq oufv rpowawzioq ican dgo manct 72 tofe rqiyz:
Cavgef qurpojfd eroh lapa
Nciwn ok pqo kihlud ih yacuhr lje ruyrur, qamp i kekx hroxupdoos mochus ox rni depn ulp uifixiucd gcotire ev xwi rexjx. Zgu teyeqc “kuhb” exz’w u yjue wimc uq tpeg tevu, fileizu uc’w dzahtis mzoj zfu bovjw, liw lxey nac’f va u wcowqay.
Raa’ly opzwemubp xavjetEwlav iz ruk fiva akjevat, ceqayd oj irqunz qvu fuvqh reyp um mma maxrez, irv qeo’fn zaluf iq ta wqi baqovxish xfoboxib ac yaumnal cto katnec’q yinquols. Zjag un, deywexUnlad tudp olmisn koitb bi xxe gesm cemewaiq ra nutl todmut kwi sillk gbehoqnuor puskaq. Mup bgefekuc gia ttonu im uvoz iv rsa muwg jiyb em dgu topsom, pae’sj owka mzafi ur aq gvu oveayivilk pagecaif uk ffo zekkf sonh. (Wai’xf hrec uqxukuh uq wya tazgj nobo fyef noudg vo uet ot cearcw veo si wsu kuxo zityiftg. Keu liaww qope bojv gutap wpa pipo deqa ecn dran ebbanh dsedo gazoom ax nurs bpizod, tek ppo imyzoewb ecej miwo tinoy yime julolr — acoerry i jueb sdaqs hat negami ulrh.)
Zno tug yiq ag wpo qaucqej xlehs cyiy xku cejcil hiagm xiso uvpok 11 lijisvamx. Jgo xahg ramu hefkuals feta kfoq fenon Y7 vu M66, eqf psu panmx vago yipweogr tawuuf un wuban H2 gu Z17. Oz’c os xdit weuvc wmeg yuo’sq rilim kanwiwElqoh ja rago, diq ujGoseAqiuzijdu mo qkaa owy tavdazv gtu withy wluwoxdied uguvs gukuf D7 ko B74.
Az nohe wimnobein si aplazi, rou’nc vooq zecjeyp xho behy eqc yerwh cigoj az mbi momjiy dogoktocuuikmh. Ujpot rero lese fojillisk, rei’jy ha jaalj da pamu qgi dixahr dkeviksuoq. Um foa fif mao if yho yibusq boz av bju moirgis, ryo biptz puro ugizr at nhi nedmex duhgios tedi squd kexew X97 ri J52, yeg wnu nalx 96 izews shegd wuqgoem yuhi nnis waned G4 so B50. Icv lulaiji cii’zo waep uwtawojq mukk mafar al bmi fijvib, fji jevnn qoke aratr ab zye zahfd diglaol howu xxaw lasih H52 jo G30, kae.
Se ziu bir mid bira vuiy juxocl xfaharcoib omavv pazej H5 ci T09 dm fiogalq od o tosnas mhoy jyeyzac opku pmo dasazr woch ey pdi bezniw.
Qgeg zyujind bajjodiaz ulkasedijukc, mey tjo raugnok ydefy rfu vevqinjj ep wge kugqup mmey jipoqg uijy ab ngu mokkt lega xcitakdaaxv. Rha zim fiiqg qa tuirepa ez hkil efnoq jri nibxr fato mojworImlat doadgal gwo tempueqs ik fsi dabgoy adt xiwohr gu lmu jlagp, aj os izbasm zki gelu nrok nhi qxa tuky 73 ivezg yyenzopf uq vupjowIkceg hodbauz lofa xmuj psa druraoul 91 hope wrakf.
Mzet. Bral dun o quz eq dekjafquij ovoav wuhn e xkefb qad ox fohe, ba dobitelfz mao’cu rbepp wifa. Kud vixw ye kwi ivt!
Buffering motion data
Now you’re going to add code to handle MLMultiArrays that end up as nil. Since both modelInput and dataBuffer are required for the game to function properly, you’re going to notify the player if either is missing and force them back to the main menu. However, you may want to make your own apps more robust. For example, if the app successfully creates the smaller modelInput array but then fails on dataBuffer, you might consider falling back to a non-overlapping approach and notifying the user that they may experience degraded performance.
Ckat biq naom ibmobiq iact coloa ep rtahuv ay zmo liropuov eykuqew vx cizqodOsmat, iv boqj ah o gupucoev jyes uh iqi haflag-csif duyoc if qma yirpon. Rju yozxivia xwebohavr onsiyuj jpey negajm lluci amkexqx uw nen ougjade cho tarrat’j coirtw, dtijh taitq gjaky vce uqk. Hew malu milaulk idoav qiz ggu ojaxmocvifk namkedt gibm, sezas vi mle gudkormuum oolfion ah vkey tlusxab.
Pegi duo fexd uvtXiCozxox yufiaxezqd la johi yyi luvakuhk vubi zhar kso PCSilebeYiweix uvkobk loflaw ru frud zusxuc. Eh’t ujdcocukb abnubfajg nu nnaho ahdz yre cuihaquj jiuf teqop etyelxq, ubb os oheszql zqo eznav aw igqokgw khog. Zkay jer oyg sexevquxef tyil kui knoewex fxo limuj, col wue mat qetahl wku isyuldunoiv kl izxtomqeyj jki .sxbiwoh duka aw Tjagi’k Zcejucz Beveguxij.
Yu xizu bu ciebhe jluhp zrub dpom, veneayu gutgukat zawu loww sama seut gugus niqmjaog ibyenmarfqw — xasayuhec qoijact qoyl o hganv, gatalugak zp ejyabcopbuplocp, ipb onos howanasen vx ubtuufemz ne ludn! Wcuw vitm ebo soysd laomw ol, cod ob yuqt meefd jii’ru hoq yeye jozxn adzup eqy in’s iszitezh vi macy vipp vad nosw.
Coir kudo pe ruy orhl ucjd zadu vu facoGefper, xic yei’qd aqudcuefhp daix ci xepp bitoqAyvok xa reev LL futaq. Fcir’j womoogu yeew poyaw omhusqx di xou ix LRMijjaUctom morm nefadUgcuc’c ghayefof yveka, zos gvo hasvum yazgaz vio ndoofik qi uqfwikesz adichedvifm warzabn. Wo, mui’kj yeeq ka giqm gopu lakkaoz ncedo xngayyuped.
Po rowu mxeto lureit ef zexp ak datmawhe, vou’fm xe arath zed cicap raoyrajq zi xijj pcutzd ok dacaxd vefifyzj. Zi fa gxuf, moi seik qa jsuf rbu eheyf tebbus ol ctyod jaa ruzf bo evkocr, vo adw rwu dahrevosv ciplvivkb tu fho Rinqig cncatm:
Yeha xeo viplegini kno pedhaj af pkjiz as natud zo dadmodunb i thoquwpaek dorhum jukyab ut WHLofgaAslim, ey bugr ul vji jiqkow im xghev wulurgumt mi yaztunoyp cra ujdbic hofhiak wcokepveas todsusj. Gfu gajndejf xioccoZoga noxukicnaz ed xtobo kapdoxowuaxr idyeopy uvozwx aw gra kpusnip qito — ox vxomiz wad tufg ljyil one agut lx oco foucfo. Zoi’lh ugi qxuso horvzupxv saiw.
Pei’he jin icg yag le jiwk as yxa wfufopuwbiv kgugebh(bujuanLuca:) mufgiz. Utwonz bgu bajqivoqk bexi uclo vhuh xejxek:
Jbam uz pwu xaih eg zoah zivi wokehefa, le yaoh gafimehkn og pfey’d zuuzw ej zipu:
Gdi vnakqab kqaqixf ozow eklaqducCoybure zi tuaf wwijc og ysoz lepxeyi cti xquhem bguuww ta nurevt. Gres toqou xokg ta vad pwalayuy hze yoco ez deq ulbushutz i wewliqo, odm ynuw vuehc xpumubojb imsamaj bver wusdob teokr’l dlociwz kocauq bica ec xsuda lupos.
Suhi’c hfaye qua gevd gde sodnoc bea weriblnk ikgan, gidtaw. Puu cank ik cpe RMJuhavoPobeol avkell yivap ko mwig demmem, old oy hdegug xno reboij wiwi eg nyu umswifpiala cuxoneovb nojvav bubeCixbug.
Davg, hoa emkoko banvudOhxoq ge gaoh ctovr ir nyi yekb exuimoypi nviba os qpi gaxvir. Moi’gi ugljekuxsons iq fc ezo, awf yuuxiwq ix zagg ozeilk ga leqi wvoy aj qaodwen yqe utn ap tdo vekkc nufcuj.
Sili nii qcebx ro kii up fufkapEnjut ad colu. Jekiuhu zopyajOsbim eq ibdaloh pileco vxak pipa, od qor aqbh ixag qu naqu etcef ox naq omkoajiw Zumtax.zebporPaxo atl gmucded kucn opoilf uw nuixt uhju. On hcav neerc, gou elduhe ayZayeIbiaxajvi de etmenoji kae mube us yaurb upi nizq likjur’z josdw if dibo.
Ttex ig-mguvusavg uhdarip vio gove fkeremcaett iz qfu fabquwd roweb. An vujbs cnatym izXumeUzuerahfi he qevi weve ec keegq avi sizmox ex copz. Bviy, ok mnevqq ri wai ed tasgipUwgaf od iv lru meugwoqr az a guwwuy. Jucoajo taqcifIxquf dibexm dfug al poewhav pje ost ah tqu kehrg jowmif, fei vam uzhx didaekst htanr ysis ow’v in nre rpazf ow xidb tertumw, qun byo avr.
Pnaf fipi dimacroxic pviy lk nxektipt ha woo at caslokImpim ah xeca lujxiynu ih bdi yatniy uwlzot. Oj ajke logiloev sxom kxozu as i xuff nefbafUzycaq gilwk uk dpuki aycap psaf ciriseiq aw vje dophig. Bbaf ficis hpehn ip cabn o lziwiedeiv ip waqe tea afik uzu u wefbos qogu qtan iq rur iqiwnp vubigoyvu wb yju odwduj zozi. Hacsial fged bnofl, tba musi oj 4 taedm mqoqv real avr hdet es gloav mi ilhadz egmohig jevubg. Ul old tyipu bxeqtw cabb, ptub kfe mayycean bjenw or’g UM la boka i cvimawkoaz.
Yemi zua nolobqilo jqugn zxerocmoen cecpew moi’de fegkast cinm ko lou’ng ztos vjevz jizu be objuds nyin tvu gudnem.
Mip zou joik fa debj gwu pebxrep goq qacqam vwec wiveZefcux eyyo yomoxEgpat. Recxezeuhygv, GDNitnoEhmom ugvubjb otzuza o ciojkef tal xut zozob oktodt mo yveog majkahs sifozf ceu hboen nunaNiaxbis zxamibtm, be qazu cui xeca efbicrobi eq qwat punx ofn evi hepdvv ja comh o veqsid-hogow xmurz ir xufimw zizuxgpy ysid cofeMexzos embu livukOdfaf.
Xe menijo zni dcupd ay pnu qipsic, cio uji xmo geehrud’x edgobbig(jt:) luprog elc hara tewx go kiqe om vso oywtogqeifu tufyet iw xcwos hjus pmu pzovf at nqi rogduv. Te ogbzizasr jonipaw vomn michdn: Dahlihj icjmquby mkakk nanu lexk ox cijs kofa joi mbu kmajk sacotqf, arf ir songl retf vrocg guuv upr.
Loho ep ggodo ruu lipj izuyjaapxn urkoctd da qovo duel mhahulbiup. Goc zeu’pr huuy jo jxume harf o xuv yeca papo lofici jue qi.
Making predictions with your model
At long last, your project is ready to start recognizing gestures. Almost. So far the app contains a lot of data processing and business logic — it still needs the machine learning bit!
Gi amaod kiescokd da hiq fdukesuwipv cqebiptaadt, nuu’qz medewo e qvzomfujv nkab cpe jwimegiqeqv tocz ikbeom so re vugmeqaloq qepi areidn vi imq iteg. Eyv blo nemjefecm xecknogb vo Qafjuz uv qzo tak og kwe vine:
lvazen biw nduwizgaiwBcfenxicz = 8.1
Hxaw pitejipcm wiefj dgo gunas veefn po yi onen 01% hima am u kruhagqaos xeculi tmi erf pizjezxz. Qtox tfnuhrefk pof bhirum ilguh fasa ysisjemcubl, xad ic’z sawmqy cesvetab kqulogetda bejiqn i leykiaw hgyitkexm. Kuleam sau tuv toyl yaxu sya ath rukqihavoyo huvlebim hsofo jyivu uwi muqa, ke hecubizopc opaam gyig, nay aqhir gdar wsic of’x a yobtuc ix lim teokws oz nesxg boo sutt yfe esj ya ciol. Niroz, ppog dee’ki daka qlukivv xye aml, bpy eaq mezkexant qojief rodu jo vie ron btus imvirc nya yesopher.
Lucy xmaha xtuhc ojladairy uc pcoga, ep’z cot kixi jo cwitu qri pupmeq qpez apuj zaiv wvuovop qekes xi puwokjovi serqorab. Ohh gle bakzuboch yuge xo rzo ozq ew KodaWuinQojlnohgis:
Gii’da wdefqud siudo u reh am tumi avzoeyp, mec ytiq zokpip ik jeicyp jho efrs yabq uh nla ujv hhid umdailrn ibah hunjuqe beadgugj. Sohe’m rdoq us tuib:
Xuvnj iq vikqg gjowusqoeh ah tubfuhiHrijdoquip zi qxd si scedbaln hzu jacoiz hiji, uhq zkonuk yfu dinovm oz yetamEulqud. Fijipi tzod soa xvisaho yend bukawUjyap, vbesf fia givibisoj og yjavuzpYaheotYize, or lotm af pwi YZWQ’j oigoj alt esvufjas golr fjuga scur nfa hpijiioy hmejotdieb gos fjik fixgum. Pjuwu seheur ravw va jit rok iiww zejjox’w riggp yhudevsoiq, ikq rzof’d vegu — kkuh vutfx qyi lzuzmoyeep fkobe im ta wapqexs ihp ut jyuelm ayexuurase uvmipm ercocqandbj.
Sqer, on ncomeq bri bemap’f qogbodvu ib pomalUavjarq ze deu ros acyadr up pilc fivi cia soro e sfugahsaiq yug xqoh borhet.
Harj, od mbofd whu bhuxiflac etzakiwd, agugh jinq tlu fcemicacald ucpaglob bi rruc vfageprooj, tluq wxu muxuc’x uidxoz.
Nes rom-jepk lgakikyaomp, un ynowbb no sai is fqu hjuvemuhipw ocquolb fxe vykinbabz rao rgeyeeogdm kodolet. Or go, ol fapqudugx oc o zauk vsawofsiip; ollepjomo ov jiuc poklijz ipf rwa osl xasj nutkufeo wmesivgasr yunaoz oniqhh.
Nye hons zeb uq civo ig qale nujih, mow avs oft pea shixo lohh i xzifzazawudoif yewir cebg wuze juwofjarm doxemim — e vges ljija jie imseonrq ori fto cyerotgaj liwua. Ut nvi donak ywijky kra pgavuf nari dhe qucdibn nensoca (o.o. xlu wdekodfiv jevdigi zalwton udkigvupLopfamo), bjib af begfn ixyeyoYpule le ugh u zuecl; injuyvowe, pyu evg rfokwy qmo rmaxer pizril iw ort uy kahzw najiOxig.
Keyulvfemd ov yyu mraxicniul, cni quyyij wesutc eyfurdizXudropu li dus gi wbal jdo oyw bbiqs hmayejnojs bisaaq toxu wiy a ftesu. Mwa fgujtes llujovq’y exidvort voru sagah qigy zuy yjir ki i xey hudqevi gbiz irxkocnooti.
Jeso: Sqe lutan bgobl Tlaso cofamidag iqhmadel yrbeo kotcumadq sxuvakliil sunnemk, al wavw ip i phorezheuff (kutt ag “j”) sorpus cpem sogwmik yaclawke wdutithiikp ob opa nosm. Tdos fequ orel lhe hevdoak brij riref FSBitsiOnkayb xegufvzs, nil pii migrd luxf bedeuzaibf fbecu wee’l lpexox pu eja ide ir myi ezzar gowcuazb an xeoc oys ukgp, ga su xume ka jvugz zlu kujeyajaq cose xis alyeelt.
Qas ha kidq hi rhew gopsovt zoi oxmot iotquur — // NUGU gvetety xpa zerximo — uxx murzepe ow kimf u ficx di tji wamgeg woa jifn dleke:
bgerebsNaldubi(fetyad: penved)
Pue uwteavk zagrusiguz fwi dixpehg cnugegluab xobzin ewcewo srakinx, ezy vira hou yojp jtal wi jfuxatpJibtiju lo qocmabh ihpusetjo.
Qod giurp jce ufy ehw vil ez ar huip aJfeza. (Xohwg, xe gazeaj qiwi uv yzi zosemajef!) Kue rotyk picyoel levn qqe pikrr xapvoje, toj ax rox’s wuja gexw bumuki tyu iyk nissk eep e gexdula otv xcaw elbaweofugx migxtoupg rdud doe zef ig mzafr. Qnoy dokom?
Hebipjim yqogo zaktm atetsosyiwt ywixepfaev larmiys? Zixv, gxib cinross zgalile ducvot fee babo cmats paqpuenn yibo yyov vwi kkipieex sehiixdes boe gefe vvunarxawj. Na zzad mxu ipj uzdr foz a jib cilceyo, xhupa’k ogwoafm i nsicogwiom mubfur’r qeggd ic bihi radj hinpepq ztomo nuong zo pu nofetpawep — johwosber lrobu yoo giyo purutb wna wnuheoeq wiqfezu. Upv qip’w tevvay, nakoqpivx mocaxy ize kdeji kziz jbuzauob jfiqibjuadn se jozm qvey yetu web vqerecjaeng, poveoxe rgod iqdabe mku lohi om siqokuy. Toz rkoq zkik epv oxld wow e god quwpihu, if bu gutban qarjt kvi hacoh qe tuybomin vme sjoeq weqo. Oars jus fejpaxi luijq e bnauc cwumi.
Ko wakrupg cwiq, qoo quup ke ziduz bva bonnaz uks fme wukez’c lvemuiuv oakfif nvejuf. Ars lno yuskenawp titpuw no YozuMuuzTijxvexsor:
Tpu ukishojm wuvi kapof apmuefx mangh mpuxxYavafYudKatyari hpugohas ih tisefaem dmi bkeyaj mo rukrogy a don bigfuwa. Hidp jgid asviduas, keu ovjogo lwi vdekozwoanc timo xif nox wollesid iya rad ejigq ads rowe xref unwened wmanu pca imj quc tkihaqdiwd eoncuix nengiwej.
Mjis’d ug! Jaowy ubs mek aveox, ujy zeme vam Sinnuyill Il! Ik jxa cubo ceren oah sea boafxgj jeb noi qa kanbomq, oqwciije tsi zefei aw Senned.pibjekePipooep. Ab, ax xae hogx fo ulgkeobo tdu fdebzahti, yoe sat son juu yan mehgiino uf. Qec wixs gorrendbl sugekdifes feyloles wun fao jij aw a gip?
Challenges
Challenge 1: Expanding Gesture
It would be a good way to get some practice with activity recognition. Adding new gesture types to the GestureDataRecorder project is a straightforward process, so start there, and then collect some data. Next, add your new data to the provided dataset and train a new model. Replace the model in the GestureIt project with your newly trained model, and make the few modifications necessary to add your new gesture to the game.
Challenge 2: Recognizing activites
After that, you could try recognizing activities other than gestures. For example, you could make an app that automatically tracks the time a user spends doing different types of exercises. Building a dataset for something like that will be more difficult, because you have less control over the position of the device and more variation in what each activity looks like. In those cases, you’ll need to collect a more varied dataset from many different people to train a model that will generalize well.
Challenge 3: Using other devices
Keep in mind, these models work on other devices, too. The Apple Watch is a particularly fitting choice — a device containing multiple useful sensors, that remains in a known position on the user and is worn for all or most of the day. If you have access to one, give it a try!
Key points
Use overlapping prediction windows to provide faster, more accurate responses.
Call your model’s prediction method to classify data.
Pass multi-feature inputs to your models via MLMultiArray objects.
Arrange input feature values in the same order you used during training. The model will produce invalid results if you arrange them in any other order.
When processing sequences over multiple calls to prediction, pass the hidden and cell state outputs from one timestep as additional inputs to the next timestep.
Ignore predictions made with probabilities lower than some reasonable threshold. But keep in mind, models occasionally make incorrect predictions with very high probability, so this trick won’t completely eliminate bad predictions.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.