OpenVINO hackathon: pag-ila sa tingog ug emosyon sa Raspberry Pi

Nobyembre 30 - Disyembre 1 sa Nizhny Novgorod gipahigayon OpenVINO hackathon. Gihangyo ang mga partisipante sa paghimo ug prototype sa solusyon sa produkto gamit ang Intel OpenVINO toolkit. Gisugyot sa mga organizer ang usa ka lista sa gibanabana nga mga hilisgutan nga mahimong magiyahan kung nagpili usa ka buluhaton, apan ang katapusan nga desisyon nagpabilin sa mga koponan. Dugang pa, ang paggamit sa mga modelo nga wala gilakip sa produkto gidasig.

OpenVINO hackathon: pag-ila sa tingog ug emosyon sa Raspberry Pi

Niini nga artikulo isulti namo kanimo kung giunsa namo paghimo ang among prototype sa produkto, diin kami sa katapusan nag-una.

Kapin sa 10 ka teams ang misalmot sa hackathon. Maayo kay ang uban kanila gikan sa ubang rehiyon. Ang lugar alang sa hackathon mao ang "Kremlinsky on Pochain" complex, diin ang mga karaang litrato sa Nizhny Novgorod gibitay sa sulod, sa usa ka entourage! (Gipahinumdoman ko ikaw nga sa pagkakaron ang sentral nga opisina sa Intel nahimutang sa Nizhny Novgorod). Ang mga partisipante gihatagan og 26 ka oras sa pagsulat og code, ug sa katapusan kinahanglan nilang ipresentar ang ilang solusyon. Ang usa ka lahi nga bentaha mao ang presensya sa usa ka sesyon sa demo aron masiguro nga ang tanan nga giplano gipatuman gyud ug wala magpabilin nga mga ideya sa presentasyon. Mga baligya, meryenda, pagkaon, tanan didto usab!

Dugang pa, opsyonal nga gihatag sa Intel ang mga camera, Raspberry PI, Neural Compute Stick 2.

Pagpili sa buluhaton

Usa sa labing lisud nga bahin sa pag-andam alang sa usa ka libre nga porma nga hackathon mao ang pagpili sa usa ka hagit. Nakahukom dayon kami nga maghimo usa ka butang nga wala pa sa produkto, tungod kay ang pahibalo nag-ingon nga kini giabiabi kaayo.

Naanalisa mga modelo, nga gilakip sa produkto sa karon nga pagpagawas, nakahinapos kami nga kadaghanan kanila nagsulbad sa lainlaing mga problema sa panan-aw sa kompyuter. Dugang pa, lisud kaayo ang paghimo sa usa ka problema sa natad sa computer vision nga dili masulbad gamit ang OpenVINO, ug bisan kung ang usa mahimo nga imbento, lisud ang pagpangita sa mga pre-trained nga mga modelo sa publiko nga domain. Nagdesisyon kami nga magkalot sa lain nga direksyon - padulong sa pagproseso sa sinultihan ug analytics. Atong tagdon ang usa ka makapaikag nga buluhaton sa pag-ila sa mga emosyon gikan sa sinultihan. Kinahanglang isulti nga ang OpenVINO adunay usa ka modelo nga nagtino sa mga emosyon sa usa ka tawo base sa ilang nawong, apan:

  • Sa teorya, posible nga maghimo usa ka hiniusa nga algorithm nga molihok sa parehas nga tunog ug imahe, nga kinahanglan maghatag usa ka pagtaas sa katukma.
  • Ang mga kamera kasagaran adunay pig-ot nga anggulo sa pagtan-aw; labaw pa sa usa ka kamera ang gikinahanglan aron matabonan ang usa ka dako nga lugar; ang tingog walay ingon nga limitasyon.

Atong pauswagon ang ideya: atong himoon ang ideya alang sa retail nga bahin isip basehan. Mahimo nimong sukdon ang katagbawan sa kustomer sa mga checkout sa tindahan. Kung ang usa sa mga kustomer wala matagbaw sa serbisyo ug nagsugod sa pagpataas sa ilang tono, mahimo nimo dayon tawagan ang tagdumala alang sa tabang.
Niini nga kaso, kinahanglan natong idugang ang pag-ila sa tingog sa tawo, kini magtugot kanato sa pag-ila sa mga empleyado sa tindahan gikan sa mga kustomer ug paghatag og analytics alang sa matag indibidwal. Aw, dugang pa, posible nga analisahon ang pamatasan sa mga empleyado sa tindahan mismo, pagtimbang-timbang sa atmospera sa team, maayo ang paminawon!

