Hackathon OpenVINO: ngenali swara lan emosi ing Raspberry Pi

30 November - 1 Desember ing Nizhny Novgorod dianakake OpenVINO hackathon. Peserta dijaluk nggawe prototipe solusi produk nggunakake toolkit Intel OpenVINO. Penyelenggara ngusulake dhaptar topik kira-kira sing bisa dipandu nalika milih tugas, nanging keputusan pungkasan tetep ana ing tim. Kajaba iku, panggunaan model sing ora kalebu ing produk kasebut dianjurake.

Hackathon OpenVINO: ngenali swara lan emosi ing Raspberry Pi

Ing artikel iki kita bakal pitutur marang kowe bab carane kita nggawe prototipe produk, kang pungkasanipun kita njupuk Panggonan pisanan.

Luwih saka 10 tim melu hackathon. Apik banget yen ana sing teka saka wilayah liya. Panggonan kanggo hackathon yaiku kompleks "Kremlinsky on Pochain", ing ngendi foto-foto kuno Nizhny Novgorod digantung ing jero, ing rombongan! (Aku ngelingake yen ing wayahe kantor pusat Intel dumunung ing Nizhny Novgorod). Peserta diwenehi 26 jam kanggo nulis kode, lan ing pungkasan kudu menehi solusi. Kauntungan sing kapisah yaiku anané sesi demo kanggo mesthekake yen kabeh sing direncanakake bener-bener ditindakake lan ora tetep dadi ide ing presentasi kasebut. Merch, cemilan, pangan, kabeh ana uga!

Kajaba iku, Intel nyedhiyakake kamera opsional, Raspberry PI, Neural Compute Stick 2.

Pilihan tugas

Salah sawijining bagean sing paling angel kanggo nyiapake hackathon gratis yaiku milih tantangan. Kita langsung mutusake kanggo nggawe barang sing durung ana ing produk kasebut, amarga woro-woro kasebut ujar manawa iki sambutan banget.

Sawise analisa model, sing kalebu ing prodhuk ing release saiki, kita teka menyang kesimpulan sing paling wong ngatasi macem-macem masalah sesanti komputer. Menapa malih, angel banget kanggo nemokake masalah ing bidang visi komputer sing ora bisa ditanggulangi kanthi nggunakake OpenVINO, lan sanajan ana sing bisa diciptakake, angel golek model sing wis dilatih ing domain umum. Kita mutusake kanggo nggali arah liyane - menyang pangolahan wicara lan analytics. Ayo nimbang tugas menarik kanggo ngenali emosi saka wicara. Mesthine OpenVINO wis duwe model sing nemtokake emosi wong adhedhasar pasuryane, nanging:

  • Ing teori, bisa nggawe algoritma gabungan sing bisa digunakake ing swara lan gambar, sing kudu nambah akurasi.
  • Kamera biasane duwe sudut pandang sing sempit; luwih saka siji kamera dibutuhake kanggo nutupi area sing amba; swara ora duwe watesan kaya ngono.

Ayo berkembang ide: ayo njupuk ide kanggo segmen ritel minangka basis. Sampeyan bisa ngukur kepuasan pelanggan ing checkouts toko. Yen salah siji saka pelanggan ora marem karo layanan lan wiwit mundhakaken muni, sampeyan bisa langsung nelpon administrator kanggo bantuan.
Ing kasus iki, kita kudu nambah pangenalan swara manungsa, iki bakal ngidini kita mbedakake karyawan toko saka pelanggan lan nyedhiyakake analytics kanggo saben individu. Kajaba iku, bakal bisa nganalisa prilaku karyawan toko dhewe, ngevaluasi swasana ing tim, muni apik!

Kita ngrumusake syarat kanggo solusi kita:

  • Ukuran cilik saka piranti target
  • Operasi wektu nyata
  • Kurang rega
  • Skalabilitas gampang

Akibaté, kita milih Raspberry Pi 3 c minangka piranti target Intel NCS 2.

Kene iku penting kanggo Wigati siji fitur penting NCS - iku paling apik karo arsitektur CNN standar, nanging yen sampeyan kudu mbukak model karo lapisan adat ing, banjur ngarepake Optimization tingkat kurang.

