OpenVINO хакатон: эътирофи овоз ва эҳсосот дар Raspberry Pi

30 ноябрь — 1 декабрь дар Нижний Новгород барпо гардид OpenVINO хакатон. Аз иштирокчиён хоҳиш карда шуд, ки прототипи ҳалли маҳсулотро бо истифода аз асбобҳои Intel OpenVINO созанд. Ташкилкунандагон рӯйхати мавзӯъҳои тахминиро пешниҳод карданд, ки ҳангоми интихоби вазифа онҳоро роҳнамоӣ кардан мумкин аст, аммо қарори ниҳоӣ дар ихтиёри дастаҳо боқӣ монд. Гайр аз ин, истифодаи моделхое, ки ба махсулот дохил нашудаанд, ташвик карда шуд.

OpenVINO хакатон: эътирофи овоз ва эҳсосот дар Raspberry Pi

Дар ин мақола мо ба шумо дар бораи он ки чӣ гуна мо прототипи маҳсулотро офаридаем, ки бо он мо дар ниҳоят ҷои аввалро гирифтем.

Дар хактон зиёда аз 10 команда иштирок дошт. Хуб аст, ки баъзеи онҳо аз дигар минтақаҳо омадаанд. Ҷои баргузории ҳакатон маҷмааи «Кремлинский на Почаин» буд, ки дар дохили он аксҳои қадимии Нижний Новгород овехта шуда буданд, дар атрофи он! (Хотиррасон мекунам, ки дар айни замон идораи марказии Intel дар Нижний Новгород ҷойгир аст). Ба иштирокчиён барои навиштани код 26 соат вақт дода шуд ва дар охир онҳо бояд ҳалли худро пешниҳод кунанд. Бартарии алоҳида мавҷудияти сеанси намоишӣ буд, то боварӣ ҳосил кунад, ки ҳама чизи ба нақша гирифташуда воқеан иҷро шудааст ва дар презентатсия идеяҳо боқӣ намемонанд. Марч, газакҳо, хӯрок, ҳама чиз дар он ҷо буд!

Илова бар ин, Intel ихтиёрӣ камераҳои Raspberry PI, Neural Compute Stick 2 -ро пешниҳод кард.

Интихоби вазифа

Яке аз қисмҳои душвортарини омодагӣ ба ҳакатони озод ин интихоби мушкилот аст. Мо дарҳол тасмим гирифтем, ки чизеро пешниҳод кунем, ки ҳанӯз дар маҳсулот набуд, зеро эълон гуфта мешавад, ки ин хеле хуш омад.

Таҳлил карда моделҳо, ки ба маҳсулот дар нашри ҷорӣ дохил карда шудаанд, мо ба хулосае меоем, ки аксарияти онҳо мушкилоти гуногуни биниши компютерро ҳал мекунанд. Гузашта аз ин, дар соҳаи биниши компютерӣ пайдо кардани мушкилоте хеле душвор аст, ки онро бо истифодаи OpenVINO ҳал кардан ғайриимкон аст ва ҳатто агар онро ихтироъ кардан мумкин бошад ҳам, дар домени ҷамъиятӣ пайдо кардани моделҳои қаблан омодашуда душвор аст. Мо тасмим гирифтем, ки дар самти дигар - ба коркарди нутқ ва таҳлилҳо кор кунем. Биёед вазифаи ҷолиби шинохтани эҳсосотро аз нутқ дида бароем. Бояд гуфт, ки OpenVINO аллакай моделе дорад, ки эҳсосоти шахсро аз рӯи чеҳраи онҳо муайян мекунад, аммо:

  • Дар назария, метавон як алгоритми якҷояеро эҷод кард, ки ҳам дар садо ва ҳам тасвир кор кунад, ки бояд дақиқиро афзоиш диҳад.
  • Камераҳо одатан кунҷи тамошои танг доранд; барои фаро гирифтани майдони калон зиёда аз як камера лозим аст, садо чунин маҳдудият надорад.

Биёед идеяро инкишоф диҳем: биёед идеяи сегменти чаканаро ҳамчун асос гирем. Шумо метавонед қаноатмандии муштариёнро дар кассаҳои мағоза чен кунед. Агар яке аз муштариён аз хидмат норозӣ бошад ва оҳанги худро баланд кунад, шумо метавонед фавран ба администратор барои кӯмак занг занед.
Дар ин ҳолат, мо бояд шинохти овози инсонро илова кунем, ки ин ба мо имкон медиҳад, ки кормандони мағозаҳоро аз муштариён фарқ кунем ва барои ҳар як фард таҳлил пешниҳод кунем. Хуб, илова бар ин, рафтори худи кормандони мағозаро таҳлил кардан, фазои коллективро баҳо додан мумкин аст, хуб садо медиҳад!

