• No results found

RÖSTIGENKÄNNING MED MOVIDIUS NEURAL COMPUTE STICK VOICE RECOGNITION WITH MOVIDIUS NEURAL COMPUTE STICK

N/A
N/A
Protected

Academic year: 2021

Share "RÖSTIGENKÄNNING MED MOVIDIUS NEURAL COMPUTE STICK VOICE RECOGNITION WITH MOVIDIUS NEURAL COMPUTE STICK"

Copied!
36
0
0

Loading.... (view fulltext now)

Full text

(1)

EL1805, Examensarbete, 15 hp

Högskoleingenjörsprogrammet i Elektronik och datorteknik, 180 hp

RÖSTIGENKÄNNING MED

MOVIDIUS NEURAL

COMPUTE STICK

VOICE RECOGNITION

WITH MOVIDIUS NEURAL

(2)

Sammanfattning

Företaget Omicron Ceti AB köpte en Intel Movidius Neural Compute Stick (NCS), som är en usb-enhet där neurala nätverk kan laddas in för att processa data. Min uppgift blev att studera hur NCS används och göra en guide med exempel. Med TensorFlow och hjälpbiblioteket TFLearn gjordes först ett testnätverk för att prova hela kedjan från träning till användning med NCS. Sedan tränades ett nätverk att kunna klassificera 14 olika ord. En mängd olika utformningar på nätverket testades, men till slut hittades ett exempel som blev en bra utgångspunkt och som efter lite justering gav en träffsäkerhet på 86% med testdatat. Vid inläsning i mikrofon så blev resultatet lite sämre, med 67% träffsäkerhet. Att processa data med NCS tog längre tid än med TFLearn men använde betydligt mindre CPU-kraft. I mindre system såsom en Raspberry Pi går det däremot inte ens att använda TensorFlow/TFLearn, så huruvida det är värt att använda NCS eller inte beror på det specifika användningsscenariot.

Abstract

(3)

Innehåll

1 Begrepp och Förkortningar 3

2 Inledning 3

3 Teori 5

3.1 Vad är neurala nätverk? . . . 5

3.2 Träning . . . 6

4 Metod och Material 7 4.1 Material . . . 7

4.2 Översikt Movidius Neural Compute Stick . . . 7

(4)

1

Begrepp och Förkortningar

DNN Deep Neural Network - Ett nätverk med fler än ett lager

FFT Fast Fourier Transform - En metod som omvandlar en signal från

tidsrummet till frekvensrummet, för att kunna se frekvensinnehållet Inferens Att dra slutsats från tidigare kunskap och erfarenheter. I detta

sam-manhang betyder det att stoppa in data i ett nätverk och få utdata som beror på den tidigare träningen

NCS Movidius Neural Compute Stick

NCSDK Neural Compute Software Development Kit

NCAPI Neural Compute Application Programmer’s Interface

Prestanda Träffsäkerhet för nätverket, hur ofta rätt svar ges

Överträning Ett neuralt nätverk kan råka bli väldigt duktigt på träningsdatat men dåligt på att generalisera, så att det blir dålig prestanda på ny data som det inte tränats på.

2

Inledning

Maskininlärning kanske låter som ett framtidskoncept, men används redan idag på många håll. Objektigenkänning i självkörande bilar, röstigenkänning i telefoner, och riktad re-klam, är alla exempel där det använts för att få bättre och snabbare resultat än att stapla ett otal if-satser på varandra. Men vad innebär maskininlärning? Det är i stora drag ett system som tränas med en mängd indata för att sedan kunna dra inferens, göra en förutsägelse, på ny okänd indata [1]. Det som tränas kallas för neuralt nätverk och kommer i olika former men är i grunden inspirerat av hur hjärnan fungerar ([2] s. I-8). Ett mål med neurala nätverk är i regel att kunna generalisera, där t.ex. ett system för ansiktsigenkänning ska kunna identifiera att det ser ett ansikte fastän det inte tränats på det specifika ansiktet.

Företaget Omicron Ceti AB är intresserat av hårdvara för maskininlärning och vill veta mer kring det för eventuell användning i framtida projekt. De har köpt en Intel Movidius Neural Compute Stick (NCS), vilket är en usb-enhet där redan tränade neurala nätverk kan laddas in för att processa indata. Syftet är att studera hur NCS används och göra en guide med exempel.

(5)

Figur 1 – Förslag på utformning av ett system för röstigenkänning

Under förstudien sattes ett antal krav på systemet, som listas i tabell 1.

Tabell 1 – Kravlista över systemet

Krav 1 Systemet kan spela in ord från användaren Bas

Krav 2 Systemet använder ett tidigare tränat nätverk tillsammans med NCS för analysera det inlästa kommandot

Bas

Krav 3 Inspelningen ska ske så brusfritt som möjligt Bas

Krav 4 Samplingsfrekvens >= 16 kHz Bas

Krav 5 NCS används för analys av de inspelade orden Bas

Krav 6 Statistik över nätverkets prestanda tas fram Bas

Krav 7 Jämförelser mellan träningssampels med och utan pålagt brus och mellan olika mikrofoner

Extra Krav 8 Inspelning med en ”verkligare” mikrofontyp, t.ex. elektretmikrofon Extra Krav 3 baseras på att nätverket kan bli bättre tränat om träningsdatat innehåller brus [3]. Kopplat till det så är utgångspunkten att inläsningen av orden sker så brusfritt som möj-ligt för att förbättra resultatet. Krav 4 bygger dels på antagandet att för dålig ljudkvalitet kan ge sämre resultat, men främst att det funna träningsdatat har en samplingsfrekvens på 16 kHz (se metodavsnittet4). Krav 8 utgår från ett produktscenario, där en användare kanske styr en hiss med rösten. Där kommer det råda suboptimala förhållanden med en så billig mikrofon som möjligt. Eftersom det är en studie snarare än en produkt så har det inte ställts några direkta krav på prestanda (där prestanda i denna kontext betyder träffsäkerheten i nätverket, hur ofta man får rätt svar). Fokus blev därför att få systemet att fungera som helhet snarare än att maximera prestandan hos röstigenkänningen. En beskrivning av arbetsgången skulle även tas fram, där det framgår med exempel hur NCS kan användas.

(6)

3

Teori

3.1 Vad är neurala nätverk?

Neurala nätverk är i grunden en analog till hur hjärnan fungerar, om än hjärnan är otroligt mycket mer komplex än vad som går simulera idag (dock så har man lyckats med en flughjärna [4]). När vi lär oss något så aktiveras våra neuroner och nya kopplingar skapas långsamt, vilka förstärks med tiden om inlärningen fortsätter ([2] s.I-8). Vi kan sedan dra inferens med hjälp av tidigare inlärda mönster: när vi ser en människa vet vi att det är en människa fastän vi aldrig sett personen förr. Vi vet dessutom att det är en människa fastän vederbörande skulle ha en ansiktsmask och sakna ett ben, medan ett naivt datorprogram kanske skulle räkna lemmar och ögon och därför missa att det är en människa. Vi är till och med så generella att vi kan se människor när det egentligen bara är en cirkel och några streck, som i figur2!

Figur 2 – En människa eller en samling streck och en cirkel?

På liknande sätt tränas neurala nätverk för att sedan (förhoppningsvis) kunna dra slut-satser om ny okänd data. Ett neuralt nätverk består av ett eller flera lager. Figur3visar principen för ett så kallat Feed Forward-nätverk, där datat går seriellt från lager till lager. Är det fler än ett lager så kallas det för djupt neuralt nätverk, eller Deep Neural Network (DNN).

Figur 3 – Principskiss av ett DNN

(7)

Figur 4 – Figuren visar ett lager med neuroner och dess associerade vikter

Vektorn p är det inkommande datat, och skickas till varje neuron. För varje neuron finns en vektor Wi med vikter, som multipliceras med p. Utvärdet från varje neuron ai

beräknas enligt ekvation1 (notation från [2] s. 2-18)

ai = f (Σwjpj + b) (1)