Mung ana siji sing kudu ditindakake: sampeyan kudu njupuk mikropon. A mikropon USB biasa bakal nindakake, nanging ora bakal katon apik bebarengan karo RPI. Nanging malah ing kene solusi kasebut secara harfiah "dumunung ing cedhak." Kanggo ngrekam swara, kita mutusake nggunakake papan Voice Bonnet saka kit Google AIY Voice Kit, sing ana mikropon stereo kabel.

Download Raspbian saka Repositori proyek AIY lan upload menyang flash drive, nyoba mikropon nggunakake printah ing ngisor iki (bakal ngrekam audio 5 detik dawa lan disimpen ing file):

arecord -d 5 -r 16000 test.wav

Aku kudu langsung nyathet yen mikropon sensitif banget lan njupuk swara kanthi apik. Kanggo ndandani iki, ayo pindhah menyang alsamixer, pilih Njupuk piranti lan nyuda tingkat sinyal input kanggo 50-60%.

Hackathon OpenVINO: ngenali swara lan emosi ing Raspberry Pi
Kita ngowahi awak kanthi file lan kabeh cocog, sampeyan bisa malah nutup kanthi tutup

Nambah tombol indikator

Nalika njupuk AIY Voice Kit, kita elinga yen ana tombol RGB, lampu latar sing bisa dikontrol dening piranti lunak. Kita nggoleki "Google AIY Led" lan nemokake dokumentasi: https://aiyprojects.readthedocs.io/en/latest/aiy.leds.html
Apa ora nggunakake tombol iki kanggo nampilake emosi dikenali, kita duwe mung 7 kelas, lan tombol wis 8 werna, mung cukup!

Kita nyambungake tombol liwat GPIO menyang Voice Bonnet, mbukak perpustakaan sing dibutuhake (wis diinstal ing kit distribusi saka proyek AIY)

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

Ayo nggawe dict sing saben emosi bakal duwe warna sing cocog ing wangun RGB Tuple lan obyek kelas aiy.leds.Leds, sing bakal nganyari warna:

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

Lan pungkasanipun, sawise saben prediksi anyar saka emosi, kita bakal nganyari werna tombol ing sesuai karo iku (dening tombol).

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

Hackathon OpenVINO: ngenali swara lan emosi ing Raspberry Pi
Tombol, bakar!

Nggarap swara

Kita bakal nggunakake pyaudio kanggo njupuk stream saka mikropon lan webrtcvad kanggo nyaring gangguan lan ndeteksi swara. Kajaba iku, kita bakal nggawe antrian sing bakal ditambahake lan mbusak kutipan swara kanthi asinkron.

Wiwit webrtcvad duwe watesan ing ukuran fragmen sing diwenehake - kudu padha karo 10/20/30ms, lan latihan model kanggo ngenali emosi (kaya sing bakal kita sinau mengko) ditindakake ing dataset 48kHz, kita bakal njupuk potongan ukuran 48000×20ms/1000×1(mono)=960 bita. Webrtcvad bakal ngasilake Bener / Palsu kanggo saben potongan kasebut, sing cocog karo anane utawa ora ana swara ing potongan kasebut.

Ayo ngleksanakake logika ing ngisor iki:

  • Kita bakal nambahake dhaptar potongan-potongan sing ana voting; yen ora ana swara, banjur kita bakal nambah jumlah potongan kosong.
  • Yen counter potongan kosong yaiku> = 30 (600 ms), banjur kita ndeleng ukuran dhaptar potongan sing akumulasi; yen> 250, banjur ditambahake menyang antrian; yen ora, kita nimbang dawane. saka rekaman ora cukup kanggo Feed menyang model kanggo ngenali speaker.
  • Yen counter potongan kosong isih <30, lan ukuran dhaptar potongan akumulasi ngluwihi 300, banjur kita bakal nambah fragmen menyang antrian kanggo prediksi sing luwih akurat. (amarga emosi cenderung owah saka wektu)

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

Wektu kanggo nggoleki model sing wis dilatih ing domain umum, pindhah menyang github, Google, nanging elinga yen kita duwe watesan babagan arsitektur sing digunakake. Iki minangka bagean sing rada angel, amarga sampeyan kudu nyoba model ing data input, lan saliyane, ngowahi menyang format internal OpenVINO - IR (Representasi Intermediate). Kita nyoba udakara 5-7 solusi sing beda saka github, lan yen model kanggo ngenali emosi bisa langsung, mula kanthi pangenalan swara kudu ngenteni luwih suwe - nggunakake arsitektur sing luwih rumit.

