OpenVINO hackathon: rikonoxximent tal-vuċi u l-emozzjonijiet fuq Raspberry Pi
30 Novembru - 1 Diċembru f'Nizhny Novgorod saret Hackathon OpenVINO. Il-parteċipanti ntalbu joħolqu prototip ta' soluzzjoni ta' prodott bl-użu tal-għodda Intel OpenVINO. L-organizzaturi pproponew lista ta’ suġġetti approssimattivi li jistgħu jiġu ggwidati minn meta jintgħażel kompitu, iżda d-deċiżjoni finali baqgħet f’idejn it-timijiet. Barra minn hekk, ġie mħeġġeġ l-użu ta’ mudelli li mhumiex inklużi fil-prodott.
F'dan l-artikolu ser ngħidulek dwar kif ħloqna l-prototip tagħna tal-prodott, li bih eventwalment ħadna l-ewwel post.
Aktar minn 10 timijiet ipparteċipaw fil-hackathon. Huwa sabiħ li xi wħud minnhom ġew minn reġjuni oħra. Il-post għall-hackathon kien il-kumpless "Kremlinsky on Pochain", fejn ritratti antiki ta 'Nizhny Novgorod kienu mdendlin ġewwa, f'madwaru! (Infakkarkom li bħalissa l-uffiċċju ċentrali ta 'Intel jinsab f'Nizhny Novgorod). Il-parteċipanti ngħataw 26 siegħa biex jiktbu l-kodiċi, u fl-aħħar kellhom jippreżentaw is-soluzzjoni tagħhom. Vantaġġ separat kien il-preżenza ta 'sessjoni demo biex jiġi żgurat li dak kollu ppjanat kien attwalment implimentat u ma jibqax ideat fil-preżentazzjoni. Merch, snacks, ikel, kollox kien hemm ukoll!
Barra minn hekk, Intel ipprovda b'mod fakultattiv kameras, Raspberry PI, Neural Compute Stick 2.
Għażla tal-kompitu
Waħda mill-aktar partijiet diffiċli tal-preparazzjoni għal hackathon b'forma ħielsa hija l-għażla ta 'sfida. Immedjatament iddeċidejna li noħorġu b'xi ħaġa li għadha ma kinitx fil-prodott, peress li t-tħabbira qalet li din kienet milqugħa ħafna.
Wara li analizzat mudelli, li huma inklużi fil-prodott fir-rilaxx attwali, naslu għall-konklużjoni li ħafna minnhom isolvu diversi problemi ta 'viżjoni tal-kompjuter. Barra minn hekk, huwa diffiċli ħafna li toħroġ bi problema fil-qasam tal-viżjoni tal-kompjuter li ma tistax tiġi solvuta bl-użu ta 'OpenVINO, u anke jekk wieħed jista' jiġi ivvintat, huwa diffiċli li ssib mudelli mħarrġa minn qabel fid-dominju pubbliku. Aħna niddeċiedu li nħaffru f'direzzjoni oħra - lejn l-ipproċessar tad-diskors u l-analiżi. Ejja nikkunsidraw kompitu interessanti li nirrikonoxxu l-emozzjonijiet mid-diskors. Wieħed irid jgħid li OpenVINO diġà għandu mudell li jiddetermina l-emozzjonijiet ta’ persuna abbażi ta’ wiċċha, iżda:
Fit-teorija, huwa possibbli li jinħoloq algoritmu kombinat li jaħdem kemm fuq il-ħoss kif ukoll fuq l-immaġni, li għandu jagħti żieda fl-eżattezza.
Il-kameras normalment ikollhom angolu tal-vista dejjaq; aktar minn kamera waħda hija meħtieġa biex tkopri żona kbira; il-ħoss m'għandux tali limitazzjoni.
Ejja niżviluppaw l-idea: ejja nieħdu l-idea għas-segment tal-bejgħ bl-imnut bħala bażi. Tista 'tkejjel is-sodisfazzjon tal-klijent fil-checkouts tal-maħżen. Jekk wieħed mill-klijenti ma jkunx sodisfatt bis-servizz u jibda jgħolli t-ton tagħhom, tista' immedjatament iċempel lill-amministratur għall-għajnuna.
F'dan il-każ, irridu nżidu r-rikonoxximent tal-vuċi umana, dan jippermettilna niddistingwu l-impjegati tal-maħżen mill-klijenti u nipprovdu analitika għal kull individwu. Ukoll, barra minn hekk, se jkun possibbli li tanalizza l-imġieba tal-impjegati tal-maħżen infushom, tevalwa l-atmosfera fit-tim, tinstema tajjeb!
Bħala riżultat, aħna nagħżlu Raspberry Pi 3 c bħala l-apparat fil-mira Intel NCS 2.
Hawnhekk huwa importanti li wieħed jinnota karatteristika waħda importanti ta 'NCS - taħdem l-aħjar ma' arkitetturi CNN standard, imma jekk għandek bżonn tmexxi mudell b'saffi tad-dwana fuqha, imbagħad tistenna ottimizzazzjoni ta 'livell baxx.
Hemm ħaġa żgħira waħda biss x'tagħmel: għandek bżonn tikseb mikrofonu. Mikrofonu USB regolari se jagħmel, iżda mhux se jidher tajjeb flimkien ma 'l-RPI. Imma anke hawn is-soluzzjoni litteralment “tinsab fil-qrib.” Biex nirreġistra l-vuċi, aħna niddeċiedu li nużaw il-bord tal-Voice Bonnet mill-kit Google AIY Voice Kit, li fuqu hemm mikrofonu stereo bil-fili.
Niżżel Raspbian minn Repożitorju tal-proġetti AIY u ittellah fuq flash drive, ittestja li l-mikrofonu jaħdem billi tuża l-kmand li ġej (se jirreġistra l-awdjo tul 5 sekondi u ssejvjah f'fajl):
arecord -d 5 -r 16000 test.wav
Minnufih għandi ninnota li l-mikrofonu huwa sensittiv ħafna u jiġbor tajjeb l-istorbju. Biex tiffissa dan, ejja mur alsamixer, agħżel Qbid apparati u naqqas il-livell tas-sinjal tad-dħul għal 50-60%.
Aħna nimmodifikaw il-ġisem b'fajl u kollox joqgħod, tista 'saħansitra tagħlaqha b'għatu
Żieda ta 'buttuna indikatur
Filwaqt li nieħdu l-AIY Voice Kit barra, niftakru li hemm buttuna RGB, li d-dawl ta 'wara tagħha jista' jiġi kkontrollat minn softwer. Aħna nfittxu "Google AIY Led" u nsibu dokumentazzjoni: https://aiyprojects.readthedocs.io/en/latest/aiy.leds.html
Għaliex ma tużax din il-buttuna biex turi l-emozzjoni rikonoxxuta, għandna biss 7 klassijiet, u l-buttuna għandha 8 kuluri, biżżejjed!
Aħna nqabbdu l-buttuna permezz ta 'GPIO ma' Voice Bonnet, tagħbija l-libreriji meħtieġa (diġà huma installati fil-kit tad-distribuzzjoni minn proġetti AIY)
from aiy.leds import Leds, Color
from aiy.leds import RgbLeds
Ejja noħolqu dict li fih kull emozzjoni jkollha kulur korrispondenti fil-forma ta 'Tuppla RGB u oġġett tal-klassi aiy.leds.Leds, li permezz tiegħu se naġġornaw il-kulur:
Se nużaw pyaudio biex naqbdu n-nixxiegħa mill-mikrofonu u webrtcvad biex niffiltraw l-istorbju u niskopru l-vuċi. Barra minn hekk, se noħolqu kju li miegħu se nżidu u nneħħu siltiet tal-vuċi b'mod mhux sinkroniku.
Peress li webrtcvad għandu limitazzjoni fuq id-daqs tal-framment fornut - għandu jkun ugwali għal 10/20/30ms, u t-taħriġ tal-mudell għar-rikonoxximent tal-emozzjonijiet (kif ser nitgħallmu aktar tard) sar fuq dataset 48kHz, aħna se jaqbad biċċiet ta' daqs 48000×20ms/1000×1(mono)=960 bytes. Webrtcvad se jirritorna Veru/Falz għal kull wieħed minn dawn il-biċċiet, li jikkorrispondi għall-preżenza jew in-nuqqas ta 'vot fil-biċċa.
Ejja nimplimentaw il-loġika li ġejja:
Aħna nżidu mal-lista dawk il-biċċiet fejn hemm vot; jekk ma jkunx hemm vot, allura nżidu l-counter tal-biċċiet vojta.
Jekk il-counter ta 'biċċiet vojta huwa> = 30 (600 ms), allura nħarsu lejn id-daqs tal-lista ta' biċċiet akkumulati; jekk ikun> 250, allura nżiduh mal-kju; jekk le, nikkunsidraw li t-tul tar-rekord mhuwiex biżżejjed biex jitimgħu lill-mudell biex jidentifika l-kelliem.
Jekk il-counter ta 'biċċiet vojta għadu < 30, u d-daqs tal-lista ta' biċċiet akkumulati jaqbeż it-300, allura aħna se nżidu l-framment mal-kju għal tbassir aktar preċiż. (għax l-emozzjonijiet għandhom it-tendenza li jinbidlu maż-żmien)
def to_queue(frames):
d = np.frombuffer(b''.join(frames), dtype=np.int16)
return d
framesQueue = queue.Queue()
def framesThreadBody():
CHUNK = 960
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 48000
p = pyaudio.PyAudio()
vad = webrtcvad.Vad()
vad.set_mode(2)
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
false_counter = 0
audio_frame = []
while process:
data = stream.read(CHUNK)
if not vad.is_speech(data, RATE):
false_counter += 1
if false_counter >= 30:
if len(audio_frame) > 250:
framesQueue.put(to_queue(audio_frame,timestamp_start))
audio_frame = []
false_counter = 0
if vad.is_speech(data, RATE):
false_counter = 0
audio_frame.append(data)
if len(audio_frame) > 300:
framesQueue.put(to_queue(audio_frame,timestamp_start))
audio_frame = []
Wasal iż-żmien li tfittex mudelli mħarrġa minn qabel fid-dominju pubbliku, mur github, Google, imma ftakar li għandna limitazzjoni fuq l-arkitettura użata. Din hija parti pjuttost diffiċli, għax trid tittestja l-mudelli fuq id-dejta tal-input tiegħek, u barra minn hekk, tikkonvertihom għall-format intern ta 'OpenVINO - IR (Rappreżentanza Intermedja). Ippruvajna madwar 5-7 soluzzjonijiet differenti minn github, u jekk il-mudell għar-rikonoxximent tal-emozzjonijiet ħadem immedjatament, allura bir-rikonoxximent tal-vuċi kellna nistennew aktar - huma jużaw arkitetturi aktar kumplessi.
Aħna niffokaw fuq dan li ġej:
Emozzjonijiet mill-vuċi - https://github.com/alexmuhr/Voice_Emotion
Taħdem skont il-prinċipju li ġej: l-awdjo jinqata 'f'siltiet ta' ċertu daqs, għal kull waħda minn dawn is-siltiet aħna nagħżlu MFCC u mbagħad ibgħathom bħala input lis-CNN
Sussegwentement nitkellmu dwar il-konverżjoni tal-mudelli, nibdew bit-teorija. OpenVINO jinkludi diversi moduli:
Open Model Zoo, mudelli li minnhom jistgħu jintużaw u inklużi fil-prodott tiegħek
Model Optimzer, li bis-saħħa tiegħu tista' tikkonverti mudell minn diversi formati ta' qafas (Tensorflow, ONNX eċċ) fil-format Intermediate Representation, li miegħu se naħdmu aktar
Inference Engine jippermettilek li tħaddem mudelli f'format IR fuq proċessuri Intel, ċipep Myriad u aċċeleraturi Neural Compute Stick
L-aktar verżjoni effiċjenti ta' OpenCV (bl-appoġġ tal-Inference Engine)
Kull mudell fil-format IR huwa deskritt minn żewġ fajls: .xml u .bin.
Il-mudelli huma kkonvertiti f'format IR permezz ta' Model Optimizer kif ġej:
--data_type jippermettilek tagħżel il-format tad-data li bih il-mudell se jaħdem. FP32, FP16, INT8 huma appoġġjati. L-għażla tat-tip ta 'dejta ottimali tista' tagħti spinta tajba lill-prestazzjoni. --input_shape jindika d-dimensjoni tad-dejta tal-input. Il-ħila li tinbidel b'mod dinamiku tidher li hija preżenti fis-C++ API, iżda aħna ma ħafferx daqshekk u sempliċement issewwiha għal wieħed mill-mudelli.
Sussegwentement, ejja nippruvaw tagħbija l-mudell diġà kkonvertit f'format IR permezz tal-modulu DNN f'OpenCV u tibgħatlu.
import cv2 as cv
emotionsNet = cv.dnn.readNet('emotions_model.bin',
'emotions_model.xml')
emotionsNet.setPreferableTarget(cv.dnn.DNN_TARGET_MYRIAD)
L-aħħar linja f'dan il-każ tippermettilek li terġa 'tidderieġi l-kalkoli lejn in-Neurali Compute Stick, il-kalkoli bażiċi jitwettqu fuq il-proċessur, iżda fil-każ tal-Raspberry Pi dan mhux se jaħdem, ser ikollok bżonn stick.
Sussegwentement, il-loġika hija kif ġej: aħna naqsmu l-awdjo tagħna fi twieqi ta 'ċertu daqs (għalina huwa 0.4 s), aħna nikkonverti kull waħda minn dawn it-twieqi f'MFCC, li mbagħad nimxu lill-grid:
emotionsNet.setInput(MFCC_from_window)
result = emotionsNet.forward()
Sussegwentement, ejja nieħdu l-aktar klassi komuni għat-twieqi kollha. Soluzzjoni sempliċi, iżda għal hackathon m'għandekx bżonn toħroġ b'xi ħaġa wisq abstruse, biss jekk ikollok ħin. Għad fadlilna ħafna xogħol x’nagħmlu, allura ejja nimxu ‘l quddiem – se nittrattaw ir-rikonoxximent tal-vuċi. Huwa meħtieġ li tinħoloq xi tip ta 'database li fiha jkunu maħżuna spettrogrammi ta' vuċijiet irreġistrati minn qabel. Peress li fadal ftit ħin, se nsolvu din il-kwistjoni mill-aħjar li nistgħu.
Jiġifieri, noħolqu skript għar-reġistrazzjoni ta 'silta tal-vuċi (taħdem bl-istess mod kif deskritt hawn fuq, biss meta jiġi interrott mit-tastiera se jiffranka l-vuċi għal fajl).
Ejja nipruvaw:
python3 voice_db/record_voice.py test.wav
Nirrekordjaw il-vuċijiet ta’ diversi nies (fil-każ tagħna, tliet membri tat-tim)
Sussegwentement, għal kull vuċi rreġistrata nwettqu trasformazzjoni fourier veloċi, niksbu spettrogramma u nissejvjawha bħala firxa numpy (.npy):
for file in glob.glob("voice_db/*.wav"):
spec = get_fft_spectrum(file)
np.save(file[:-4] + '.npy', spec)
Aktar dettalji fil-fajl create_base.py
Bħala riżultat, meta nħaddmu l-iskript prinċipali, se nġibu inkorporazzjonijiet minn dawn l-ispettrogrammi fil-bidu nett:
for file in glob.glob("voice_db/*.npy"):
spec = np.load(file)
spec = spec.astype('float32')
spec_reshaped = spec.reshape(1, 1, spec.shape[0], spec.shape[1])
srNet.setInput(spec_reshaped)
pred = srNet.forward()
emb = np.squeeze(pred)
Wara li nirċievu l-inkorporazzjoni mis-segment ħoss, inkunu nistgħu niddeterminaw lil min jappartjeni billi nieħdu d-distanza tal-cosine mill-passaġġ għall-vuċijiet kollha fid-database (iż-żgħar, l-aktar probabbli) - għad-demo nissettjaw il-limitu sa 0.3):
Fl-aħħar, nixtieq ninnota li l-veloċità tal-inferenza kienet mgħaġġla u għamlitha possibbli li jiżdiedu 1-2 mudelli aktar (għal kampjun ta '7 sekondi ħadet 2.5 għall-inferenza). Ma kellniex aktar ħin biex inżidu mudelli ġodda u ffukajna fuq il-kitba ta’ prototip tal-applikazzjoni tal-web.
Applikazzjoni tal-web
Punt importanti: nieħdu router magħna mid-dar u nwaqqfu n-netwerk lokali tagħna, jgħin biex jgħaqqad l-apparat u l-laptops fuq in-netwerk.
Il-backend huwa kanal ta 'messaġġ tarf sa tarf bejn il-faċċata u Raspberry Pi, ibbażat fuq teknoloġija websocket (protokoll http fuq tcp).
L-ewwel stadju huwa li tirċievi informazzjoni pproċessata minn lampun, jiġifieri, tbassir ppakkjati f'json, li jiġu ffrankati fid-database f'nofs il-vjaġġ tagħhom sabiex tkun tista 'tiġi ġġenerata statistika dwar l-isfond emozzjonali tal-utent għall-perjodu. Dan il-pakkett imbagħad jintbagħat lill-frontend, li juża l-abbonament u jirċievi pakketti mill-endpoint tal-websocket. Il-mekkaniżmu backend kollu huwa mibni fil-lingwa golang; intgħażel għax huwa adattat tajjeb għal kompiti asinkroniċi, li l-goroutines jimmaniġġjaw tajjeb.
Meta jaċċessa l-endpoint, l-utent jiġi rreġistrat u mdaħħal fl-istruttura, imbagħad il-messaġġ tiegħu jiġi riċevut. Kemm l-utent kif ukoll il-messaġġ jiddaħħlu f'hub komuni, li minnu l-messaġġi diġà jintbagħtu aktar (għall-faċċata sottoskritta), u jekk l-utent jagħlaq il-konnessjoni (lampun jew quddiem), allura l-abbonament tiegħu jiġi kkanċellat u jitneħħa minn il-hub.
Qed nistennew konnessjoni minn wara
Front-end hija applikazzjoni tal-web miktuba f'JavaScript li tuża l-librerija React biex tħaffef u tissimplifika l-proċess ta 'żvilupp. L-għan ta 'din l-applikazzjoni huwa li jivviżwalizza data miksuba bl-użu ta' algoritmi li jaħdmu fuq in-naħa ta 'wara u direttament fuq il-Raspberry Pi. Il-paġna għandha rotta sezzjonali implimentata bl-użu ta 'react-router, iżda l-paġna ewlenija ta' interess hija l-paġna ewlenija, fejn fluss kontinwu ta 'dejta jiġi riċevut f'ħin reali mis-server bl-użu tat-teknoloġija WebSocket. Raspberry Pi jiskopri vuċi, jiddetermina jekk jappartjenix għal persuna speċifika mid-database reġistrata, u jibgħat lista ta 'probabbiltà lill-klijent. Il-klijent juri l-aħħar data rilevanti, juri l-avatar tal-persuna li x'aktarx tkellmet fil-mikrofonu, kif ukoll l-emozzjoni li biha jippronunzja l-kliem.
Home page bi tbassir aġġornat
Konklużjoni
Ma kienx possibbli li tlesti kollox kif ippjanat, sempliċement ma kellniex ħin, għalhekk it-tama ewlenija kienet fid-demo, li kollox jaħdem. Fil-preżentazzjoni tkellmu dwar kif jaħdem kollox, x’mudelli ħadu, x’problemi ltaqgħu magħhom. Li jmiss kien il-parti demo - esperti mixi madwar il-kamra f'ordni każwali u avviċinat kull tim biex iħarsu lejn il-prototip tax-xogħol. Saqsewna wkoll mistoqsijiet, kulħadd wieġeb il-parti tiegħu, ħallew il-web fuq il-laptop, u kollox ħadem tassew kif mistenni.
Ħa ninnota li l-ispiża totali tas-soluzzjoni tagħna kienet $150:
Raspberry Pi 3 ~ $35
Google AIY Voice Bonnet (tista' tieħu ħlas mill-ġdid) ~ 15$
Intel NCS 2 ~ 100$
Kif tittejjeb:
Uża r-reġistrazzjoni mill-klijent - staqsi biex taqra t-test li jiġi ġġenerat bl-addoċċ
Żid ftit mudelli oħra: tista 'tiddetermina s-sess u l-età bil-vuċi
Ilħna separati li jdoqqu fl-istess ħin (dijarizzazzjoni)
Bħala konklużjoni, nixtieq ngħid grazzi lill-organizzaturi u lill-parteċipanti. Fost il-proġetti ta’ timijiet oħra, personalment għoġobna s-soluzzjoni għall-monitoraġġ ta’ spazji ta’ parkeġġ b’xejn. Għalina, kienet esperjenza wildly friska ta 'immersjoni fil-prodott u l-iżvilupp. Nittama li jsiru aktar u aktar avvenimenti interessanti fir-reġjuni, inkluż dwar suġġetti tal-IA.