där b är en konstant, bias (visas ej i figuren), och f är en aktiveringsfunktion. Det är en funktion som väljs beroende vad nätverket ska utföra, och som oftast är olinjär [5]. Vanliga aktiveringsfunktioner är sigmoid och tanh, vars utvärden går från 0 till 1 respektive -1 till 1, vilket då motverkar att värdena i nätverket sväller till orimliga proportioner. En annan är Rectified Linear Unit, ReLu. Den är linjär för värden över 0 och ger annars 0 i utvärde, vilket gör funktionen i sin helhet olinjär. I nätverk som klassificerar indata i distinkta klasser kan funktionen Softmax användas. Den ger sannolikheten för varje klass, så att den totala summan blir 1 [1].

3.2 Träning

(8)

indikation på hur generell inlärningen blev.

En risk är överträning, där nätverket kan ha god prestanda på träningssetet men får mycket sämre resultat på valideringssetet. Detta kan motverkas med så kallade dropout-lager [6]. För varje iteration i träningsfasen behålls varje element med en angiven sanno-likhet.

4

Metod och Material

4.1 Material

Systemkraven dikterades främst av NCS. En dator med 64 bit Ubuntu 16.04 som ope-rativsystem eller en Raspberry Pi 3 med Raspbian Stretch krävs för kompilering och kommunikation med NCS (4.2). För enkelhetens skull användes min egen dator under hela kedjan, från träning till inferenstester: en Acer Aspire (modellbeteckning E15 E5-521G-87EH) med 8 Gb RAM och en fyrkärnig processor som går upp till 2.4 GHz. Operativsystemet är Ubuntu 16.04 LTS. Det API som används vid inferens med NCS stöder både Python och C/C++, men all programmering skedde i Python v3.5.2. Detta dels eftersom det trots obefintlig tidigare erfarenhet med språket bedömdes spara tid jämfört med C, och dels för att Python är det primära språket för Tensorflow (4.3). Vid inläsning av ord användes Trust Mico USB Microphone. Den bedömdes vara av nog hög kvalitet för testerna, och usb-anslutningen var en fördel eftersom datorn inte har mikrofoningång.

4.2 Översikt Movidius Neural Compute Stick

Movidius Neural Compute Stick från Intel är specialiserad hårdvara för att köra inferens på redan tränade neurala nätverk. Det är en usb-sticka som innehåller deras Movidius Myriad 2 VPU (Vision Processing Unit) som enligt säljargumenten erbjuder hög pre-standa till strömsnåla system, där säkerhetskameror och drönare ges som exempel [7]. Nätverket måste först tränas på en dator, där ramverken som stöds är Caffe och Tensor-Flow. Det tränade nätverket kompileras sedan till ett format som förstås av NCS med hjälp av mjukvaran Intel Movidius Neural Compute Software Development Kit (NCS-DK), som anropas via terminalkommandon. En fil i formatet .graph genereras som sedan laddas in i NCS och som maximalt får vara 320 MB. Kommunikationen med NCS sker via programmeringsgränssnittet NCAPI, som finns både till C och Python.

4.3 TensorFlow/TFLearn

(9)

samtidigt. TensorFlow stöder flera språk men är primärt gjort för användning med Pyt-hon, vilket även TFLearn är.

Figur5 visar ett exempel på hur lager definieras i TFLearn.

Figur 5 – Exempel på nätverksdefinition i TFLearn

I första lagret anges formen på indatat. Formen [None,10] anger att det är en vektor som är 10 element lång och en odefinierad ”batch size”, alltså hur många vektorer som matas in per gång. Lagret som heter ”fully connected” är det standardlager som beskrevs i avsnitt3.1. Där anges hur många neuroner som ska vara i lagret och vilken aktiverings-funktion som används. Ej visat i bild är att det även anges om nätverket är ett DNN eller ett sekvensgenererande nätverk. Det finns även fler argument till varje lager än som använts i figuren.

Under projektet användes Tensorflow v1.7.0 och TFLearn v0.3.2.

4.4 Arbetsgång

Under arbetets gång har små ”testfiler” använts för att snabbt kunna testa egenskrivna och inbyggda Python-funktioner, för att sedan inkorporera dem i huvudprojekten. För att spara tid gjordes inget eget bibliotek; de funktioner som återanvänds kopierades helt enkelt in i rätt fil. Koden är inte jättegenerell och tar inte argument. Sökvägar osv. är skrivna direkt i filen, och funktioner är skrivna med förkunskap om filformat etc. Valet av av ramverk för uppbyggnaden av nätverket blev TensorFlow tillsammans med högnivå-API:t TFLearn, just för att TFLearn verkade vara en rimlig förenkling. Jag följde rekom-mendationen på hemsidan [8] och installerade TensorFlow i en isolerad Pythonmiljö med Virtualenv, och valde versionen för Python 3.5 och endast CPU-användning (Nvidias GPU:er kan annars användas för att accelerera beräkningar). Installationen validerades enligt deras instruktion. Efter det installerades den senaste stabila versionen av TFLearn och ett projekt från deras snabbstartsguide [9] testades, vilket fungerade. Samma projekt användes som mall för att göra ett eget testprojekt, där tanken var att göra ett enkelt nätverk med lättolkad utdata. Detta för att få testa hela kedjan, från att bygga nätverket till att använda det med NCS.

4.4.1 Testnätverk

(10)

Svaret som ges vid träning är en vektor med längd 10 med en 1:a på samma index som indatat och resten nollor, enligt figur 6.

Figur 6 – Illustration av in- och utdata från det första testnätverket

Nätverket är detsamma som i figur 5. Softmax används som aktiveringsfunktion i ut-lagret och Pythonfunktion argmax (från numpy-biblioteket) kan då användas för att få det index i utvektorn som anger högst sannolikhet. Testnätverket fick 100% prestanda vid träningen, och gav alltid rätt svar vid test. Koden är bifogad som build_graph.py i bilaga A.

NCSDK/NCAPI installerades och testades enligt [10]. Här ska noteras att det släpptes nya versioner mot slutet av projektet, som dessutom inte är bakåtkompatibla. Alla tes-ter gjordes med NCSDK 2.0 och NCAPI v1, men den bifogade koden är omskriven och testat för NCSDK 2.04/NCAPI v2. En fallgrop är att den förväntade datatypen byttes från float16 till float32, vilket dock går att ändra. Vid inferens omvandlas datat hur som helst till float16 så det blir ingen skillnad i prestanda.

För att kompilering till NCS filformat ska fungera måste träningsspecifik data tas bort. Det görs genom att definiera om samma nätverk fast utan t.ex. regression- och dropout-lager. Man laddar sedan in de tidigare nätverksvikterna, som sparats vid träning, och sparar igen. För testnätverket görs det i prep_graph.py, bilagaA.

Kompileringen sker med terminalkommandot mvNCCompile, som är en del av NCS-DK. Som argument anges [filnamn].meta för det sparade nätverket. Det går att ange fler argument, vilket visade sig inte vara så frivilligt som det framstår av beskrivningen [11]. NCS har 12 st så kallade SHAVE-processorer, där bara en används om inget annat anges. Det är en potentiell flaskhals så det sattes till max antal. Namn på in- och utlager går även ange, t.ex. för att testa specifika delar av ett nätverk. Som sett i figur 5 så går det att explicit namnge lagren men det visade sig att namnen får tillägg vid sparning, vilket kan vara en konsekvens av TFLearn. Genom att skriva ut en läsbar beskrivning av nätverket med funktionen tensorflow.train.write_graph() så gick det få de kompletta namnen. Slutligen så går det ange namn på den genererade .graph-filen. Det fulla kom-mandot för testnätverket blev

mvNCCompile graph_inference.meta -s 12 -in input/X -on output/Softmax -o graph_comp.graph

(11)

4.4.2 Röstigenkänning

Under förstudien hittades Googles Speech Commands Data Set v0.01 (släppt under Cre-ative Commons BY 4.0 license), som användes som träningsdata. Det är ungefär 65 000 inläsningar fördelade på 30 ord, inlästa av många olika människor (crowdsourcat) [12]. Alla filer är en sekund långa med samplingsfrekvens 16 kHz i 16 bit mono.

