OpenVINO hackathon: naskirina deng û hestan li ser Raspberry Pi

30ê Mijdarê - 1ê Kanûnê li Nîjnî Novgorodê hat lidarxistin Hackathon OpenVINO. Ji beşdaran hat xwestin ku bi karanîna amûra Intel OpenVINO prototîpek çareseriyek hilberek çêbikin. Organîzator navnîşek mijarên texmînî pêşniyar kirin ku di hilbijartina karekî de dikare were rêve kirin, lê biryara dawî di destê tîmê de ma. Wekî din, karanîna modelên ku di hilberê de ne hatine teşwîq kirin.

OpenVINO hackathon: naskirina deng û hestan li ser Raspberry Pi

Di vê gotarê de em ê ji we re vebêjin ka me çawa prototîpa xwe ya hilberê çêkir, ku em di dawiyê de cîhê yekem girt.

Zêdeyî 10 tîm beşdarî hackathonê bûn. Xweş e ku hinek ji wan ji herêmên din hatine. Cihê hackathon kompleksa "Kremlinsky on Pochain" bû, ku wêneyên kevnar ên Nizhny Novgorod di hundurê de, di nav derdor de hatin daliqandin! (Ez tê bîra we ku niha nivîsgeha navendî ya Intel li Nizhny Novgorod e). Ji beşdaran re 26 saet ji bo nivîsandina kodê hate dayîn, û di dawiyê de neçar bûn ku çareseriya xwe pêşkêş bikin. Avantajek cihêreng hebûna danişînek demo bû da ku pê ewle bibe ku her tiştê ku hatî plansaz kirin bi rastî hatî bicîh kirin û di pêşkêşiyê de raman nemîne. Merc, xwarin, xwarin, her tişt jî li wir bû!

Wekî din, Intel vebijarkî kamerayan, Raspberry PI, Neural Compute Stick 2 peyda kir.

Hilbijartina peywirê

Yek ji beşên herî dijwar ên amadekirina hackathonek belaş hilbijartina dijwariyek e. Me tavilê biryar da ku em tiştek ku hîn di hilberê de nebû derxin holê, ji ber ku di daxuyaniyê de hate gotin ku ev pir bi xêr hatî.

Analîz kirin modela, ku di hilbera heyî de di nav hilberê de cih digirin, em digihîjin vê encamê ku piraniya wan pirsgirêkên cihêreng ên dîtina komputerê çareser dikin. Wekî din, pir dijwar e ku meriv di warê dîtina komputerê de pirsgirêkek ku bi karanîna OpenVINO-yê nayê çareser kirin were çareser kirin, û hetta meriv dikare were îcad kirin jî, dijwar e ku meriv modelên pêş-perwerdekirî di qada gelemperî de bibîne. Em biryar didin ku di rêgezek din de bikolin - berbi pêvajoyek axaftinê û analîtîk. Werin em karekî balkêş bihesibînin ku hestên ji axaftinê nas bikin. Pêdivî ye ku were gotin ku OpenVINO jixwe modelek heye ku hestên kesek li ser rûyê wî diyar dike, lê:

  • Di teorîyê de, gengaz e ku meriv algorîtmayek hevgirtî biafirîne ku dê hem li ser deng û hem jî wêneyê bixebite, ku divê rastbûnê zêde bike.
  • Kamera bi gelemperî xwedan goşeyek dîtinê ya teng in; ji bo vegirtina deverek mezin ji yekê zêdetir kamera hewce ye; deng ne xwedan sînorek wusa ye.

Werin em ramanê pêş bixin: werin em ramana beşa firotanê wekî bingeh bigirin. Hûn dikarin razîbûna xerîdar li firoşgehan bipîvin. Ger yek ji xerîdar ji karûbarê nerazî be û dest bi bilindkirina dengê xwe bike, hûn dikarin tavilê ji bo alîkariyê bangî rêveberê bikin.
Di vê rewşê de, pêdivî ye ku em nasîna dengê mirovî lê zêde bikin, ev ê bihêle ku em karmendên firotgehê ji xerîdar cuda bikin û ji bo her kesan analîtîk peyda bikin. Welê, ji bilî vê, dê mimkun be ku meriv behreya xebatkarên firotgehê bixwe analîz bike, atmosfera di tîmê de binirxîne, baş xuya dike!

