Найпростіше управління комп'ютером за допомогою голосу


Якщо вас цікавить, як допомогти обездвиженному людині управляти комп'ютером для спілкування із зовнішнім світом – вам сюди. Якщо вам цікаво, яке відношення до цього мають крейда-частотні кепстральные коефіцієнти і нейронні мережі – вам теж сюди.

Частина I. Програма для керування комп'ютером за допомогою голосу
До мене звернувся чоловік з проханням написати програму, яка дозволила б керувати комп'ютерною мишею за допомогою голосу. Тоді я і уявити собі не міг, що, практично повністю паралізований чоловік, який навіть не може сам повернути голову, а може лише розмовляти, здатний розвинути бурхливу діяльність, допомагаючи собі та іншим жити активним життям, отримувати нові знання і навички, працювати і заробляти, спілкуватися з іншими людьми по всьому світу, брати участь у конкурсі соціальних проектів.

Дозволю собі привести тут пару посилань на сайти, автором і/або ідейним натхненником яких є ця людина – Олександр Макарчук з міста Борисов, Білорусь:

«У Сови» — школа дистанційного навчання для людей з обмеженими можливостями. sova.by
«Без обмежень» — поради для тих, кому потрібно працювати на комп'ютері без рук bezogranicheniy.ru


Для роботи на комп'ютері Олександр використовував програму «Vocal Joystick» — розроблення студентів Університету штату Вашингтон, виконану на кошти Національного Наукового Фонду (NSF). См. melodi.ee.washington.edu/vj