Filerna i sampelbiblioteket är i wav-format, så första steget blev att extrahera själva ljud-datat från filerna. Det görs med Pythons wave-bibliotek, där man först måste omvandla det byte-format som används till vanliga heltal. Det visade sig att vissa filer var kortare än en sekund (eller 16 000 samplingar), vilket ordnades genom att förlänga datat med slumptal med samma maxamplitud som snittamplituden i filens 300 första samplingar. För att minska variationen i träningsdatat så normaliseras varje ord så att maxampli-tuden blir ungefär ±32767, motsvarande full volym för 16 bits ljud. Ordet flyttas sedan till början av filen genom att söka efter första förekomsten av en gränsamplitud och byta plats på de två segmenten. Gränsamplituden sattes till en konstant och valdes genom testning. Det är dock osäkert hur bra det fungerar generellt men jag antog att det i snitt skulle bli samma fel för ett givet ord, vilket då minskar variationerna och alltså uppfyller syftet. Figur7och8visar ljuddata från en fil i originalform respektive normali-serad och förflyttad. Där syns både det tillagda bruset och att början av ordet klippts av.

(12)

Figur 8 – Data från samma ljudfil som i figur 7 men som normaliserats och där ordet flyttats till början

Alla inläsningar processades och sparades som en numpy-array i ett träningsset och ett testset för respektive ord. Vid själva träningen anges i TFLearn hur stor andel av det sparade träningssetet som ska användas för träning respektive validering. Ordningen på datat randomiserades innan sparning eftersom samma person oftast har två inläsningar per ord.

I hopp om att spara tid testades först att träna nätverk enbart med den normaliserade och förflyttade ljuddatan. Flera olika utformningar av nätverket testades med varieran-de antal lager och neuroner och generellt använvarieran-des endast orvarieran-den ”yes” och ”no”, men prestandan blev aldrig bättre än slumpen. Med inspiration från [13] så gjordes en fre-kvensanalys på filerna (efter normalisering/förflyttning). Filerna delades upp i segment om 20 millisekunder och en FFT utfördes på varje segment. Grundtanken var att skapa ett Recurring Neural Netwok (RNN) där det tas hänsyn till ordningen på indatat, men det visade sig att NCS inte stöder RNN så ett ”vanligt” DNN användes ändå. Figurerna

(13)

Figur 9 – Ordet ”yes” i frekvensspektrat. Ljusare färger indikerar mer energi i frekvens-området.

Figur 10 – Ordet ”no” i frekvensspektrat. Ljusare färger indikerar mer energi i frekvens-området.

För att minimera manuell handpåläggning gjordes samplelib_process.py (i bilagaB). Där går det ange vilka ord i sampelbiblioteket som ska processas, vilket då sker i ett enda svep. Det visade sig att det fanns enstaka filer som var över en sekund, vilket koden inte hanterar. I slutändan processades 14 av orden.

(14)

att det kunde vara ett problem. Batch normalization-lager normaliserar datat [14], och när det testades blev resultaten mycket bättre. Det gick däremot inte kompilera nätver-ket, trots att NCS officiellt stöder batch normalization. Till slut hittade jag ett exempel som också använde frekvensanalys och DNN [15]. I det nätverket har alla dolda lager 128 neuroner och ReLu som aktiveringsfunktion. Med det som start så blev resultaten bra, och antalet lager utökades tills 14 ord var inlärda med en prestanda på 86.8%. Utlagret använder Softmax som aktiveringsfunktion och har en neuron per ord. Dropoutlager la-des till vid träning för att minska risk för överträning, där 10% dropout rate visade sig fungera bra.

Figur 11 – Definitionen i TFLearn av det slutgilta nätverket. NODES är 128, alltså antalet neuroner i de dolda lagren. Utlagret har 14 neuroner, motsvarande det antal ord som kan klassificeras.

Filen training.py i bilagaBinnehåller koden som användes vid träningen av det slutgilti-ga nätverket. Där definieras den lista med ord som tränas, vilken sparas och används av efterföljande steg för att slippa behöva kopiera mellan filer och dessutom minska risken för fel. Facit genereras nämligen av en funktion i respektive fil, och då måste ordningen på orden vara densamma som den var vid träningen.

(15)

Figur 12 – Exempel på inläsning med mikrofon. Här visas även tiden det tog att processa ljudet och köra inferens.

För att spela in från mikrofonen anropas terminalkommandot arecord via Pythons sub-process-funktion. I argumenten anges att formatet ska vara 16 kHz 16 bit mono, och att inspelningen ska vara en sekund lång. Därefter utförs samma process som med sam-pelbiblioteket (normalisering, förflyttning, frekvensanalys), för att sedan skickas till NCS för inferens.

4.4.3 Tester

Nätverket validerades med testseten för att se om prestandan bibehölls (validation.py bilaga B). Det gjordes både med TFLearn och NCS, och samtidigt mättes tiden för respektive test. Det går att anropa TFLearns inferensfunktion med hela testdatat (hä-danefter kallat TF Batch) som indata direkt snarare än att anropa funktionen med en inläsning i taget (TF Single). Eftersom NCS kräver ett anrop per inläsning så gjordes bå-da varianterna med TFLearn för att få en rättvis jämförelse men samtidigt se om det blir någon skillnad mellan anropssätten. Testseten innehöll totalt 3321 inläsningar. Mindre ”formella” tester gjordes under arbetets gång med den första varianten av nätverket där det även testades på en äldre laptop med en tvåkärnig processor, för att se eventuella skillnader.

För att testa prestandan vid inläsning i mikrofon fick fyra personer läsa in de 14 inlärda orden två gånger var, alltså totalt 8 inläsningar per ord. En inläsning gjordes om när det uppstod uppenbara fel såsom att inspelningen inte startade direkt så att inläsningen blev avklippt. Testet skedde i en enskilt rum utan störande ljud.

Gemensamt för de ovanstående testerna är att ingen hänsyn togs till hur säkert svaret från inferensen var. Den högsta siffran i svarsvektorn valdes alltid som svar.

(16)

användning, och eftersom processorn är 4-kärnig så innebär det att en fullastad kärna kommer att visas som 25% belastning.

Endast en mikrofon testades i slutändan, och träningsdatat behandlades aldrig med något extra brus. Det märktes på några stickprov att ljudkvalitén skiftar mycket mellan inläsningar, vilket är rimligt eftersom det är ”vanligt folk” som bidragit och många då förmodligen bara använt sin datormikrofon.

5

Resultat

Figur13 visar det slutgiltitga systemet, redo för inläsning i mikrofonen.

Figur 13 – Figuren visar det slutgiltiga systemet

Prestandan för TFLearn och NCS blev 86.3% respektive 86.4%. TF Single tog 12 sekun-der och NCS tog 15 sekunsekun-der. TF Batch tog 0 sekunsekun-der, alltså snabbare än upplösningen på tidtagningen. Testerna med det gamla nätverket på den äldre laptopen tog 1 min 42 sek för TF Single, 8 sek för TF Batch, och 1 min 53 sek för NCS.

(17)

Figur 14 – Antal korrekta klassificeringar av de inlästa orden, där 8 rätt är det maximala.

Den uppmätta CPU-belastningen blev 25% för TF Single, >90% för TF Batch, och 1-2% för NCS. Exakta siffror var svåra att få på grund av de variationer som alltid finns i en dator.

En liten guide har överlämnats till företaget, med utgångspunkt från de bifogade exemp-len.

6

Diskussion

(18)

äldre datorn. Att TF Batch nästan maximerade alla kärnor syntes, men tidsåtgången var lägre än vad endast parallellisering kan förklara. En gissning är minskad overhead på grund av färre loopar och funktionsanrop.

Prestandan när nätverket testades med mikrofon var betydligt lägre jämfört med testse-tet. Idealt hade fler personer deltagit i försöket, och det var dessutom endast mansröster. Det går dock konstatera en skillnad på ordbasis, så svagheten ligger gissningsvis i själva nätverket. Som syntes i figurerna 9och 10 så går det visualisera ljudet som en bild där färgerna motsvarar intensiteten i frekvensspektrat så det hade varit intressant att appli-cera t.ex. convolution och max pooling, som vanligtvis används mer i bildbehandling. Vad gäller kravlistan över systemet (tabell 1) så går det nog säga att alla baskrav är uppfyllda, men inget av extrakraven. En bättre mikrofon kunde eventuellt ha använts, men träningsdatat bestod inte av några perfekta inspelningar brusmässigt sett så jag bedömer att den var bra nog.