Em pêdiviyên ji bo çareseriya xwe formule dikin:

  • Mezinahiya piçûk a cîhaza armancê
  • Operasyona dema rast
  • Bihayê kêm
  • Scalability Easy

Wekî encamek, em Raspberry Pi 3 c wekî amûra armanc hilbijêrin Intel NCS 2.

Li vir girîng e ku meriv taybetmendiyek girîng a NCS-ê destnîşan bike - ew bi mîmariyên standard CNN re çêtirîn dixebite, lê heke hûn hewce ne ku modelek bi qatên xwerû li ser wê bimeşînin, wê hingê li hêviya xweşbîniya asta nizm bin.

Tenê tiştek piçûk heye ku hûn bikin: hûn hewce ne ku mîkrofonek bistînin. Mîkrofonek USB-ya birêkûpêk dê bike, lê ew ê bi RPI re baş xuya neke. Lê tewra li vir jî çareserî bi rastî "nêzîk e." Ji bo tomarkirina deng, em biryar didin ku panela Voice Bonnet ji kîtê bikar bînin Google Aiy Deng Kit, ku li ser mîkrofonek stereo têl heye.

Raspbian ji dakêşin depoya projeyên AIY û wê li ajokerek flashê bar bikin, biceribînin ku mîkrofon bi fermana jêrîn kar dike (ew ê deng 5 saniye dirêj tomar bike û wê li pelek tomar bike):

arecord -d 5 -r 16000 test.wav

Divê ez tavilê zanibim ku mîkrofon pir hesas e û deng baş hildide. Ji bo rastkirina vê yekê, werin em biçin alsamixer, cîhazên Capture hilbijêrin û asta sînyala têketinê ji% 50-60 kêm bikin.

OpenVINO hackathon: naskirina deng û hestan li ser Raspberry Pi
Em laşê bi pelê diguhezînin û her tişt li hev tê, hûn jî dikarin wê bi qapaxekê vekin

Zêdekirina bişkokek nîşanker

Dema ku Kita Dengê AIY ji hev vediqetîne, em ji bîr dikin ku bişkokek RGB heye, ku ronahiya paşerojê dikare ji hêla nermalavê ve were kontrol kirin. Em li "Google AIY Led" digerin û belgeyan dibînin: https://aiyprojects.readthedocs.io/en/latest/aiy.leds.html
Çima vê bişkojkê bikar neynin da ku hestiyariya naskirî nîşan bidin, tenê 7 çînên me hene, û bişkok 8 reng hene, bes bes!

Em bişkojê bi navgîniya GPIO ve bi Voice Bonnet ve girêdidin, pirtûkxaneyên pêwîst bar dikin (ew berê di kîtê belavkirinê de ji projeyên AIY hatine saz kirin)

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

Werin em dîktatorek biafirînin ku tê de her hestek di forma RGB Tuple û objeyek çîna aiy.leds.Led-ê de rengekî têkildar hebe, bi navgîniya wê em ê reng nûve bikin:

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()

Û di dawiyê de, piştî her pêşbîniya nû ya hestek, em ê rengê bişkojê li gorî wê (bi key) nûve bikin.

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

OpenVINO hackathon: naskirina deng û hestan li ser Raspberry Pi
Bişkok, şewitandin!

Bi deng kar dikin

Em ê pyaudio bikar bînin da ku tîrêjê ji mîkrofonê û webrtcvad bigirin da ku deng fîltre bikin û deng nas bikin. Digel vê yekê, em ê rêzek biafirînin ku em ê bi asynkronî jêderkên deng lê zêde bikin û jê bikin.