Мо талаботро барои ҳалли худ таҳия мекунем:

  • Андозаи хурди дастгоҳи мавриди ҳадаф
  • Амалиёт дар вақти воқеӣ
  • Нархи паст
  • Миқёспазирии осон

Дар натиҷа, мо Raspberry Pi 3 c-ро ҳамчун дастгоҳи мавриди ҳадаф интихоб мекунем Intel NCS 2.

Дар ин ҷо муҳим аст, ки як хусусияти муҳими NCS-ро қайд кард - он бо меъмории стандартии CNN беҳтарин кор мекунад, аммо агар ба шумо лозим аст, ки моделеро бо қабатҳои фармоишӣ иҷро кунед, пас оптимизатсияи сатҳи пастро интизор шавед.

Танҳо як чизи хурде лозим аст: шумо бояд микрофон гиред. Микрофони муқаррарии USB кор мекунад, аммо он дар якҷоягӣ бо RPI хуб ба назар намерасад. Аммо ҳатто дар ин ҷо ҳалли аслан "наздик аст". Барои сабти овоз, мо тасмим гирифтем, ки тахтаи Voice Bonnet-ро аз маҷмӯа истифода барем Маҷмӯи овозии Google AIY, ки дар он микрофони стерео симдор мавҷуд аст.

Raspbian аз Анбори лоиҳаҳои AIY ва онро ба флешдор бор кунед, санҷед, ки микрофон бо истифода аз фармони зерин кор мекунад (он аудиоро 5 сония сабт мекунад ва онро дар файл захира мекунад):

arecord -d 5 -r 16000 test.wav

Ман фавран бояд қайд кунам, ки микрофон хеле ҳассос аст ва садоро хуб қабул мекунад. Барои ислоҳ кардани ин, биёед ба alsamixer равем, Дастгоҳҳои сабтро интихоб кунед ва сатҳи сигнали вурудро то 50-60% кам кунед.

OpenVINO хакатон: эътирофи овоз ва эҳсосот дар Raspberry Pi
Мо баданро бо файл тағир медиҳем ва ҳама чиз мувофиқ аст, шумо метавонед онро ҳатто бо сарпӯш пӯшед

Илова кардани тугмаи нишондиҳанда

Ҳангоми ҷудо кардани маҷмӯаи Voice AIY, мо дар хотир дорем, ки тугмаи RGB мавҷуд аст, ки чароғи паси онро тавассути нармафзор идора кардан мумкин аст. Мо "Google AIY Led" -ро ҷустуҷӯ мекунем ва ҳуҷҷатҳоро пайдо мекунем: https://aiyprojects.readthedocs.io/en/latest/aiy.leds.html
Чаро ин тугмаро барои намоиши эҳсосоти эътирофшуда истифода набаред, мо ҳамагӣ 7 синф дорем ва тугма 8 ранг дорад, бас аст!

Мо тугмаро тавассути GPIO ба Voice Bonnet пайваст мекунем, китобхонаҳои заруриро бор мекунем (онҳо аллакай дар маҷмӯаи тақсимот аз лоиҳаҳои AIY насб шудаанд)

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

Биёед як дикта эҷод кунем, ки дар он ҳар як эҳсос ранги мувофиқ дар шакли RGB Tuple ва объекти синфи aiy.leds.Leds дошта бошад, ки тавассути он мо рангро навсозӣ мекунем:

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

Ва ниҳоят, пас аз ҳар як пешгӯии нави эҳсосот, мо ранги тугмаро мувофиқи он навсозӣ мекунем (бо калид).

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

OpenVINO хакатон: эътирофи овоз ва эҳсосот дар Raspberry Pi
Тугма, сӯзон!

Кор бо овоз

Мо pyaudio-ро барои сабт кардани ҷараён аз микрофон ва webrtcvad барои филтр кардани садо ва муайян кардани овоз истифода хоҳем кард. Илова бар ин, мо навбат эҷод мекунем, ки ба он порчаҳои овозиро ба таври асинхронӣ илова ва хориҷ мекунем.

Азбаски webrtcvad дар андозаи порчаи додашуда маҳдудият дорад - он бояд ба 10/20/30 мс баробар бошад ва омӯзиши модел барои шинохти эҳсосот (чунон ки мо дертар хоҳем фаҳмид) дар маҷмӯи додаҳои 48 кГц анҷом дода шуд, мо порчаҳои андозаи 48000×20ms/1000×1(моно)=960 байтро сабт кунед. Webrtcvad барои ҳар яке аз ин порчаҳо True/False-ро бармегардонад, ки ба мавҷудият ё набудани овоз дар порча мувофиқат мекунад.