Generella förbättringar som skulle kunna göras är att hitta metoder/nätverkslager som minimerar behovet av förbehandling av träningsdatat och inläsningar. Det vore även önskvärt att träna in oljud och ”fel ord” så att nätverket kan klassificera något som okänt istället för att alltid ge ett svar. Med mer tid hade jag även samlat alla skrivna funk-tioner i ett bibliotek snarare än att kopiera in dem i vardera projektfil. Det var inget stort problem med så pass få filer, men det skulle göra koden mer överskådlig och minska risken för fel.

(19)

Referenser

[1] Machine Learning Glossary (2018)

https://developers.google.com/machine-learning/glossary/

[2] Hagan, M.T. , Demith, H.B. , Beale, M.H. , De Jesús, O. (2014). Neural Network Design. 2nd Ed.

http://hagan.okstate.edu/NNDesign.pdf

[3] Yin, S. et al.(2015). Noisy training for deep neural networks in speech recognition EURASIP Journal on Audio, Speech, and Music Processing 2015:2

DOI 10.1186/s13636-014-0047-0

[4] Arena, P. , Patané, L. , Termini, P.S. An insect brain computational model inspired by Drosophila melanogaster: Simulation results

The 2010 International Joint Conference on Neural Networks (IJCNN) DOI: 10.1109/IJCNN.2010.5596513

[5] Sharma V,A. Understanding Activation Functions in Neural Networks (2017)

https://medium.com/the-theory-of-everything/understanding-activation-functions-in-neural-networks-9491262884e0

[6] Srivastava, N. et al. (2014). Dropout: A Simple Way to Prevent Neural Networks from Overfitting

Journal of Machine Learning Research 15 (2014) 1929-1958

http://jmlr.org/papers/volume15/srivastava14a.old/srivastava14a.pdf

[7] Intel MovidiusR TM Neural Compute Stick (Hämtad 180526)

https://developer.movidius.com/

[8] Installing TensorFlow on Ubuntu (2018)

https://www.tensorflow.org/install/install_linux#InstallingVirtualenv

[9] TFLearn - Quick Start

http://tflearn.org/tutorials/quickstart.html

[10] Intel MovidiusR TM NCS Quick Start (Hämtad 180527)

https://developer.movidius.com/start

[11] Intel MovidiusR TM Neural Compute SDK (2018)

https://movidius.github.io/ncsdk/tools/compile.html

[12] Research at Google (2017) Launching the Speech Commands Dataset

(20)

[13] Geitgey, A. (2016) Machine Learning is Fun Part 6: How to do Speech Recognition with Deep Learning

https://medium.com/@ageitgey/machine-learning-is-fun-part-6-how-to-do-speech-recognitionwith-deep-learning-28293c162f7a

[14] Doukkali, F. (2017) Batch normalization in Neural Networks

https://towardsdatascience.com/batch-normalization-in-neural-networks-1ac91516821c

[15] Sainath, T.N., Parada, C. (2015) Convolutional Neural Networks for Small-footprint Keyword Spotting

Interspeech 2015

(21)

A

DNNexample

build_graph.py 1 # Python 3 . 5 # S t e f a n Vidmark 3 i m p o r t numpy a s np 5 i m p o r t t f l e a r n i m p o r t t e n s o r f l o w a s t f 7

# Golomb−R i c e unä r k o d n i n g med padding , 0−9

9 # F a c i t ä r en 1 : a på motsvarande i n d e x som d e t kodade t a l e t

# Kodning ex : S i f f r a n 3 b l i r [ 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ]

11# F a c i t ex : [ 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] b l i r t i l l [ 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ]

# I n p u t : Ön s k a t a n t a l t a l som s k a s lu mp as fram och k o d a s

13# Output : De kodade t a l e n samt motsvarande f a c i t

d e f e n c o d e r ( no_numbers ) : 15 v a l = np . random . r a n d i n t ( 0 , 1 0 , [ no_numbers , 1 ] ) d a t a = np . z e r o s ( ( no_numbers , 1 0 ) ) 17 f a c i t = np . z e r o s ( ( no_numbers , 1 0 ) ) 19 f o r x i n r a n g e( no_numbers ) : d a t a [ x ] = np . c o n c a t e n a t e ( ( np . o n e s ( v a l [ x ] ) , np . z e r o s ( 1 0 − v a l [ x ] ) ) ) 21 f a c i t [ x , v a l [ x ] ] = 1 r e t u r n data , f a c i t 23 ########################################### 25 # G e n e r e r a d a t a och f a c i t 27 data , f a c i t = e n c o d e r ( 1 0 0 0 0 ) 29# Nä t v e r k s l a g e r

i n p u t _ l a y e r = t f l e a r n . inp ut_d ata ( s h a p e =[None , 1 0 ] , name=’ i n p u t ’)

31 h l a y e r 1 = t f l e a r n . f u l l y _ c o n n e c t e d ( i n p u t _ l a y e r , 4 0 , a c t i v a t i o n=’ s i g m o i d ’, name =" h l a y e r 1 ") o u t p u t _ l a y e r = t f l e a r n . f u l l y _ c o n n e c t e d ( h l a y e r 1 , 1 0 , a c t i v a t i o n=’ s o f t m a x ’, name=’ o u t p u t ’) 33 n e t = t f l e a r n . r e g r e s s i o n ( o u t p u t _ l a y e r ) 35# M o d e l l model = t f l e a r n .DNN( net , t e n s o r b o a r d _ v e r b o s e =0) 37 #Trä n i n g

39 model . f i t ( data , f a c i t , n_epoch =10 , v a l i d a t i o n _ s e t = 0 . 3 , s h u f f l e=True ,

show_metric=True )

41# Spara den t r ä nade m o d e l l e n

s a v e r = t f . t r a i n . S a v e r ( t f . g l o b a l _ v a r i a b l e s ( ) )

43 s a v e r . s a v e ( model . s e s s i o n , " . / o u t p u t / graph_model ")

# Nedanst å ende g e r en l ä s b a r b e s k r i v n i n g av nä t v e r k e t , med namnet på a l l a n o d e r

(22)

prep_graph.py # Python 3 . 5 2 # S t e f a n Vidmark 4 # S p a r a r om nä t v e r k e t f r ån b u i l d _ g r a p h . py f ö r a t t # t a b o r t t r ä n i n g s d a t a 6 i m p o r t t f l e a r n 8 i m p o r t t e n s o r f l o w a s t f 10 # Nä t v e r k s l a g e r

12 i n p u t _ l a y e r = t f l e a r n . inp ut_d ata ( s h a p e =[None , 1 0 ] , name=’ i n p u t ’)

h l a y e r 1 = t f l e a r n . f u l l y _ c o n n e c t e d ( i n p u t _ l a y e r , 4 0 , a c t i v a t i o n=’ s i g m o i d ’, name =" h l a y e r 1 ") 14 o u t p u t _ l a y e r = t f l e a r n . f u l l y _ c o n n e c t e d ( h l a y e r 1 , 1 0 , a c t i v a t i o n=’ s o f t m a x ’, name=’ o u t p u t ’) 16# M o d e l l model = t f l e a r n .DNN( o u t p u t _ l a y e r ) 18 # Ladda nä t v e r k s v i k t e r f r ån s p a r a d m o d e l l

20 model . l o a d (’ . / o u t p u t / graph_model ’, w e i g h t s _ o n l y=True )

22# Spara

s a v e r = t f . t r a i n . S a v e r ( t f . g l o b a l _ v a r i a b l e s ( ) )

24 s a v e r . s a v e ( model . s e s s i o n , ’ . / o u t p u t / g r a p h _ i n f e r e n c e ’)

# Nedanst å ende g e r en l ä s b a r b e s k r i v n i n g av nä t v e r k e t , med namnet på a l l a n o d e r