Ji ber ku webrtcvad di mezinahiya perçeya peydakirî de sînorek heye - divê ew 10/20/30ms wekhev be, û perwerdehiya modelê ji bo naskirina hestan (wek ku em ê paşê fêr bibin) li ser danehevek 48kHz hate kirin, em ê perçeyên bi mezinahiya 48000×20ms/1000×1(mono)=960 byte bigire. Webrtcvad dê ji bo her yek ji van perçeyan Rast/False vegerîne, ku bi hebûn an nebûna dengek di perçeyê de têkildar e.

Werin em mantiqa jêrîn bicîh bînin:

  • Em ê wan perçeyên ku deng lê hebe têxin lîsteyê, ger deng tune be, em ê jimarvana perçeyên vala zêde bikin.
  • Ger jimarvana perçeyên vala >=30 (600 ms) be, wê demê em li mezinahiya lîsteya perçeyên berhevkirî dinêrin; heke ew> 250 be, wê demê em wê lê zêde dikin rêzê, heke na, em dirêjiyê dihesibînin. ya tomar ne bes e ku meriv wê bide modelê da ku axaftvan nas bike.
  • Ger jimarvana perçeyên vala hê jî <30 be, û mezinahiya lîsteya perçeyên berhevkirî ji 300-î derbastir be, wê hingê em ê perçeyê li dorê zêde bikin ji bo pêşbîniyek rasttir. (ji ber ku hest bi demê re diguherin)

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

Wext e ku meriv li modelên pêş-perwerdekirî di qada gelemperî de bigerin, biçin github, Google, lê ji bîr mekin ku li ser mîmariya hatî bikar anîn sînorek me heye. Ev beşek pir dijwar e, ji ber ku hûn neçar in ku modelan li ser daneyên têketina xwe biceribînin, û ji bilî vê, wan veguherînin forma navxweyî ya OpenVINO - IR (Nûneriya Navber). Me bi qasî 5-7 çareseriyên cihêreng ji github ceriband, û ger modela naskirina hestan tavilê bixebite, wê hingê bi naskirina deng re em neçar bûn ku demek dirêjtir li bendê bin - ew mîmariyên tevlihevtir bikar tînin.

Em li ser van tiştan bisekinin:

Piştre em ê li ser veguherandina modelan biaxivin, bi teoriyê dest pê bikin. OpenVINO çend modulan vedihewîne:

  • Model Zoo vekin, modelên ku dikarin di hilbera we de werin bikar anîn û têkevin
  • Model Optimzer, bi saya wê hûn dikarin modelek ji formên çarçoveyek cihêreng (Tensorflow, ONNX hwd) veguherînin forma Nûnertiya Navîn, ku em ê pê re bêtir bixebitin
  • Inference Engine destûrê dide te ku hûn modelan bi formata IR-ê li ser pêvajoyên Intel, çîpên Myriad û bilezkerên Neural Compute Stick bimeşînin.
  • Guhertoya herî bikêr a OpenCV (bi piştgiriya Engine Inference)
    Her modelek di formata IR de ji hêla du pelan ve tête diyar kirin: .xml û .bin.
    Model bi navgîniya Model Optimizer ve wekî jêrîn vediguhezînin formata IR:

    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 destûrê dide te ku hûn formata daneyê ya ku dê model pê re bixebite hilbijêrin. FP32, FP16, INT8 têne piştgirî kirin. Hilbijartina celebê daneya çêtirîn dikare performansek baş bide.
    --input_shape pîvana daneya têketinê nîşan dide. Qabiliyeta guheztina dînamîkî ew xuya dike ku di API-ya C++ de heye, lê me ew qas dûr nexist û bi tenê ew ji bo yek ji modelan rast kir.
    Dûv re, em hewl bidin ku modela ku berê hatî veguheztin di formata IR-ê de bi modula DNN-ê ve li OpenCV-ê bar bike û wê bişîne.

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

    Rêza paşîn di vê rewşê de dihêle hûn hesabên beralî bikin Neural Compute Stick, hesabên bingehîn li ser pêvajoyê têne kirin, lê di doza Raspberry Pi de ev ê nexebite, hûn ê hewceyê darikê bikin.

    Dûv re, mantiq wiha ye: em dengê xwe li pencereyên bi pîvanek diyarkirî dabeş dikin (ji bo me ew 0.4 s ye), em her yek ji van pencereyan vediguhezînin MFCC, ku em dûv re li torê vedixwin:

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

    Dûv re, em ji bo hemî pencereyan çîna herî gelemperî bigirin. Çareseriyek hêsan, lê ji bo hackathon-ê hûn ne hewce ne ku hûn tiştek pir bêkêmasî derxînin, tenê heke wextê we hebe. Hîn gelek karê me heye ku em bikin, ji ber vê yekê em biçin - em ê bi naskirina dengan re mijûl bibin. Pêdivî ye ku celebek databasek were çêkirin ku tê de spektrogramên dengên pêş-qeydkirî bêne hilanîn. Ji ber ku hindik dem maye, em ê bi qasî ku ji destê me bê em ê vê pirsgirêkê çareser bikin.

    Ango, em skrîptek ji bo tomarkirina dengek dengek diafirînin (ew bi heman awayê ku li jor hatî destnîşan kirin dixebite, tenê dema ku ji klavyeyê qut bibe ew ê deng li pelek tomar bike).

    Ka em biceribînin:

    python3 voice_db/record_voice.py test.wav

    Em dengê çend kesan tomar dikin (di doza me de, sê endamên tîmê)
    Dûv re, ji bo her dengek tomarkirî em veguherînek çargoşe ya bilez pêk tînin, spektrogramek werdigirin û wê wekî rêzek numpy (.npy) hilînin:

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

    Agahiyên bêtir di dosyayê de create_base.py
    Wekî encamek, gava ku em skrîpta sereke dimeşînin, em ê di destpêkê de ji van spektrograman veqetandî bistînin:

    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)

    Piştî wergirtina vegirtina ji beşê dengdayî, em ê karibin bi girtina dûrahiya kosînusê ya ji derbasbûnê ji hemî dengên di databasê re (çi piçûktir, îhtîmalek mezin) - ji bo demoyê em bend destnîşan bikin heta 0.3):

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

    Di dawiyê de, ez dixwazim balê bikişînim ku leza encamdanê zû bû û gengaz kir ku 1-2 modelên din lê zêde bike (ji bo nimûneyek 7 çirkeyan dirêj ji bo encamdanê 2.5 girt). Êdî wextê me tunebû ku em modelên nû lê zêde bikin û li ser nivîsandina prototîpa serîlêdana webê sekinîn.

    Serlêdana Webê

    Xalek girîng: em ji malê routerek bi xwe re digirin û tora xweya herêmî saz dikin, ew ji bo girêdana cîhaz û laptopan li ser torê dibe alîkar.

    Piştgir kanalek peyama dawî-bi-dawî ye di navbera pêş û Raspberry Pi de, ku li ser bingeha teknolojiya websocket (http li ser protokola tcp) ye.

    Qonaxa yekem wergirtina agahdariya pêvajokirî ji raspberry e, ango pêşbînkerên ku di json de hatine pak kirin, ku di nîvê rêwîtiya xwe de di databasê de têne tomar kirin da ku statîstîk di derheqê paşxaneya hestyarî ya bikarhêner a ji bo heyamê de bêne çêkirin. Dûv re ev pakêt ji pêşiyê re tê şandin, ku abonetiyê bikar tîne û pakêtan ji xala dawiya websocketê distîne. Tevahiya mekanîzmaya paşîn bi zimanê golang hatî çêkirin; ew hate hilbijartin ji ber ku ew ji bo karên asynchronous, ku goroutine baş bi rê ve dibin, xweş e.
    Dema ku gihîştina xala dawîn, bikarhêner tê qeyd kirin û têkevin nav avahiyê, paşê peyama wî tê wergirtin. Hem bikarhêner û hem jî peyam di nav navendek hevpar de têne şandin, ku jê mesajan berê bêtir têne şandin (ji eniya abonetiyê re), û ger bikarhêner pêwendiyê bigire (raspberry an pêş), wê hingê abonetiya wî tê betal kirin û ew ji nav tê derxistin. hub.

    OpenVINO hackathon: naskirina deng û hestan li ser Raspberry Pi
    Em li benda pêwendiyek ji paş ve ne

    Front-end serîlêdanek webê ye ku di JavaScript-ê de hatî nivîsandin ku pirtûkxaneya React bikar tîne da ku pêvajoya pêşkeftinê bilezîne û hêsan bike. Armanca vê serîlêdanê ev e ku daneyên ku bi karanîna algorîtmayên ku li aliyê paşîn û rasterast li ser Raspberry Pi-yê têne xebitandin xuyang bikin. Rûpel xwedan rêça beşê ye ku bi karanîna react-router ve hatî bicîh kirin, lê rûpela sereke ya balkêş rûpela sereke ye, ku tê de herikînek domdar a daneyê di demek rast de ji serverê bi karanîna teknolojiya WebSocket tê wergirtin. Raspberry Pi dengek nas dike, diyar dike ka ew ji databasa qeydkirî ya kesek taybetî ye, û navnîşek îhtîmalê ji xerîdar re dişîne. Xerîdar daneyên herî dawî yên têkildar nîşan dide, avatarê kesê ku bi îhtîmalek mezin di mîkrofonê de peyivî, û her weha hesta ku bi wan peyvan bilêv dike nîşan dide.

    OpenVINO hackathon: naskirina deng û hestan li ser Raspberry Pi
    Rûpelê malê bi pêşbîniyên nûvekirî

    encamê

    Ne mimkun bû ku em her tiştî wekî ku hatî plansaz kirin temam bikin, me bi tenê wextê me tune bû, ji ber vê yekê hêviya sereke di demo de bû, ku her tişt dê bixebite. Di danasînê de li ser her tişt çawa dixebite, wan çi model girtin, bi çi pirsgirêkan re rû bi rû man axivîn. Piştre beşa demo-yê bû - pispor bi rêzek rasthatî li jûreyê geriyan û nêzî her tîmekê bûn ku li prototîpa xebatê binerin. Wan jî pirs ji me kirin, her kesî bersiva xwe da, wan tevn li ser laptopê hiştin, û her tişt bi rastî wekî ku dihat hêvî kirin xebitî.

    Bihêle ez not bikim ku lêçûna giştî ya çareseriya me 150 $ bû:

    • Raspberry Pi 3 ~ 35 $
    • Google AIY Voice Bonnet (hûn dikarin heqê dengbêjiyê bistînin) ~ 15$
    • Intel NCS 2 ~ 100$

    Meriv çawa çêtir dike:

    • Qeydkirina ji xerîdar bikar bînin - bipirsin ku nivîsa ku bi rengek rasthatî hatî çêkirin bixwînin
    • Çend modelên din lê zêde bikin: hûn dikarin zayend û temen bi deng diyar bikin
    • Dengên hevdem ji hev veqetînin (diyarkirin)

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

    OpenVINO hackathon: naskirina deng û hestan li ser Raspberry Pi
    Westiyayî lê kêfxweş in

    Di dawiyê de ez dixwazim spasiya amadekar û beşdaran bikim. Di nav projeyên tîmên din de, me bixwe ji çareseriya çavdêriya cîhên parkkirinê yên belaş hez kir. Ji bo me, ew azmûnek hovane ya binavbûna hilber û pêşkeftinê bû. Ez hêvî dikim ku li herêman, di nav de li ser mijarên AI-ê, dê bêtir û bêtir bûyerên balkêş werin lidarxistin.

Source: www.habr.com

Add a comment