Giporma namon ang mga kinahanglanon alang sa among solusyon:

  • Gamay nga gidak-on sa target device
  • Tinuod nga oras nga operasyon
  • Ubos nga presyo
  • Sayon scalability

Ingon usa ka sangputanan, gipili namon ang Raspberry Pi 3 c ingon ang target nga aparato Intel NCS 2.

Dinhi importante nga timan-an ang usa ka importante nga bahin sa NCS - kini labing maayo sa mga standard nga arkitektura sa CNN, apan kung kinahanglan nimo nga magpadagan og usa ka modelo nga adunay custom nga mga layer niini, unya magdahum nga ubos ang lebel nga pag-optimize.

Adunay usa lang ka gamay nga butang nga buhaton: kinahanglan nimo nga makakuha usa ka mikropono. Ang usa ka regular nga USB mikropono mahimo, apan kini dili maayo tan-awon uban sa RPI. Apan bisan dinhi ang solusyon literal nga "naa sa duol." Aron irekord ang tingog, mihukom kami nga gamiton ang Voice Bonnet board gikan sa kit Google AIY Voice Kit, diin adunay wired stereo microphone.

I-download ang Raspbian gikan sa Ang mga proyekto sa AIY repository ug i-upload kini sa usa ka flash drive, sulayi nga ang mikropono nagtrabaho gamit ang mosunod nga sugo (kini magrekord sa audio 5 segundos ang gitas-on ug i-save kini sa usa ka file):

arecord -d 5 -r 16000 test.wav

Kinahanglan nakong timan-an dayon nga ang mikropono sensitibo kaayo ug maayo nga mokuha og kasaba. Aron ayuhon kini, adto ta sa alsamixer, pilia ang Capture devices ug pakunhuran ang lebel sa input signal ngadto sa 50-60%.

OpenVINO hackathon: pag-ila sa tingog ug emosyon sa Raspberry Pi
Gibag-o namon ang lawas gamit ang usa ka file ug ang tanan mohaum, mahimo pa nimo kini isira sa usa ka taklob

Pagdugang ug indicator button

Samtang gilain ang AIY Voice Kit, among nahinumduman nga adunay usa ka RGB nga buton, ang backlight nga mahimong kontrolado sa software. Gipangita namo ang "Google AIY Led" ug nakit-an ang dokumentasyon: https://aiyprojects.readthedocs.io/en/latest/aiy.leds.html
Ngano nga dili gamiton kini nga buton aron ipakita ang giila nga emosyon, kami adunay 7 ra nga mga klase, ug ang buton adunay 8 nga mga kolor, igo ra!

Gikonektar namon ang buton pinaagi sa GPIO sa Voice Bonnet, i-load ang kinahanglan nga mga librarya (na-install na sila sa distribution kit gikan sa mga proyekto sa AIY)

from aiy.leds import Leds, Color
from aiy.leds import RgbLeds

Maghimo kita og usa ka dict diin ang matag emosyon adunay katugbang nga kolor sa porma sa RGB Tuple ug usa ka butang sa klase aiy.leds.Leds, diin atong i-update ang kolor:

led_dict = {'neutral': (255, 255, 255), 'happy': (0, 255, 0), 'sad': (0, 255, 255), 'angry': (255, 0, 0), 'fearful': (0, 0, 0), 'disgusted':  (255, 0, 255), 'surprised':  (255, 255, 0)} 
leds = Leds()

Ug sa katapusan, pagkahuman sa matag bag-ong panagna sa usa ka emosyon, among i-update ang kolor sa buton nga nahiuyon niini (pinaagi sa yawe).

leds.update(Leds.rgb_on(led_dict.get(classes[prediction])))

OpenVINO hackathon: pag-ila sa tingog ug emosyon sa Raspberry Pi
Butang, sunogon!

Pagtrabaho gamit ang tingog

Gamiton namo ang pyaudio aron makuha ang sapa gikan sa mikropono ug webrtcvad aron masala ang kasaba ug makamatikod sa tingog. Dugang pa, maghimo kami usa ka pila diin among idugang ug tangtangon ang mga kinutlo sa tingog.