26#t f . t r a i n . w r i t e _ g r a p h ( model . s e s s i o n . graph , ’ . / o u t p u t / ’ , ’ g r a p h _ i n f e r e n c e .

(23)

runNCS.py 1 # Python 3 . 5 # NCSDK 2 . 0 4 / NCAPI v2 3 # S t e f a n Vidmark 5 # T e s t a r d e t t r ä nade nä t v e r k e t genom a t t kö r a i n s i f f r o r n a # 0 t i l l 9 7 9 from mvnc i m p o r t mvncapi a s n c s i m p o r t numpy a s np 11

# Golomb−R i c e unä r k o d n i n g med padding , 0−9

13# Kodning ex : S i f f r a n 3 b l i r [ 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ]

d e f int_to_coded ( number ) :

15 r e t u r n np . c o n c a t e n a t e ( ( np . o n e s ( number ) , np . z e r o s ( 1 0 − number ) ) ) 17# Golomb−R i c e unä r k o d n i n g med padding , 0−9

# F a c i t ä r en 1 : a på motsvarande i n d e x som d e t kodade t a l e t

19# Kodning ex : S i f f r a n 3 b l i r [ 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ]

# F a c i t ex : [ 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] b l i r t i l l [ 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ]

21# I n p u t : Ön s k a t a n t a l t a l som s k a s lu mp as fram och k o d a s

# Output : De kodade t a l e n samt motsvarande f a c i t

23 d e f e n c o d e r ( no_numbers ) : v a l = np . random . r a n d i n t ( 0 , 1 0 , [ no_numbers , 1 ] ) 25 d a t a = np . z e r o s ( ( no_numbers , 1 0 ) ) f a c i t = np . z e r o s ( ( no_numbers , 1 0 ) ) 27 f o r x i n r a n g e( no_numbers ) : 29 d a t a [ x ] = np . c o n c a t e n a t e ( ( np . o n e s ( v a l [ x ] ) , np . z e r o s ( 1 0 − v a l [ x ] ) ) ) f a c i t [ x , v a l [ x ] ] = 1 31 r e t u r n data , f a c i t 33############################################################ 35# Få ID på a l l a e n h e t e r deviceName = n c s . e n u m e r a t e _ d e v i c e s ( ) 37 i f l e n( deviceName ) == 0 : p r i n t("No d e v i c e d e t e c t e d , q u i t t i n g ") 39 q u i t ( )

41# I n i t i a l i s e r a och ö ppna d e v i c e −o b j e k t

p r i n t(" I n i t : ", end=’ ’) 43 d e v i c e = n c s . D e v i c e ( deviceName [ 0 ] ) p r i n t("CHECK\n") 45 p r i n t("Open : ", end=’ ’) d e v i c e .open( ) 47 p r i n t("CHECK\n")

49# Öppna graph− f i l och l ä s i n t i l l d e v i c e

p r i n t(" A l l o c a t e : ", end=’ ’)

51 w i t h open(’ . / o u t p u t / graph_comp2 . graph ’, mode=’ rb ’) a s f :

(24)

53 graph = n c s . Graph (’ ’)

f i f o _ i n , f i f o _ o u t = graph . a l l o c a t e _ w i t h _ f i f o s ( d e v i c e , g r a p h f i l e )

55 p r i n t("CHECK\n")

57# Ladda i n d a t a och hämta r e s u l t a t

p r i n t(" I n f e r e n c e : ")

59 p r i n t(" ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ")

f o r i i n r a n g e( 1 0 ) :

61 d a t a = int_to_coded ( i ) . a s t y p e ( d t y p e=np . f l o a t 3 2 )

graph . q u e u e _ i n f e r e n c e _ w i t h _ f i f o _ e l e m ( f i f o _ i n , f i f o _ o u t , data , None )

(25)

B

DNNspeech

samplelib_process.py # Python 3 . 5 2 # S t e f a n Vidmark 4 # P r o c e s s a r s a m p l i n g s b i b l i o t e k e t Speech Commands D a t a s e t # download . t e n s o r f l o w . o r g / d a t a / speech_commands_v0 . 0 1 . t a r . gz 6 # N o r m a l i s e r a r , f l y t t a r o r d e t t i l l bö r j a n av f i l e n , g ö r FFT i 20 ms−d e l a r

# och s p a r a r som numpy a r r a y

8 i m p o r t wave 10 i m p o r t o s i m p o r t t i m e 12 i m p o r t random i m p o r t numpy a s np 14 from numpy i m p o r t f f t 16 #N o r m a l i s e r a r f ö r motsvarande 16 b i t s s i g n e d i n t 18 d e f n o r m a l i z e ( d a t a ) : max_value = 0 20 f o r i i n r a n g e(l e n( d a t a ) ) : i f a b s( d a t a [ i ] ) > max_value : 22 max_value = a b s( d a t a [ i ] ) c o e f f = i n t( 3 2 7 6 7 / max_value ) 24 i f c o e f f < 1 : c o e f f = 1 26 r e t u r n [ i ∗ c o e f f f o r i i n d a t a ] 28 # K o n v e r t e r a r b y t e f o r m a t t i l l en l i s t a med i n t 30# Utg å r f r ån 16 b i t s l j u d # Fö r l ä n g e r t i l l 16000 s a m p l e s om k l i p p e t ä r k o r t a r e 32 d e f byte_to_int ( params , a u d i o d a t a ) : a u d i o d a t a _ i n t = [ None ] ∗i n t( params . n f r a m e s ) 34 f o r i i n r a n g e( 0 , l e n( a u d i o d a t a ) , 2 ) : a u d i o d a t a _ i n t [i n t( i / 2 ) ] = i n t. from_bytes ( a u d i o d a t a [ i : i + 2 ] , 36 b y t e o r d e r=’ l i t t l e ’, s i g n e d=True ) i f params . n f r a m e s < 1 6 0 0 0 : 38 avg = i n t(sum(a b s( i ) f o r i i n a u d i o d a t a _ i n t [ 0 : 3 0 0 ] ) / 3 0 0 ) p a d d i n g = [ None ] ∗i n t(16000 − params . n f r a m e s ) 40 f o r i i n r a n g e(l e n( p a d d i n g ) ) :

p a d d i n g [ i ] = random . r a n d i n t (−avg , avg )

42 a u d i o d a t a _ i n t . e x t e n d ( p a d d i n g ) r e t u r n a u d i o d a t a _ i n t 44 # R e t u r n e r a r metadata och PCM−d a t a 46# PCM−d a t a t ä r i byte−f o r m a t d e f e x t r a c t _ d a t a ( path , f i l e n a m e ) :

48 a f i l e = wave .open( path + f i l e n a m e , mode=’ rb ’)

(26)

50 metadata = a f i l e . g e t p a r a m s ( ) a f i l e . c l o s e ( ) 52 r e t u r n metadata , PCM 54# Skapa en ny byte−a r r a y f ö r s k r i v n i n g # Utg å r f r ån 16 b i t s l j u d 56 d e f int_to_byte ( a u d i o d a t a ) : a u d i o d a t a _ p r o c e s s e d = b y t e a r r a y(i n t( 2 ∗l e n( a u d i o d a t a ) ) ) 58 f o r i i n r a n g e(l e n( a u d i o d a t a ) ) : a u d i o d a t a _ p r o c e s s e d [i n t( i ∗ 2 ) : ] = ( ( a u d i o d a t a [ i ] ) . t o _ b y t e s ( 2 , b y t e o r d e r= ’ l i t t l e ’, s i g n e d=True ) ) [ : ] 60 r e t u r n a u d i o d a t a _ p r o c e s s e d 62# F l y t t a r t a l e t nä rmare bö r j a n av f i l e n # Fö r u t s ä t t e r n o r m a l i s e r a t l j u d 64 d e f r e p o s i t i o n ( a u d i o d a t a ) : i n d e x = 0 66 f o r i i n r a n g e(l e n( a u d i o d a t a ) ) : i f a b s( a u d i o d a t a [ i ] ) > 6 0 0 0 : 68 i n d e x = i b r e a k 70 r e t u r n a u d i o d a t a [ i n d e x : : ] + a u d i o d a t a [ 0 : i n d e x ] 72# F u n k t i o n t a g e n f r ån h t t p s : / / s t a c k o v e r f l o w . com/ q u e s t i o n s / 4 6 0 1 3 7 3 / b e t t e r −

