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.
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!
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%.
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:
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:
Emosi saka swara - https://github.com/alexmuhr/Voice_Emotion
Kerjane miturut prinsip ing ngisor iki: audio dipotong dadi ukuran tartamtu, kanggo saben bagean kasebut kita pilih MFCC lan banjur ngirim minangka input kanggo CNN
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:
--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):
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.
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.
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
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.