Tungod kay ang webrtcvad adunay limitasyon sa gidak-on sa gihatag nga tipik - kini kinahanglan nga katumbas sa 10/20/30ms, ug ang pagbansay sa modelo alang sa pag-ila sa mga emosyon (ingon sa atong mahibal-an sa ulahi) gihimo sa usa ka 48kHz dataset, atong buhaton. pagkuha sa mga tipak sa gidak-on 48000Γ—20ms/1000Γ—1(mono)=960 bytes. Ibalik sa Webrtcvad ang True/False para sa matag usa niini nga mga tipak, nga katumbas sa presensya o pagkawala sa usa ka boto sa tipak.

Atong ipatuman ang mosunod nga lohika:

  • Atong idugang sa lista kadtong mga tipik diin adunay boto; kung walay boto, nan atong dugangan ang counter sa walay sulod nga mga tipak.
  • Kung ang counter sa walay sulod nga mga tipik kay >=30 (600 ms), nan atong tan-awon ang gidak-on sa listahan sa natipon nga mga tipak; kon kini> 250, nan atong idugang kini sa pila; kon dili, atong isipon nga ang gitas-on sa rekord dili igo aron ipakaon kini sa modelo aron mailhan ang mamumulong.
  • Kung ang counter sa walay sulod nga mga tipik kay <30 pa, ug ang gidak-on sa listahan sa natipon nga mga tipak molapas sa 300, nan atong idugang ang tipik sa pila para sa mas tukma nga panagna. (tungod kay ang mga emosyon lagmit mausab sa paglabay sa panahon)

 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 = []

Panahon na nga mangita alang sa mga pre-trained nga mga modelo sa publiko nga domain, adto sa github, Google, apan hinumdomi nga kami adunay limitasyon sa gigamit nga arkitektura. Kini usa ka lisud nga bahin, tungod kay kinahanglan nimo nga sulayan ang mga modelo sa imong input data, ug dugang pa, i-convert kini sa internal nga format sa OpenVINO - IR (Intermediate Representation). Gisulayan namon ang mga 5-7 nga lainlaing mga solusyon gikan sa github, ug kung ang modelo alang sa pag-ila sa mga emosyon molihok dayon, unya uban ang pag-ila sa tingog kinahanglan namon maghulat nga mas dugay - gigamit nila ang labi ka komplikado nga mga arkitektura.

Nagtutok kami sa mosunod:

  • Mga emosyon gikan sa tingog - https://github.com/alexmuhr/Voice_Emotion
    Naglihok kini sumala sa mosunod nga prinsipyo: ang audio giputol sa mga tudling sa usa ka piho nga gidak-on, alang sa matag usa niini nga mga tudling nga atong gipili MFCC ug dayon isumite kini isip input sa CNN
  • Pag-ila sa tingog - https://github.com/linhdvu14/vggvox-speaker-identification
    Dinhi, imbes sa MFCC, nagtrabaho kami sa usa ka spectrogram, pagkahuman sa FFT among gipakaon ang signal sa CNN, diin sa output nakakuha kami usa ka representasyon sa vector sa tingog.