way−to−s h u f f l e −two−numpy−a r r a y s −i n −u n i s o n

d e f r a n d o m i z e _ o r d e r ( a ) : 74 p = np . random . p e r m u t a t i o n (l e n( a ) ) r e t u r n a [ p ] 76 ######################################################### 78 N = 320 80 Fs = 16000 s c a l e f a c t o r = N/ Fs 82 PATH = ’ . / s a m p l e s / ’

84 WORDLIST = [’ y e s ’, ’ no ’,’ r i g h t ’, ’ l e f t ’,’ up ’, ’ down ’, ’ z e r o ’,’ one ’,’ two ’,

’ t h r e e ’ ,’ f o u r ’, ’ f i v e ’ ,’ s i x ’ ,’ s e v e n ’]

86 f o r name i n WORDLIST:

i f o s . path . i s d i r (PATH+name ) == F a l s e :

88 WORDLIST. remove ( name )

(27)

100 f o r i i n r a n g e( n o _ f i l e s ) : params , d a t a = e x t r a c t _ d a t a (PATH+word+’ / ’, f i l e l i s t [ i ] ) 102 d a t a = r e p o s i t i o n ( n o r m a l i z e ( byte_to_int ( params , d a t a ) ) ) 104 f o r j i n r a n g e( 5 0 ) : a r r [ i , j , : ] = np . a b s o l u t e ( f f t . f f t ( d a t a [i n t( j ∗N) :i n t(N∗ ( j +1) ) ] ) [ 0 : 1 6 0 ] ) ∗ s c a l e f a c t o r 106 i f ( i % 2 0 0 ) == 0 : p r i n t("%d o f %d" % ( i , n o _ f i l e s ) ) 108 a r r = r a n d o m i z e _ o r d e r ( a r r ) 110 t e s t _ i n d e x = i n t(l e n( a r r ) ∗ 0 . 9 )

np . s a v e (’ . / t r a i n _ d a t a / ’ + word + ’ _FFT_training . npy ’, a r r [ 0 : t e s t _ i n d e x ] .

a s t y p e ( d t y p e=np . f l o a t 3 2 ) )

112 np . s a v e (’ . / t r a i n _ d a t a / ’ + word + ’ _FFT_test . npy ’, a r r [ t e s t _ i n d e x : ] . a s t y p e (

d t y p e=np . f l o a t 3 2 ) )

114 t 2 = t i m e . t i m e ( )

p r i n t("DONE")

116 t_min = i n t( ( t2−t 1 ) / 6 0 )

t _ s e c = i n t( ( t2−t 1 ) % 6 0 )

(28)

training.py 1 # Python 3 . 5

# S t e f a n Vidmark

3 # Trä n a r e t t n e u r a l t nä t v e r k med o r d e n som a n g e s i w o r d l i s t

# S p a r a r w o r d l i s t , som anv ä nds av e f t e r f ö l j a n d e program

5 i m p o r t numpy a s np 7 i m p o r t t f l e a r n i m p o r t t e n s o r f l o w a s t f 9 i m p o r t t i m e 11# F u n k t i o n t a g e n f r ån h t t p s : / / s t a c k o v e r f l o w . com/ q u e s t i o n s / 4 6 0 1 3 7 3 / b e t t e r −

way−to−s h u f f l e −two−numpy−a r r a y s −i n −u n i s o n

d e f r a n d o m i z e _ o r d e r 2 ( a , b ) :

13 p = np . random . p e r m u t a t i o n (l e n( a ) )

r e t u r n a [ p ] , b [ p ]

15

# Skapar en d i c t med w o r d l i s t som key , dä r v a l u e ä r

17# en a r r a y med 0 : o r och en 1 : a på motsvarande i n d e x som o r d e t

d e f c r e a t e D i c t ( w o r d l i s t ) : 19 d = {} f o r i i n r a n g e(l e n( w o r d l i s t ) ) : 21 v a l u e = np . z e r o s (l e n( w o r d l i s t ) ) . a s t y p e ( d t y p e=np . f l o a t 3 2 ) v a l u e [ i ] = 1 23 d [ w o r d l i s t [ i ] ] = v a l u e r e t u r n d 25 # D e f i n i e r a o r d e n som nä t v e r k e t s k a t r ä na , s p a r a l i s t a n

27# och den d i c t som i n n e h å l l e r l a b e l s

w o r d l i s t = [’ y e s ’, ’ no ’,’ r i g h t ’, ’ l e f t ’,’ up ’, ’ down ’, ’ z e r o ’,’ one ’,’ two ’,

’ t h r e e ’ ,’ f o u r ’, ’ f i v e ’ ,’ s i x ’ ,’ s e v e n ’] 29 PATH = ’ . / t r a i n _ d a t a / ’ l a b e l D i c t = c r e a t e D i c t ( w o r d l i s t ) 31 w i t h open(’ w o r d l i s t . t x t ’,’w ’) a s f : 33 f . w r i t e (s t r( w o r d l i s t ) ) 35 # Ladda i n t r ä n i n g s d a t a och s k a p a l a b e l s

37 d a t a = np . l o a d (PATH + w o r d l i s t [ 0 ] +’ _FFT_training . npy ’)

l a b e l s = np . t i l e ( l a b e l D i c t [ w o r d l i s t [ 0 ] ] , (l e n( d a t a ) , 1 ) )

39

f o r i i n r a n g e( 1 ,l e n( w o r d l i s t ) ) :

41 newdata = np . l o a d (PATH + w o r d l i s t [ i ] +’ _FFT_training . npy ’)

d a t a = np . append ( data , newdata , a x i s =0)

(29)

51 n e t = t f l e a r n . i nput _dat a ( s h a p e =[None , 5 0 , 1 6 0 ] , name=’ i n p u t ’)

n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

53 n e t = t f l e a r n . d r o p o u t ( net , 0 . 9 )

n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

55 n e t = t f l e a r n . d r o p o u t ( net , 0 . 9 )

n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

57 n e t = t f l e a r n . d r o p o u t ( net , 0 . 9 )

n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

59 n e t = t f l e a r n . d r o p o u t ( net , 0 . 9 )

n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

61 n e t = t f l e a r n . d r o p o u t ( net , 0 . 9 ) n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,l e n( w o r d l i s t ) , a c t i v a t i o n=’ s o f t m a x ’, name= ’ o u t p u t ’) 63 n e t = t f l e a r n . r e g r e s s i o n ( n e t ) 65# M o d e l l model = t f l e a r n .DNN( net , t e n s o r b o a r d _ v e r b o s e =3) 67 #Trä n i n g 69 t 1 = t i m e . t i m e ( )

model . f i t ( data , l a b e l s , n_epoch =10 , v a l i d a t i o n _ s e t = 0 . 2 , s h u f f l e=True ,

show_metric=True ) 71 t 2 = t i m e . t i m e ( ) t_min = i n t( ( t2−t 1 ) / 6 0 ) 73 t _ s e c = i n t( ( t2−t 1 ) % 6 0 ) p r i n t(" T o t a l t i m e : %d min %d s e c " % ( t_min , t _ s e c ) ) 75

# Spara den t r ä nade m o d e l l e n

77 s a v e r = t f . t r a i n . S a v e r ( t f . g l o b a l _ v a r i a b l e s ( ) )

s a v e r . s a v e ( model . s e s s i o n , " . / o u t p u t / speech_model ")

79# Nedanst å ende g e r en l ä s b a r b e s k r i v n i n g av nä t v e r k e t , med namnet på a l l a

n o d e r

(30)

resave.py 1 # Python 3 . 5 # S t e f a n Vidmark 3 # S p a r a r om nä t v e r k e t utan t r ä n i n g s d a t a i n f ö r # k o m p i l e r i n g t i l l NCS 5 i m p o r t t f l e a r n 7 i m p o r t t e n s o r f l o w a s t f i m p o r t numpy a s np 9 # Ladda o r d l i s t a n f r ån t r ä n i n g e n 11 w i t h open(’ w o r d l i s t . t x t ’,’ r ’) a s f : w o r d l i s t = e v a l( f . r e a d ( ) ) 13 NODES = 128 15 # Nä t v e r k s l a g e r