Kita fokus ing ngisor iki:

Sabanjure kita bakal ngomong babagan ngowahi model, diwiwiti kanthi teori. OpenVINO kalebu sawetara modul:

  • Bukak Model Zoo, model sing bisa digunakake lan kalebu ing produk sampeyan
  • Model Optimzer, thanks kanggo sampeyan bisa ngowahi model saka macem-macem format framework (Tensorflow, ONNX etc) menyang format Intermediate Representation, karo kang kita bakal bisa luwih.
  • Mesin Inferensi ngidini sampeyan mbukak model ing format IR ing prosesor Intel, Kripik Myriad lan akselerator Neural Compute Stick
  • Versi OpenCV sing paling efisien (kanthi dhukungan Inferensi Engine)
    Saben model ing format IR diterangake dening rong file: .xml lan .bin.
    Model diowahi dadi format IR liwat Model Optimizer kaya ing ngisor iki:

    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 ngidini sampeyan milih format data sing bakal digunakake model kasebut. FP32, FP16, INT8 didhukung. Milih jinis data sing optimal bisa menehi dorongan kinerja sing apik.
    --input_shape nuduhake ukuran data input. Kemampuan kanggo ngganti dinamis misale jek ana ing C ++ API, nanging kita ora dig sing adoh lan mung ndandani iku kanggo salah siji model.
    Sabanjure, ayo nyoba mbukak model sing wis diowahi ing format IR liwat modul DNN menyang OpenCV lan nerusake menyang.

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

    Baris pungkasan ing kasus iki ngijini sampeyan kanggo pangalihan petungan menyang Neural Compute Stick, petungan dhasar dileksanakake ing prosesor, nanging ing cilik saka Raspberry Pi iki ora bakal bisa, sampeyan kudu kelet.

    Sabanjure, logika kaya ing ngisor iki: kita dibagi audio menyang jendhela ukuran tartamtu (kanggo kita iku 0.4 s), kita ngowahi saben jendhela iki menyang MFCC, kang banjur feed menyang kothak.

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

    Sabanjure, ayo njupuk kelas sing paling umum kanggo kabeh windows. A solusi prasaja, nanging kanggo hackathon sampeyan ora perlu teka munggah karo soko banget abstruse, mung yen sampeyan duwe wektu. Isih akeh tugas sing kudu ditindakake, mula ayo maju - kita bakal ngatasi pangenalan swara. Sampeyan kudu nggawe sawetara jinis database ing ngendi spektrogram swara sing wis direkam bakal disimpen. Amarga wektu isih sithik, kita bakal ngrampungake masalah iki kanthi sabisa.

    Yaiku, kita nggawe skrip kanggo ngrekam kutipan swara (kerjane kanthi cara sing padha kaya sing kasebut ing ndhuwur, mung nalika diselani saka keyboard bakal nyimpen swara menyang file).

    Ayo jajal:

    python3 voice_db/record_voice.py test.wav

    Kita ngrekam swara sawetara wong (ing kasus kita, telung anggota tim)
    Sabanjure, kanggo saben swara sing direkam, kita nindakake transformasi fourier kanthi cepet, entuk spektrogram lan simpen minangka array numpy (.npy):

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

    Rincian liyane ing file create_base.py
    Akibaté, nalika kita mbukak skrip utama, kita bakal entuk embeddings saka spektrogram iki ing wiwitan:

    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)

    Sawise nampa embedding saka segmen sing nyuworo, kita bakal bisa nemtokake sapa sing dadi kagungane kanthi njupuk jarak kosinus saka wacana menyang kabeh swara ing database (sing luwih cilik, luwih cenderung) - kanggo demo kita nyetel ambang. iki 0.3):

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

    Ing pungkasan, Aku kaya Wigati sing kacepetan inferensi cepet lan digawe iku bisa kanggo nambah 1-2 model liyane (kanggo sampel 7 detik dawa njupuk 2.5 kanggo inferensi). Kita ora duwe wektu maneh kanggo nambah model anyar lan fokus kanggo nulis prototipe aplikasi web.

    Aplikasi web

    Titik penting: kita njupuk dalan saka omah lan nyetel jaringan lokal, mbantu nyambungake piranti lan laptop liwat jaringan.

    Backend minangka saluran pesen end-to-end antarane ngarep lan Raspberry Pi, adhedhasar teknologi websocket (http liwat protokol tcp).

    Tahap pisanan yaiku nampa informasi sing diproses saka raspberry, yaiku, prediktor sing dikemas ing json, sing disimpen ing database separo perjalanan supaya statistik bisa diasilake babagan latar mburi emosi pangguna kanggo periode kasebut. Paket iki banjur dikirim menyang frontend, sing nggunakake langganan lan nampa paket saka endpoint websocket. Mekanisme backend kabeh dibangun nganggo basa golang, dipilih amarga cocog kanggo tugas sing ora sinkron, sing ditangani kanthi apik.
    Nalika ngakses titik pungkasan, pangguna didaftar lan mlebu menyang struktur, banjur pesen kasebut ditampa. Pangguna lan pesen dilebokake ing hub umum, saka ngendi pesen wis dikirim luwih lanjut (menyang ngarep langganan), lan yen pangguna nutup sambungan kasebut (raspberry utawa ngarep), mula langganane dibatalake lan dicopot saka hub.

    Hackathon OpenVINO: ngenali swara lan emosi ing Raspberry Pi
    Kita ngenteni sambungan saka mburi

    Front-end minangka aplikasi web sing ditulis ing JavaScript nggunakake perpustakaan React kanggo nyepetake lan nyederhanakake proses pangembangan. Tujuan aplikasi iki yaiku kanggo nggambarake data sing dipikolehi nggunakake algoritma sing mlaku ing sisih mburi lan langsung ing Raspberry Pi. Kaca kasebut nduweni routing sectional sing dileksanakake nggunakake react-router, nanging kaca utama kapentingan yaiku kaca utama, ing ngendi aliran data sing terus-terusan ditampa ing wektu nyata saka server nggunakake teknologi WebSocket. Raspberry Pi ndeteksi swara, nemtokake manawa iku belongs kanggo wong tartamtu saka database kedhaftar, lan ngirim dhaftar kemungkinan kanggo klien. Klien nampilake data sing paling anyar sing relevan, nampilake avatar wong sing paling kamungkinan ngomong ing mikropon, uga emosi sing ngucapake tembung kasebut.

    Hackathon OpenVINO: ngenali swara lan emosi ing Raspberry Pi
    Kaca ngarep kanthi ramalan sing dianyari

    kesimpulan

    Ora bisa ngrampungake kabeh kaya sing direncanakake, kita mung ora duwe wektu, mula pangarep-arep utama ana ing demo, kabeh bakal bisa ditindakake. Ing presentation padha ngomong bab carane kabeh bisa, model apa padha njupuk, apa masalah padha ketemu. Sabanjure yaiku bagean demo - para ahli mlaku-mlaku ngubengi ruangan kanthi acak lan nyedhaki saben tim kanggo ndeleng prototipe sing digunakake. Dheweke uga takon pitakon, kabeh wong mangsuli bageane, dheweke ninggalake web ing laptop, lan kabeh bisa ditindakake kaya sing dikarepake.

    Elinga yen total biaya solusi kita yaiku $150:

    • Raspberry Pi 3 ~ $35
    • Google AIY Voice Bonnet (sampeyan bisa njupuk biaya respeaker) ~ 15$
    • Intel NCS 2 ~ 100$

    Cara nambah:

    • Gunakake registrasi saka klien - takon kanggo maca teks sing digawe kanthi acak
    • Tambah sawetara model liyane: sampeyan bisa nemtokake jender lan umur kanthi swara
    • Pisah swara bebarengan (diarisasi)

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

    Hackathon OpenVINO: ngenali swara lan emosi ing Raspberry Pi
    Kesel nanging kita seneng

    Pungkasaning atur kula ngaturaken agunging panuwun dhumateng panatacara saha para peserta. Ing antarane proyek tim liyane, kita seneng karo solusi kanggo ngawasi papan parkir gratis. Kanggo kita, iki minangka pengalaman kecemplung ing produk lan pangembangan. Muga-muga acara sing luwih menarik bakal dianakake ing wilayah kasebut, kalebu topik AI.

Source: www.habr.com

Add a comment