Биёед мантиқи зеринро амалӣ кунем:

  • Мо ба рӯйхат он порчаҳоеро, ки дар онҳо овоз ҳаст, илова мекунем; агар овоз набошад, ҳисобкунаки порчаҳои холиро зиёд мекунем.
  • Агар ҳисобкунаки порчаҳои холӣ >=30 (600 мс) бошад, мо ба андозаи рӯйхати қисмҳои ҷамъшуда назар мекунем; агар он >250 бошад, онро ба навбат илова мекунем; агар не, мо онро ҳисоб мекунем, ки дарозии аз сабт аст, кифоя нест, ки ба таъом он ба модели барои муайян кардани сухангӯй.
  • Агар ҳисобкунаки порчаҳои холӣ ҳоло ҳам <30 бошад ва андозаи рӯйхати порчаҳои ҷамъшуда аз 300 зиёд бошад, пас мо барои пешгӯии дақиқтар фрагментро ба навбат илова мекунем. (зеро эҳсосот бо мурури замон тағир меёбанд)

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

Вақти он расидааст, ки моделҳои қаблан омӯзонидашударо дар домени ҷамъиятӣ ҷустуҷӯ кунед, ба github, Google равед, аммо дар хотир доред, ки мо дар меъмории истифодашуда маҳдудият дорем. Ин як қисми хеле душвор аст, зеро шумо бояд моделҳоро дар маълумоти воридшудаи худ санҷед ва илова бар ин, онҳоро ба формати дохилии OpenVINO - IR (Намояндагии мобайнӣ) табдил диҳед. Мо тақрибан 5-7 ҳалли гуногунро аз github санҷидем ва агар модели шинохти эҳсосот фавран кор кунад, пас бо шинохти овоз мо бояд дертар интизор шавем - онҳо меъмории мураккабтарро истифода мебаранд.

Мо ба чизҳои зерин диққат медиҳем:

  • Эҳсосот аз овоз - https://github.com/alexmuhr/Voice_Emotion
    Он аз рӯи принсипи зерин кор мекунад: аудио ба порчаҳои андозаи муайян бурида мешавад, барои ҳар яке аз ин порчаҳо мо интихоб мекунем MFCC ва сипас онҳоро ҳамчун вуруд ба CNN пешниҳод кунед
  • Шинохти овоз - https://github.com/linhdvu14/vggvox-speaker-identification
    Дар ин ҷо, ба ҷои MFCC, мо бо спектрограмма кор мекунем, пас аз FFT мо сигналро ба CNN мерасонем, ки дар баромад мо муаррифии вектории овозро ба даст меорем.