Не втримавсядо Речі, на сайті університету (http://www.washington.edu/ 90% статей саме про гроші. Важко знайти що-небудь про наукову роботу. Ось, наприклад, витяги з першої сторінки: «Те, випускник університету, раніше харчувався грибами і з працею платив за квартиру. Тепер він старший менеджер ІТ-компанії і кредитує університет», «Великі Дані допомагають бездомним», «Компанія зобов'язалася заплатити 5 мільйонів доларів за новий навчальний корпус».

Одному мені ріже око?


Програма була зроблена в 2005-2009 роках і добре працювала на Windows XP. В більш свіжих версій Windows програма може зависнути, що неприйнятно для людини, яка не може встати зі стільця і її перезапустити. Тому програму потрібно було переробити.

Вихідних текстів немає, є лише окремі публікації, що відкривають технології, на яких вона заснована (MFCC, MLP – про це читайте у другій частині).
За образом і подобою була написана нова програма (за три місяці).

Власне, подивитися, як вона працює, можна тут:


Завантажити програму та/або подивитися вихідні коди можна тут:
https://github.com/MastaLomaster/mishkinamish

Ніяких особливих дій для установки програми виконувати не треба, просто натискаєте на неї, та запускаєте. Єдине, в деяких випадках потрібно, щоб вона була запущена від імені адміністратора (наприклад, при роботі з віртуальною клавіатурою «Comfort Keys Pro»):



Мабуть, варто згадати тут і про інші речі, які я раніше робив для того, щоб можна було управляти комп'ютером без рук.

Якщо у вас є можливість повертати голову, то гарною альтернативою eViacam може послужити гіроскоп, що кріпиться до голови. Ви отримаєте швидке і точне позиціювання курсору та незалежність від освітлення.

Детальніше – тут: https://habrahabr.ru/post/213715/

Якщо ви можете рухати тільки зіницями очей, то можна використовувати трекер напрямку погляду і програму до нього (можуть бути складності, якщо ви носите окуляри).

Детальніше – тут: https://habrahabr.ru/post/208108/

Частина II. Як це влаштовано?
З опублікованих матеріалів про програму «Vocal Joystick» було відомо, що працює вона наступним чином:
  1. нарізка звукового потоку на кадри по 25 мілісекунд з перехлестом по 10 мілісекунд
  2. отримання 13 кепстральных коефіцієнтів (MFCC) для кожного кадру
  3. перевірка того, що вимовляється один з 6 запам'ятованих звуків (4 голосних і 2 приголосних) за допомогою багатошарового персептрона (MLP)
  4. втілення знайдених звуків в рух/клацання миші


Перша задача примітна лише тим, що для її вирішення в реальному часі довелося вводити в програму три додаткових потоку, так як зчитування даних з мікрофона, обробка звуку, програвання звуку через звукову карту відбуваються асинхронно.

Остання задача просто реалізується за допомогою SendInput функції.

Найбільший же інтерес, мені здається, представляють друга і третя завдання. Отже.

Завдання №2. Отримання 13 кепстральных коефіцієнтів
Якщо хто не в темі – основна проблема впізнавання звуків комп'ютером полягає в наступному: важко порівняти два звуку, так як дві несхожі по контуру звукові хвилі можуть звучати схоже з точки зору людського сприйняття.

І серед тих, хто займається розпізнаванням мови, йде пошук «філософського каменя» — набору ознак, які б однозначно класифікували звукову хвилю.

З тих ознак, що доступні широкій публіці і описані в підручниках, найбільше поширення одержали так звані крейда-частотні кепстральные коефіцієнти (MFCC).

Історія їх така, що спочатку вони призначалися зовсім для іншого, а саме, для придушення луни в сигналі (пізнавальну статтю на цю тему написали шановні Оппенгейм і Боярин, хай буде радість в будинках цих благородних мужів. См. A. V. Oppenheim and R. W. Schafer, «From Frequency to Quefrency: A History of the Cepstrum»).

Але людина влаштована так, що він схильний використовувати те, що йому краще знайоме. І тим, хто займався мовними сигналами, що прийшло в голову використовувати вже готове подання сигналу у вигляді MFCC. Виявилося, що, загалом, працює. (Один мій знайомий, спеціаліст по вентиляційних систем, коли я його запитав, як би зробити дачну альтанку, запропонував використовувати вентиляційні короби. Просто тому, що їх він знав краще за інших будівельних матеріалів).

Є MFCC хорошим класифікатором для звуків? Я б не сказав. Один і той же звук, вимовлені мною в різні мікрофони, потрапляє в різні області простору MFCC-коефіцієнтів, а ідеальний класифікатор намалював би їх поруч. Тому, зокрема, при зміні мікрофона ви повинні заново навчати програму.


Це всього лише одна з проекцій 13-вимірного простору MFCC в 3-мірне, але і на ній видно, що я маю на увазі – червоні, фіолетові і сині точки отримані від різних мікрофонів: (Plantronix, вбудований масив мікрофонів, Jabra), але звук вимовлявся один.

Однак, оскільки нічого кращого я запропонувати не можу, також скористаюся стандартною методикою – обчисленням MFCC-коефіцієнтів.

Щоб не помилитися в реалізації, у перших версіях програми в якості основи був використаний код з добре відомої програми CMU Sphinx, точніше, її реалізації на мові C, именующейся pocketsphinx, розробленої в Університеті Карнегі-Меллона (світ з ними обома! © Хоттабич).

Вихідні коди pocketsphinx відкриті, та ось невдача – якщо ви їх використовуєте, то повинні у своїй програмі (як в исходниках, так і в виконуваному модулі) прописати текст, що містить, зокрема, наступне:

* This work was supported in part by funding from the Defense Advanced
 
* Research Projects Agency and the National Science Foundation of the
 
* United States of America, and the CMU Sphinx Speech Consortium.
 


Мені це здалося неприйнятним, і довелося переписати код. Це позначилося на швидкодії програми (в кращу сторону, до речі, хоча «читабельність» коду кілька постраждала). Багато в чому завдяки використанню бібліотек «Intel Performance Primitives», але і сам дещо оптимізував, начебто MEL-фільтра. Тим не менш, перевірка на тестових даних показала, що отримуються MFCC-коефіцієнти повністю аналогічні тим, що отримуються за допомогою, наприклад, утиліти sphinx_fe.

У програмах sphinxbase обчислення MFCC-коефіцієнтів проводиться наступними кроками:
крок Функція sphinxbase Суть операції
1 fe_pre_emphasis З поточного відліку віднімається велика частина попереднього відліку (наприклад, 0.97 від його значення). Примітивний фільтр, отбрасывающий нижні частоти.
2 fe_hamming_window Вікно Хеммінга – вносить загасання на початку і наприкінці кадру
3 fe_fft_real Швидке перетворення Фур'є
4 fe_spec2magnitude Зі звичайного спектру отримуємо спектр потужності, втрачаючи фазу
5 fe_mel_spec Групуємо частоти спектра [наприклад, 256 штук] 40 купок, використовуючи MEL-шкалу та вагові коефіцієнти
6 fe_mel_cep Беремо логарифм і застосовуємо DCT2-перетворення до 40 значень з попереднього кроку.
Залишаємо перші 13 значень результату.
Є кілька варіантів DCT2 (HTK, legacy, класичний), що відрізняються константою, на яку ми ділимо отримані коефіцієнти, і особливої константою для нульового коефіцієнта. Можна вибрати будь-який варіант, суті це не змінить.
У ці кроки ще вклинюються функції, які дозволяють відокремити сигнал від шуму і від тиші, типу fe_track_snr, fe_vad_hangover, але нам вони не потрібні, і відволікатися на них не будемо.

Були виконані наступні заміни для кроків по отриманню MFCC-коефіцієнтів:

крок Функція sphinxbase Переробка
1 fe_pre_emphasis cas_pre_emphasis
(через frame[i] -= frame[i — 1] * pre_emphasis_alpha;)
2 fe_hamming_window for(i=0;i<MM_SOUND_BUFFER_LEN;i++)
buf_in[i]*=(0.53836-0.46164*cos(2*3.14159*i/(MM_SOUND_BUFFER_LEN-1)));
3 fe_fft_real ippsDFTFwd_RToCCS_32f
4 fe_spec2magnitude for(i=0;i<=DFT_SIZE/2;i++)
buf_ipp[i]=buf_ipp[i*2]*buf_ipp[i*2]+buf_ipp[i*2+1]*buf_ipp[i*2+1];
5 fe_mel_spec cas_mel_spec
(через предрасчитанную таблицю)
6 fe_mel_cep CS_mel_cep
(через логарифм + ippsDCTFwd_32f_I)
Що ж далі? У нас є вектор 13-вимірного простору. Як визначити, до якого звуку він відноситься?

Завдання №3. Перевірка того, що вимовляється один з 6 запам'ятованих звуків
У програмі-оригіналі «Vocal Joystick» для класифікації використовувався багатошаровий персептрон (MLP) – нейронна мережа без новомодних наворотів.

Давайте подивимося, наскільки виправдане застосування нейронної мережі тут.

Згадаймо, що роблять нейрони в штучних нейронних мережах.

Якщо у нейрона N входів, то нейрон ділить N-мірний простір навпіл. Рубає гіперплощиною навідліг. При цьому в одній половині простору він спрацьовує (видає позитивну відповідь), а в іншій – не спрацьовує.

Давайте подивимося на [майже] найпростіший варіант – нейрон з двома входами. Він, природно, буде ділити навпіл двовимірне простір.

Нехай на вхід подаються значення X1 і X2, які нейрон множить на вагові коефіцієнти W1 і W2, і додає вільний член C.



Отже, на виході нейрона (позначимо його за Y) отримуємо:
Y=X1*W1+X2*W2+C

(опустимо поки тонкощі про сигмоїдальні функції)

Вважаємо, що нейрон спрацьовує, коли Y>0. Пряма, задана рівнянням 0=X1*W1+X2*W2+C якраз і ділить простір на частину, де Y>0, та частина, де Y<0.

Проілюструємо сказане конкретними числами.
Нехай W1=1, W2=1, C=-5;


Тепер подивимося, як нам організувати нейронну мережу, яка б спрацьовувала на деякій області простору, умовно кажучи – плямі, і не спрацьовувала у всіх інших місцях.

З малюнка видно, що для того, щоб окреслити область в двовимірному просторі, нам знадобиться щонайменше 3 прямих, тобто 3 пов'язаних з ними нейрона.



Ці три нейрона ми об'єднаємо разом за допомогою ще одного шару, отримавши багатошарову нейронну мережу (MLP).



А якщо нам потрібно, щоб нейронна мережа спрацьовувала в двох областях простору, то знадобиться ще мінімум три нейрона (4,5,6 на малюнках):


І тут вже без третього шару не обійтися:


А третій шар – це вже майже Deep Learning…


Тепер звернемося за допомогою до ще одного прикладу. Нехай наша нейронна мережа повинна видавати позитивну відповідь на червоних точках, і негативний – на синіх точках.



Якщо б мене попросили відрізати прямими червоне від синього, то я б зробив це якось так:



Але нейронна мережа апріорі не знає, скільки прямих (нейронів) їй знадобиться. Цей параметр треба поставити перед навчанням мережі. І робить це людина на основі… інтуїції або проб і помилок.

Якщо ми виберемо дуже мало нейронів у першому шарі (три, наприклад), то можемо отримати ось таку нарізку, яка буде давати багато помилок (помилкова заштрихована область):



Але навіть якщо число нейронів достатньо, в результаті тренування мережа може «не зійтися», тобто досягти певного стабільного стану, далекого від оптимального, коли відсоток помилок буде високий. Як ось тут, верхня перекладина вляглася на два горба і нікуди з них не піде. А під нею велика область, породжує помилки:



Знову, можливість таких випадків залежить від початкових умов навчання і послідовності навчання, тобто від випадкових чинників:

— Що ти думаєш, то доїде колесо, якщо б сталося, до Москви чи не доїде?
— А ти як думаєш, зійдеться ента нейронна мережа або не зійдеться?
Є ще один неприємний момент, пов'язаний з нейронними мережами. Їх «забудькуватість».

Якщо почати згодовувати мережі тільки сині точки, і перестати згодовувати червоні, то вона може спокійно урвати собі шматок червоної області, перемістивши туди свої межі:



Якщо у нейронних мереж стільки недоліків, і людина може провести кордону набагато ефективніше нейронної мережі, навіщо ж їх тоді взагалі використовувати?

А є одна маленька, але дуже суттєва деталь.

Я дуже добре можу відокремити червоне сердечко від синього фону відрізками прямих у двовимірному просторі.

Я непогано зможу відокремити площинами статую Венери від навколишнього її тривимірного простору.

Але в чотиривимірному просторі я не зможу нічого, вибачте. А в 13-мірному — тим більше.

А ось для нейронної мережі розмірність простору перешкодою не є. Я сміявся над нею в просторах малої розмірності, але варто було вийти за межі буденного, як вона мене легко уделала.

Тим не менш питання поки відкритий – наскільки виправдане застосування нейронної мережі в даній конкретній задачі, враховуючи перераховані вище недоліки нейронних мереж.

Забудемо на секунду, що наші MFCC-коефіцієнти знаходяться в 13-мірному просторі, і уявімо, що вони двовимірні, тобто точки на площині. Як в цьому випадку можна було б відокремити один звук від іншого?

Нехай MFCC-точки звуку 1 мають середньоквадратичне відхилення R1, що [грубо] означає, що точки, не надто далеко відхиляються від середнього, найбільш характерні точки, що знаходяться в межах кола з радіусом R1. Точно так само точки, яким ми довіряємо у звуку 2 знаходяться всередині кола з радіусом R2.



Увага, запитання: де провести пряму, яка відділяла б звук 1 від звуку 2?

Напрошується відповідь: посередині між кордонами кіл. Заперечення є? Заперечень немає.



Далі, уявимо, що звуку три. У цьому випадку проведемо кордону між кожною парою звуків.



І, нарешті, не забудемо, що десь у просторі є точка, яка є відображенням повної тиші в MFCC-просторі. Ні, це не 13 нулів, як могло б здатися. Це одна точка, у якій не може бути середньоквадратичного відхилення. І прямі, якими ми відріжемо її від наших трьох звуків, можна провести прямо по кордонах кіл:



На малюнку нижче кожному звуку відповідає шматок простору свого кольору, і ми завжди можемо сказати, до якого звуку відноситься та чи інша точка простору (чи не відноситься ні до якого):



Ну, добре, а тепер згадаємо, що простір 13-мірне, і те, що було добре малювати на папері, тепер виявляється тим, що не вкладається в людському мозку.

Так, та не так. На щастя, в просторі будь-якої розмірності залишаються такі поняття, як точка, пряма, [гіпер]площину, [гіпер]сфера.

Ми повторюємо ті ж дії і в 13-мірному просторі: знаходимо дисперсію, визначаємо радіуси [гіпер]сфер, з'єднуємо їх центри прямий, рубаємо її [гіпер]площиною в точці, дорівнює віддаленій від кордонів [гіпер]сфер.

Ніяка нейронна мережа не зможе правильно відокремити один звук від іншого.

Тут, щоправда, слід зробити застереження. Все це справедливо, якщо інформація про звук – це хмара точок, що відхиляються від середнього однаково в усіх напрямках, тобто добре вписується в гиперсферу. Якщо б це хмара було фігурою складної форми, наприклад, 13-мірної зігнутої сосискою, то всі наведені вище міркування були б не вірні. І можливо, при правильному навчанні, нейронна мережа змогла б показати тут свої сильні сторони.

Але я б не ризикував. А застосував би, наприклад, набори нормальних розподілів (GMM), (що, до речі і зроблено в CMU Sphinx). Завжди приємніше, коли ти розумієш, який конкретно алгоритм привів до отримання результату. А не як у нейронної мережі: Оракул, на основі свого багатогодинного варіння бульйону з даних для тренування, наказує вам прийняти рішення, що запитуваний звук – це звук №3. (Мене особливо напружує, коли нейронної мережі намагаються довірити керування автомобілем. Як потім в нестандартній ситуації зрозуміти, із-за чого машина повернула ліворуч, а не праворуч? Всемогутній Нейрон наказав?).

Але набори нормальних розподілів – це вже окрема велика тема, яка виходить за рамки цієї статті.

Сподіваюся, що стаття була корисною, та/або змусила ваші мозкові звивини поскрипіти.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.