17 n e t = t f l e a r n . i nput _dat a ( s h a p e =[None , 5 0 , 1 6 0 ] , name=’ i n p u t ’)

n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

19 n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

21 n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

23 n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,l e n( w o r d l i s t ) , a c t i v a t i o n=’ s o f t m a x ’, name= ’ o u t p u t ’) 25# M o d e l l model = t f l e a r n .DNN( net , t e n s o r b o a r d _ v e r b o s e =0) 27 # Ladda nä t v e r k s v i k t e r f r ån s p a r a d m o d e l l

29 model . l o a d (’ . / o u t p u t / speech_model ’, w e i g h t s _ o n l y=True )

31# Spara

s a v e r = t f . t r a i n . S a v e r ( t f . g l o b a l _ v a r i a b l e s ( ) )

33 s a v e r . s a v e ( model . s e s s i o n , ’ . / o u t p u t / s p e e c h _ i n f e r e n c e ’)

# Nedanst å ende g e r en l ä s b a r b e s k r i v n i n g av nä t v e r k e t , med namnet på a l l a n o d e r

35 t f . t r a i n . w r i t e _ g r a p h ( model . s e s s i o n . graph , ’ . / o u t p u t / ’, ’ g r a p h _ i n f e r e n c e .

(31)

validation.py

# Python 3 . 5

2 # S t e f a n Vidmark

# Mä t e r t i d och t r ä f f s ä k e r h e t h o s d e t t r ä nade nä t v e r k e t

4 # Anvä n d e r t e s t −s e t e t , som e j anv ä n t s v i d t r ä n i n g e n

6 i m p o r t t f l e a r n from mvnc i m p o r t mvncapi a s n c s 8 i m p o r t numpy a s np i m p o r t t i m e 10 NCS = 1 12 TFLEARN = 1 SINGLE = 1 #Lä g g e r i n e t t v ä r d e å t g å ngen 14 MULTI = 1 #Lä g g e r a l l d a t a på en g å ng 16# J ämfö r i n d e x f ö r d e t hö g s t a t a l e t , # r e t u r n e r a r a n t a l r ä t t i p r o c e n t 18 d e f c h e c k R e s u l t ( l a b e l s , o u t p u t ) : e q u a l = 0 20 f o r i i n r a n g e(l e n( l a b e l s ) ) : i f np . argmax ( l a b e l s [ i , : ] ) == np . argmax ( o u t p u t [ i , : ] ) : 22 e q u a l = e q u a l +1 r e t u r n e q u a l /l e n( l a b e l s ) 24 d e f timeConv ( t _ s t a r t , t_stop ) : 26 t_min = i n t( ( t_stop−t _ s t a r t ) / 6 0 ) t _ s e c = i n t( ( t_stop−t _ s t a r t ) % 6 0 ) 28 r e t u r n t_min , t _ s e c

30# Skapar en d i c t med w o r d l i s t som key , dä r v a l u e ä r

# en a r r a y med 0 : o r och en 1 : a på motsvarande i n d e x som o r d e t

32 d e f c r e a t e D i c t ( w o r d l i s t ) : d = {} 34 f o r i i n r a n g e(l e n( w o r d l i s t ) ) : v a l u e = np . z e r o s (l e n( w o r d l i s t ) ) . a s t y p e ( d t y p e=np . f l o a t 3 2 ) 36 v a l u e [ i ] = 1 d [ w o r d l i s t [ i ] ] = v a l u e 38 r e t u r n d ############################################################### 40 # Ladda o r d l i s t a n f r ån t r ä n i n g e n 42 w i t h open(’ w o r d l i s t . t x t ’,’ r ’) a s f : w o r d l i s t = e v a l( f . r e a d ( ) ) 44 l a b e l D i c t = c r e a t e D i c t ( w o r d l i s t ) 46 # Ladda i n t e s t d a t a 48 PATH = ’ . / t r a i n _ d a t a / ’

d a t a = np . l o a d (PATH + w o r d l i s t [ 0 ] +’ _FFT_test . npy ’)

50 l a b e l s = np . t i l e ( l a b e l D i c t [ w o r d l i s t [ 0 ] ] , (l e n( d a t a ) , 1 ) )

(32)

newdata = np . l o a d (PATH + w o r d l i s t [ i ] +’ _FFT_test . npy ’)

54 d a t a = np . append ( data , newdata , a x i s =0)

n e w l a b e l = np . t i l e ( l a b e l D i c t [ w o r d l i s t [ i ] ] , (l e n( newdata ) , 1 ) ) 56 l a b e l s = np . append ( l a b e l s , n e w l a b e l , a x i s =0) 58 d a t a = d a t a . a s t y p e ( d t y p e=np . f l o a t 3 2 ) # NCS h a r f l o a t 3 2 som s t a n d a r d k o n f i g u r a t i o n ############## TFLEARN ################## 60 i f TFLEARN != 0 : 62 NODES = 128 64 # Nä t v e r k s l a g e r

n e t = t f l e a r n . i nput _data ( s h a p e =[None , 5 0 , 1 6 0 ] , name=’ i n p u t ’)

66 n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

68 n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

70 n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,NODES, a c t i v a t i o n=’ ReLu ’)

n e t = t f l e a r n . f u l l y _ c o n n e c t e d ( net ,l e n( w o r d l i s t ) , a c t i v a t i o n=’ s o f t m a x ’, name=’ o u t p u t ’) 72 # M o d e l l 74 model = t f l e a r n .DNN( net , t e n s o r b o a r d _ v e r b o s e =0) 76 # Ladda nä t v e r k s v i k t e r f r ån s p a r a d m o d e l l model . l o a d (’ . / o u t p u t / s p e e c h _ i n f e r e n c e ’, w e i g h t s _ o n l y=True ) 78 i f SINGLE == 1 : 80 r e s u l t = np . z e r o s ( (l e n( d a t a ) ,l e n( l a b e l s [ 0 , : ] ) ) , d t y p e=np . f l o a t 1 6 ) p r i n t(" \n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ TFLearn I n f e r e n c e s i n g l e s ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ") 82 p r i n t(" S t a r t i n g : ") 84 t 1 = t i m e . t i m e ( ) f o r i i n r a n g e(l e n( d a t a ) ) :

86 temp = model . p r e d i c t ( [ d a t a [ i , : ] ] ) # Klamrar f ö r a t t f å r ä t t f o r m a t

r e s u l t [ i , : ] = temp 88 t 2 = t i m e . t i m e ( ) p r i n t("Done \n") 90 p r i n t(" Accuracy %f : " % ( c h e c k R e s u l t ( l a b e l s , r e s u l t ) ) ) 92 t_min , t _ s e c = timeConv ( t1 , t 2 )

p r i n t("Time : %d min %d s e c " % ( t_min , t _ s e c ) )

(33)

104 p r i n t("Done \n")

106 p r i n t(" Accuracy %f : " % ( c h e c k R e s u l t ( l a b e l s , r e s u l t ) ) )

t_min , t _ s e c = timeConv ( t1 , t 2 )

108 p r i n t("Time : %d min %d s e c " % ( t_min , t _ s e c ) ) 110 112 ############## NCS ##################### i f NCS != 0 : 114 r e s u l t = np . z e r o s ( (l e n( d a t a ) ,l e n( l a b e l s [ 0 , : ] ) ) , d t y p e=np . f l o a t 1 6 ) p r i n t(" \n ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ MNCS I n f e r e n c e ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ") 116 # Få ID på a l l a e n h e t e r 118 deviceName = n c s . e n u m e r a t e _ d e v i c e s ( ) i f l e n( deviceName ) == 0 : 120 p r i n t("No d e v i c e d e t e c t e d , q u i t t i n g ") q u i t ( ) 122

# I n i t i a l i s e r a och ö ppna d e v i c e −o b j e k t

124 d e v i c e = n c s . D e v i c e ( deviceName [ 0 ] )

d e v i c e .open( )

126

128 # Öppna graph− f i l och l ä s i n t i l l d e v i c e