Минбаъд мо дар бораи табдил додани моделҳо, аз назария сар карда, сӯҳбат хоҳем кард. OpenVINO якчанд модулҳоро дар бар мегирад:

  • Модели зоопаркро кушоед, ки моделҳо метавонанд аз онҳо истифода шаванд ва ба маҳсулоти шумо дохил карда шаванд
  • Model Optimzer, ба шарофати он шумо метавонед моделро аз форматҳои чаҳорчӯбаи гуногун (Tensorflow, ONNX ва ғайра) ба формати намояндагии мобайнӣ табдил диҳед, ки мо минбаъд бо он кор хоҳем кард.
  • Engine Inference ба шумо имкон медиҳад, ки моделҳоро дар формати IR дар протсессори Intel, микросхемаҳои Myriad ва суръатбахшии Neural Compute Stick иҷро кунед.
  • Версияи самараноки OpenCV (бо дастгирии Inference Engine)
    Ҳар як модел дар формати IR бо ду файл тавсиф карда мешавад: .xml ва .bin.
    Моделҳо ба формати IR тавассути Model Optimizer ба таври зерин табдил дода мешаванд:

    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 ба шумо имкон медиҳад, ки формати маълумотро интихоб кунед, ки модел бо он кор хоҳад кард. FP32, FP16, INT8 дастгирӣ карда мешавад. Интихоби намуди оптималии маълумот метавонад баланд бардоштани самаранокии хуб диҳад.
    --input_shape андозаи маълумоти воридшударо нишон медиҳад. Қобилияти ба таври динамикӣ тағир додани он дар API C++ мавҷуд аст, аммо мо он қадар дур кофта нашудаем ва танҳо онро барои яке аз моделҳо ислоҳ кардем.
    Сипас, биёед кӯшиш кунем, ки модели аллакай табдилёфтаро дар формати IR тавассути модули DNN ба OpenCV бор кунем ва ба он ирсол кунем.

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

    Сатри охирин дар ин ҳолат ба шумо имкон медиҳад, ки ҳисобҳоро ба Neural Compute Stick равона кунед, ҳисобҳои асосӣ дар протсессор анҷом дода мешаванд, аммо дар ҳолати Raspberry Pi ин кор намекунад, ба шумо чӯб лозим мешавад.

    Баъдан, мантиқ чунин аст: мо аудиои худро ба тирезаҳои андозаи муайян тақсим мекунем (барои мо он 0.4 с аст), мо ҳар яке аз ин тирезаҳоро ба MFCC табдил медиҳем, ки мо онро ба шабака интиқол медиҳем:

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

    Баъд, биёед синфи маъмултаринро барои ҳама тирезаҳо гирем. Ҳалли оддӣ, аммо барои ҳакатон ба шумо лозим нест, ки чизи аз ҳад бемаънӣ пайдо кунед, танҳо агар вақт дошта бошед. Мо ҳанӯз кори зиёде дорем, пас биёед идома диҳем - мо бо шинохти овоз сару кор хоҳем кард. Як навъ базаи маълумотро ташкил кардан лозим аст, ки дар он спектрограммахои овозхои пешакй сабтшуда нигох дошта мешаванд. Азбаски вақти кам мондааст, мо то ҳадди имкон ин масъаларо ҳал мекунем.

    Махз, мо барои сабти порчаи овоз скрипт месозем (он ҳамон тавре, ки дар боло тавсиф шудааст, кор мекунад, танҳо ҳангоми қатъ кардани клавиатура овозро дар файл нигоҳ медорад).

    Биёед кӯшиш кунем:

    python3 voice_db/record_voice.py test.wav

    Мо овози чанд нафарро сабт мекунем (дар ҳолати мо, се аъзои даста)
    Минбаъд, барои ҳар як овози сабтшуда мо табдили фаврии фуриро иҷро мекунем, спектрограмма мегирем ва онро ҳамчун массиви нумпӣ (.npy) захира мекунем:

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

    Тафсилоти бештар дар файл create_base.py
    Дар натиҷа, вақте ки мо скрипти асосиро иҷро мекунем, мо дар ибтидо аз ин спектрограммаҳо дохилкунӣ мегирем:

    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)

    Пас аз гирифтани дохилкунӣ аз сегменти садошуда, мо метавонем муайян кунем, ки он ба кӣ тааллуқ дорад, бо назардошти масофаи косинус аз гузаргоҳ то ҳама овозҳои пойгоҳи додаҳо (қадар хурдтар, эҳтимоли бештар аст) - барои намоиш мо остонаро муқаррар мекунем. ба 0.3):

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

    Дар охир, мехоҳам қайд намоям, ки суръати хулосабарорӣ зуд буд ва имкон дод, ки 1-2 модели дигар илова карда шавад (барои намунаи 7 сония барои хулосабарорӣ 2.5 вақт лозим буд). Мо дигар вақт барои илова кардани моделҳои нав надоштем ва ба навиштани прототипи веб-барнома тамаркуз кардем.

    Барномаи веб

    Нуктаи муҳим: мо роутерро аз хона бо худ мегирем ва шабакаи маҳаллии худро танзим мекунем, он барои пайваст кардани дастгоҳ ва ноутбукҳо тавассути шабака кӯмак мекунад.

    Дар пушти сар як канали паёмӣ байни фронт ва Raspberry Pi мебошад, ки ба технологияи websocket (http аз протоколи tcp) асос ёфтааст.

    Марҳилаи аввал ин гирифтани иттилооти коркардшуда аз raspberry мебошад, яъне пешгӯиҳо дар json бастабандишуда, ки дар нимсолаи сафари худ дар пойгоҳи додаҳо захира карда мешаванд, то омор дар бораи заминаи эмотсионалии корбар дар ин давра тавлид шавад. Пас аз он ин баста ба интерфейс фиристода мешавад, ки он обунаро истифода мебарад ва бастаҳоро аз нуқтаи ниҳоии websocket қабул мекунад. Тамоми механизми пуштибонӣ бо забони голанг сохта шудааст; он интихоб шудааст, зеро он барои вазифаҳои асинхронӣ, ки горутинҳо хуб кор мекунанд, мувофиқ аст.
    Ҳангоми дастрасӣ ба нуқтаи ниҳоӣ, корбар ба қайд гирифта мешавад ва ба сохтор ворид карда мешавад, пас паёми ӯ қабул карда мешавад. Ҳам корбар ва ҳам паём ба як маркази умумӣ ворид карда мешаванд, ки аз он паёмҳо аллакай минбаъд фиристода мешаванд (ба фронти обунашуда) ва агар корбар пайвастро қатъ кунад (малина ё фронт), пас обунаи ӯ бекор карда мешавад ва ӯ аз он хориҷ карда мешавад. марказ.

    OpenVINO хакатон: эътирофи овоз ва эҳсосот дар Raspberry Pi
    Мо интизори пайвастшавӣ аз қафо ҳастем

    Front-end як барномаи вебест, ки дар JavaScript бо истифода аз китобхонаи React барои суръат ва содда кардани раванди таҳия навишта шудааст. Мақсади ин барнома визуалӣ кардани маълумотест, ки бо истифода аз алгоритмҳое, ки дар паҳлӯи ақиб ва бевосита дар Raspberry Pi кор мекунанд, ба даст оварда шудаанд. Саҳифа дорои масири бахшӣ мебошад, ки бо истифода аз реакт-роутер амалӣ карда мешавад, аммо саҳифаи асосии таваҷҷӯҳ саҳифаи асосӣ мебошад, ки дар он ҷараёни доимии маълумот дар вақти воқеӣ аз сервер бо истифода аз технологияи WebSocket қабул карда мешавад. Raspberry Pi овозро муайян мекунад, муайян мекунад, ки оё он ба шахси мушаххас тааллуқ дорад, аз пойгоҳи додаҳои сабтшуда ва рӯйхати эҳтимолиятро ба муштарӣ мефиристад. Мизоҷ маълумоти охирини мувофиқро нишон медиҳад, аватари шахсеро, ки эҳтимолан бо микрофон сухан гуфта буд ва инчунин эҳсосоте, ки ӯ калимаҳоро талаффуз мекунад, нишон медиҳад.

    OpenVINO хакатон: эътирофи овоз ва эҳсосот дар Raspberry Pi
    Саҳифаи асосӣ бо пешгӯиҳои навшуда

    хулоса

    Ҳама чизро тавре ба нақша гирифтан мумкин набуд, мо танҳо вақт надоштем, аз ин рӯ умеди асосӣ дар намоиш буд, ки ҳама чиз кор хоҳад кард. Дар презентатсия онҳо дар бораи он, ки ҳама чиз чӣ гуна кор мекунад, кадом моделҳоро гирифтаанд, ба кадом мушкилот дучор шуданд, сӯҳбат карданд. Минбаъд қисми намоишӣ буд - коршиносон бо тартиби тасодуфӣ дар гирду атрофи толор мегаштанд ва ба ҳар як даста барои дидани прототипи корӣ муроҷиат карданд. Онҳо ба мо саволҳо доданд, ҳама ба қисми худ ҷавоб доданд, онҳо вебро дар ноутбук тарк карданд ва ҳама чиз воқеан тавре ки интизор буд, кор кард.

    Бояд қайд кунам, ки арзиши умумии ҳалли мо $150 буд:

    • Raspberry Pi 3 ~ 35 доллар
    • Google AIY Voice Bonnet (шумо метавонед хироҷи сухангӯро гиред) ~ 15 доллар
    • Intel NCS 2 ~ 100$

    Чӣ тавр беҳтар кардан:

    • Бақайдгирии муштариро истифода баред - хоҳиш кунед, ки матнеро, ки ба таври тасодуфӣ тавлид шудааст, хонед
    • Якчанд модели дигарро илова кунед: шумо метавонед ҷинс ва синну солро бо овоз муайян кунед
    • Овозҳои ҳамзамон садои ҷудогона (диаризатсия)

    Анбор: https://github.com/vladimirwest/OpenEMO

    OpenVINO хакатон: эътирофи овоз ва эҳсосот дар Raspberry Pi
    Хаста, вале хурсандем

    Дар хотима мехоҳам ба созмондиҳандагон ва иштирокчиён ташаккур мегӯям. Дар байни лоиҳаҳои дастаҳои дигар, мо шахсан роҳи ҳалли мониторинги таваққуфгоҳи ройгонро дӯст медоштем. Барои мо, ин як таҷрибаи аҷиби таъмид дар маҳсулот ва рушд буд. Умедворам, ки дар минтақаҳо чорабиниҳои ҷолиб бештар, аз ҷумла дар мавзӯъҳои AI баргузор мешаванд.

Манбаъ: will.com

Илова Эзоҳ