Sunod kita maghisgot mahitungod sa pagkabig sa mga modelo, sugod sa teorya. Ang OpenVINO naglakip sa daghang mga module:

  • Open Model Zoo, mga modelo nga mahimong gamiton ug iapil sa imong produkto
  • Model Optimzer, salamat nga mahimo nimong mabag-o ang usa ka modelo gikan sa lainlaing mga format sa framework (Tensorflow, ONNX etc) ngadto sa format nga Intermediate Representation, diin kami magtrabaho pa.
  • Ang Inference Engine nagtugot kanimo sa pagpadagan sa mga modelo sa IR format sa Intel processors, Myriad chips ug Neural Compute Stick accelerators
  • Ang labing episyente nga bersyon sa OpenCV (nga adunay suporta sa Inference Engine)
    Ang matag modelo sa IR format gihulagway sa duha ka file: .xml ug .bin.
    Ang mga modelo gi-convert sa IR format pinaagi sa Model Optimizer sama sa mosunod:

    python /opt/intel/openvino/deployment_tools/model_optimizer/mo_tf.py --input_model speaker.hdf5.pb --data_type=FP16 --input_shape [1,512,1000,1]

    --data_type nagtugot kanimo sa pagpili sa format sa datos diin ang modelo magamit. Gisuportahan ang FP32, FP16, INT8. Ang pagpili sa labing maayo nga tipo sa datos makahatag usa ka maayo nga pagpauswag sa pasundayag.
    --input_shape nagpakita sa dimensyon sa input data. Ang abilidad sa dinamikong pagbag-o kini daw naa sa C ++ API, apan wala kami nagkalot nga layo ug yano nga giayo kini alang sa usa sa mga modelo.
    Sunod, atong sulayan nga ikarga ang nakabig na nga modelo sa IR format pinaagi sa DNN module ngadto sa OpenCV ug ipasa kini niini.

    import cv2 as cv
    emotionsNet = cv.dnn.readNet('emotions_model.bin',
                              'emotions_model.xml')
    emotionsNet.setPreferableTarget(cv.dnn.DNN_TARGET_MYRIAD)

    Ang katapusan nga linya sa kini nga kaso nagtugot kanimo sa pag-redirect sa mga kalkulasyon sa Neural Compute Stick, ang mga batakang kalkulasyon gihimo sa processor, apan sa kaso sa Raspberry Pi dili kini molihok, kinahanglan nimo ang usa ka sungkod.

    Sunod, ang lohika mao ang mosunod: among gibahin ang among audio ngadto sa mga bintana sa usa ka piho nga gidak-on (alang kanamo kini 0.4 s), among gi-convert ang matag usa niini nga mga bintana ngadto sa MFCC, nga among gipakaon sa grid:

    emotionsNet.setInput(MFCC_from_window)
    result = emotionsNet.forward()

    Sunod, atong kuhaon ang labing kasagaran nga klase alang sa tanan nga mga bintana. Usa ka yano nga solusyon, apan alang sa usa ka hackathon dili nimo kinahanglan nga maghimo usa ka butang nga labi ka abstruse, kung adunay ka oras. Daghan pa mig trabaho, mao nga magpadayon ta - atubangon nato ang voice recognition. Kinahanglang maghimo ug usa ka matang sa database diin ang mga spectrograms sa pre-recorded nga mga tingog itago. Tungod kay gamay ra ang nahabilin nga oras, among sulbaron kini nga isyu kutob sa among mahimo.

    Sa ato pa, naghimo kami usa ka script alang sa pagrekord sa usa ka kinutlo sa tingog (kini molihok sa parehas nga paagi sama sa gihulagway sa ibabaw, kung mabalda gikan sa keyboard kini maluwas ang tingog sa usa ka file).

    Atong sulayan:

    python3 voice_db/record_voice.py test.wav

    Girekord namon ang mga tingog sa daghang mga tawo (sa among kaso, tulo ka mga miyembro sa team)
    Sunod, alang sa matag narekord nga tingog naghimo kami og paspas nga fourier nga pagbag-o, pagkuha og spectrogram ug i-save kini isip numpy array (.npy):

    for file in glob.glob("voice_db/*.wav"):
            spec = get_fft_spectrum(file)
            np.save(file[:-4] + '.npy', spec)

    Dugang detalye sa file create_base.py
    Ingon usa ka sangputanan, kung gipadagan namon ang panguna nga script, makakuha kami mga embeddings gikan sa kini nga mga spectrogram sa sinugdanan:

    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)

    Human madawat ang pag-embed gikan sa gipalanog nga bahin, mahimo natong mahibal-an kung kinsa kini pinaagi sa pagkuha sa gilay-on nga cosine gikan sa agianan ngadto sa tanan nga mga tingog sa database (mas gamay, mas lagmit) - alang sa demo nga atong gibutang ang threshold ngadto sa 0.3):

            dist_list = cdist(emb, enroll_embs, metric="cosine")
            distances = pd.DataFrame(dist_list, columns = df.speaker)

    Sa katapusan, gusto nakong timan-an nga ang katulin sa inference paspas ug nagpaposible sa pagdugang og 1-2 pa nga mga modelo (alang sa usa ka sample nga 7 segundos ang gitas-on nagkinahanglan og 2.5 alang sa inference). Wala na kami panahon sa pagdugang og bag-ong mga modelo ug naka-focus sa pagsulat og prototype sa web application.

    Web application

    Usa ka importante nga punto: nagdala kami og router uban kanamo gikan sa balay ug gipahimutang ang among lokal nga network, kini makatabang sa pagkonektar sa device ug mga laptop sa network.

    Ang backend usa ka end-to-end message channel tali sa atubangan ug Raspberry Pi, base sa websocket nga teknolohiya (http over tcp protocol).

    Ang una nga yugto mao ang pagdawat sa giproseso nga impormasyon gikan sa raspberry, nga mao, ang mga prediktor nga giputos sa json, nga gitipigan sa database sa tunga-tunga sa ilang panaw aron ang mga estadistika mahimong mamugna mahitungod sa emosyonal nga background sa tiggamit alang sa panahon. Kini nga packet ipadala dayon ngadto sa frontend, nga naggamit og suskrisyon ug makadawat og mga packet gikan sa websocket endpoint. Ang tibuuk nga mekanismo sa backend gitukod sa pinulongang golang; gipili kini tungod kay haum kini alang sa mga asynchronous nga buluhaton, nga maayo ang pagdumala sa mga goroutine.
    Sa pag-access sa endpoint, ang user narehistro ug misulod sa istruktura, dayon ang iyang mensahe madawat. Ang tiggamit ug ang mensahe gisulod sa usa ka komon nga hub, diin ang mga mensahe gipadala na sa dugang (ngadto sa na-subscribe nga atubangan), ug kung ang user magsira sa koneksyon (raspberry o atubangan), unya ang iyang suskrisyon kanselahon ug siya tangtangon gikan sa ang hub.

    OpenVINO hackathon: pag-ila sa tingog ug emosyon sa Raspberry Pi
    Naghulat kami alang sa koneksyon gikan sa luyo

    Ang Front-end usa ka aplikasyon sa web nga gisulat sa JavaScript gamit ang React library aron mapadali ug mapasimple ang proseso sa pag-uswag. Ang katuyoan sa kini nga aplikasyon mao ang paghanduraw sa datos nga nakuha gamit ang mga algorithm nga nagdagan sa back-end nga bahin ug direkta sa Raspberry Pi. Ang panid adunay sectional routing nga gipatuman gamit ang react-router, apan ang nag-unang panid sa interes mao ang nag-unang panid, diin ang usa ka padayon nga stream sa data madawat sa tinuod nga panahon gikan sa server gamit ang WebSocket nga teknolohiya. Ang Raspberry Pi nakamatikod sa usa ka tingog, nagtino kon iya ba kini sa usa ka espesipikong tawo gikan sa narehistro nga database, ug nagpadala ug lista sa posibilidad ngadto sa kliyente. Gipakita sa kliyente ang pinakabag-o nga may kalabutan nga datos, gipakita ang avatar sa tawo nga lagmit nagsulti sa mikropono, ingon man ang emosyon nga iyang gilitok ang mga pulong.

    OpenVINO hackathon: pag-ila sa tingog ug emosyon sa Raspberry Pi
    Panimalay nga panid nga adunay bag-ong mga panagna

    konklusyon

    Dili mahimo nga makompleto ang tanan sama sa giplano, wala kami oras, mao nga ang panguna nga paglaum naa sa demo, nga ang tanan molihok. Sa presentasyon sila naghisgot kon sa unsang paagi ang tanan nagtrabaho, unsa nga mga modelo ang ilang gikuha, unsa nga mga problema nga ilang nasugatan. Sunod mao ang bahin sa demo - ang mga eksperto naglibot sa kwarto sa random nga pagkahan-ay ug miduol sa matag team aron tan-awon ang nagtrabaho nga prototype. Gipangutana usab nila kami, ang tanan mitubag sa ilang bahin, gibiyaan nila ang web sa laptop, ug ang tanan nagtrabaho gyud sama sa gipaabut.

    Timan-i nako nga ang kinatibuk-ang gasto sa among solusyon kay $150:

    • Raspberry Pi 3 ~ $35
    • Google AIY Voice Bonnet (mahimo nimong kuhaon ang bayad sa respeaker) ~ 15$
    • Intel NCS 2 ~ 100$

    Unsaon pagpauswag:

    • Paggamit pagrehistro gikan sa kliyente - hangyoa nga basahon ang teksto nga namugna nga random
    • Pagdugang og pipila ka mga modelo: mahimo nimong mahibal-an ang gender ug edad pinaagi sa tingog
    • Pagbulag sa dungan nga tingog (diarization)

    Repositoryo: https://github.com/vladimirwest/OpenEMO

    OpenVINO hackathon: pag-ila sa tingog ug emosyon sa Raspberry Pi
    Kapoy pero happy mi

    Sa pagtapos, gusto kong magpasalamat sa mga nag-organisar ug mga partisipante. Lakip sa mga proyekto sa ubang mga team, personal namong ganahan ang solusyon sa pagmonitor sa mga libreng parking space. Alang kanamo, kini usa ka bugnaw nga kasinatian sa pagpaunlod sa produkto ug pag-uswag. Nanghinaut ko nga mas daghan ug mas makaiikag nga mga panghitabo ang ipahigayon sa mga rehiyon, lakip na sa AI nga mga topiko.

Source: www.habr.com

Idugang sa usa ka comment