w i t h open(’ . / o u t p u t / s p e e c h . graph ’, mode=’ rb ’) a s f :

130 g r a p h f i l e = f . r e a d ( )

graph = n c s . Graph (’ ’)

132 f i f o _ i n , f i f o _ o u t = graph . a l l o c a t e _ w i t h _ f i f o s ( d e v i c e , g r a p h f i l e )

134 # Ladda i n d a t a och hämta r e s u l t a t

p r i n t(" S t a r t i n g : ") 136 t 1 = t i m e . t i m e ( ) f o r i i n r a n g e(l e n( d a t a ) ) : 138 graph . q u e u e _ i n f e r e n c e _ w i t h _ f i f o _ e l e m ( f i f o _ i n , f i f o _ o u t , d a t a [ i , : ] , None ) r e s u l t [ i , : ] , u s e r o b j = f i f o _ o u t . read_elem ( ) 140 t 2 = t i m e . t i m e ( ) p r i n t("Done \n") 142 p r i n t(" Accuracy %f : " % ( c h e c k R e s u l t ( l a b e l s , r e s u l t ) ) ) 144 t_min , t _ s e c = timeConv ( t1 , t 2 )

p r i n t("Time : %d min %d s e c " % ( t_min , t _ s e c ) )

(34)

mic_inference.py

# Python 3 . 5

2 # NCSDK 2 . 0 4 / NCAPI v2

# S t e f a n Vidmark

4

# Lå t e r anv ä ndaren l ä s a i n o r d i en m i k r o f o n som NCS

6 # a n a l y s e r a r och s k r i v e r ut s v a r 8 from mvnc i m p o r t mvncapi a s n c s i m p o r t numpy a s np 10 i m p o r t s u b p r o c e s s from numpy i m p o r t f f t 12 i m p o r t wave i m p o r t w a r n i n g s 14 w a r n i n g s . f i l t e r w a r n i n g s (" i g n o r e ", c a t e g o r y=D e p r e c a t i o n W a r n i n g ) #Tar b o r t v a r n i n g a r som o r s a k a s a s NCAPI 16 #N o r m a l i s e r a r f ö r motsvarande 16 b i t s s i g n e d i n t 18 d e f n o r m a l i z e ( d a t a ) : max_value = 0 20 f o r i i n r a n g e(l e n( d a t a ) ) : i f a b s( d a t a [ i ] ) > max_value : 22 max_value = a b s( d a t a [ i ] ) c o e f f = i n t( 3 2 7 6 7 / max_value ) 24 i f c o e f f < 1 : c o e f f = 1 26 r e t u r n [ i ∗ c o e f f f o r i i n d a t a ] 28 # K o n v e r t e r a r b y t e f o r m a t t i l l en l i s t a med i n t 30# Utg å r f r ån 16 b i t s l j u d # Fö r l ä n g e r t i l l 16000 s a m p l e s om k l i p p e t ä r k o r t a r e 32 d e f byte_to_int ( params , a u d i o d a t a ) : a u d i o d a t a _ i n t = [ None ] ∗i n t( params . n f r a m e s ) 34 f o r i i n r a n g e( 0 , l e n( a u d i o d a t a ) , 2 ) : a u d i o d a t a _ i n t [i n t( i / 2 ) ] = i n t. from_bytes ( a u d i o d a t a [ i : i + 2 ] , 36 b y t e o r d e r=’ l i t t l e ’, s i g n e d=True ) i f params . n f r a m e s < 1 6 0 0 0 : 38 avg = i n t(sum(a b s( i ) f o r i i n a u d i o d a t a _ i n t [ 0 : 3 0 0 ] ) / 3 0 0 ) p a d d i n g = [ None ] ∗i n t(16000 − params . n f r a m e s ) 40 f o r i i n r a n g e(l e n( p a d d i n g ) ) :

p a d d i n g [ i ] = random . r a n d i n t (−avg , avg )

42 a u d i o d a t a _ i n t . e x t e n d ( p a d d i n g )

r e t u r n a u d i o d a t a _ i n t [ 0 : 1 6 0 0 0 ]

44

d e f e x t r a c t _ d a t a ( path , f i l e n a m e ) :

46 a f i l e = wave .open( path + f i l e n a m e , mode=’ rb ’)

a u d i o d a t a = a f i l e . r e a d f r a m e s ( a f i l e . g e t n f r a m e s ( ) ) #Få s i byte−f o r m a t

48 metadata = a f i l e . g e t p a r a m s ( )

a f i l e . c l o s e ( )

(35)

52# F l y t t a r t a l e t nä rmare bö r j a n av f i l e n # Fö r u t s ä t t e r n o r m a l i s e r a t l j u d 54 d e f r e p o s i t i o n ( a u d i o d a t a ) : i n d e x = 0 56 f o r i i n r a n g e(l e n( a u d i o d a t a ) ) : i f a b s( a u d i o d a t a [ i ] ) > 6 0 0 0 : 58 i n d e x = i b r e a k 60 r e t u r n a u d i o d a t a [ i n d e x : : ] + a u d i o d a t a [ 0 : i n d e x ] 62# Skapar en d i c t med w o r d l i s t som key , dä r v a l u e ä r

# en a r r a y med 0 : o r och en 1 : a på motsvarande i n d e x som o r d e t

64 d e f c r e a t e D i c t ( w o r d l i s t ) : d = {} 66 f o r i i n r a n g e(l e n( w o r d l i s t ) ) : v a l u e = np . z e r o s (l e n( w o r d l i s t ) ) . a s t y p e ( d t y p e=np . f l o a t 3 2 ) 68 v a l u e [ i ] = 1 d [ w o r d l i s t [ i ] ] = v a l u e 70 r e t u r n d ########################################################## 72 FFT_COEFF = 0 . 0 2 74

FILENAME = "temp . wav"

76# S i f f r o r n a i plughw : X, Y b e r o r på v i l k e n mick som anv ä nds

# K o l l a med a r e c o r d − l

78 ARGS = [" a r e c o r d −d 1 −D plughw : 2 , 0 − f S16_LE −c1 −r 16000 " + FILENAME ]

80# Ladda o r d l i s t a n f r ån t r ä n i n g e n w i t h open(’ w o r d l i s t . t x t ’,’ r ’) a s f : 82 w o r d l i s t = e v a l( f . r e a d ( ) ) l a b e l D i c t = c r e a t e D i c t ( w o r d l i s t ) 84 # Få ID på a l l a e n h e t e r 86 deviceName = n c s . e n u m e r a t e _ d e v i c e s ( ) i f l e n( deviceName ) == 0 : 88 p r i n t("No d e v i c e d e t e c t e d , q u i t t i n g ") q u i t ( ) 90

# I n i t i a l i s e r a och ö ppna d e v i c e −o b j e k t

92 d e v i c e = n c s . D e v i c e ( deviceName [ 0 ] )

d e v i c e .open( )

94

# Öppna graph− f i l och l ä s i n t i l l d e v i c e

96 w i t h open(’ . / o u t p u t / s p e e c h . graph ’, mode=’ rb ’) a s f :

(36)

References

Related documents

Operationssjuksköterskor och annan personal till exempel operatörer som arbetar med operationssjukvård har en hög risk att utsättas för stick- och skärskador och exponering av

Figure 18: Graph showing the execution time per dataset as a function of number of datasets when the network is a 4 layered network with 128 neurons in each layer.

This report will focus on finding out the differences in performance between deferred shading implemented on DirectX 10 and DirectX 11 based hardware, using the

The accelerometer and the gyroscope were used to measure the angle and the angular velocity of the system, and the the Hall effect sensors were used to measure the angular velocity

In this chapter results are presented for the measurements of the density volume generation time with compute shaders, the mesh generation time with the Marching cubes implementation

Händelseförlopp (ange den utrustning du använde som typ av kanyl, instrument

A growing empirical literature suggest that price increases relative to a reference price, dened as what the consumer is used to pay for the good, have more eect on demand

Två Africa Forum, ett i Mali förra året och ett i Etiopien år, ledde vidare till ett Zimbabwe Social Forum i oktober samt ett regionalt, Southern Africa Social Forum i november