![](https://habrastorage.org/files/f88/2ea/d70/f882ead70e094eafa8515cd7c87eaed3.png)
Пару месяцев назад мне захотелось поэкспериментировать с нейроинтерфейсом. Никогда этой темой не занимался, но вдруг стало любопытно. Вроде как лет 5-10 назад обещали бум нейроустройств, а всё что мы сейчас имеем на рынке — устройство чтобы махать ушами, устройство чтобы светить камешком, да устройство чтобы левитировать шаром. Где-то на подходе устройство чтобы будить вовремя. Вот тут есть неплохая статья про всё это дело. В то же время регулярно появляются какие-то исследования, где рассказывают, что люди могут научиться двигать роботическими руками-ногами или писать тексты (1, 2, 3, вот тут есть подборка). Но это всё опытное, в единственном экземпляре, со стоимостью аппаратуры как хорошее авто.
А где что-то посередине? Что-то полезное обычному пользователю? Пусть даже не везде, а в каких-то отдельных применениях. Ведь даже навскидку придумывается несколько вещей: детектор засыпания для водителя, повышение работоспособности (например через выбор музыки, или управление перерывами!). Можно выбрать что-то более специфическое. Например смотреть и анализировать своё состояние в киберспорте. Для этого же даже трекеры зрачков выпускают и используют. Почему нет таких применений? Этот вопрос мучил меня. В итоге решил почитать куда наука движется, а так же купить простенькую нейрогарнитуру и затестить. В статье — попытка разобраться в теме, немного исходников и много анализа текущих достижений потребительской электроники.
Что использовал и почему
В продаже есть много различных нейрогарнитур. Вот несколько подборок на тему: 1, 2.
В Москве есть далеко не все из них. Взять решил банальный MindWave NeuroSky. Он бюджетный, а главное — есть неплохое SDK с примерами на нескольких языках.
![](https://habrastorage.org/files/9a8/960/7c4/9a89607c4d374d078557cf973845c7b1.jpg)
Минусы Neurosky
Сразу о минусах. Почему-то о них мало пишут. Но они есть:
1) Сам Mindwave цепляется к компу как COM-порт. Приложение может цепляться к нему напрямую через функции .NET обёртки. А может цепляться через веб-сервер Neurosky, висящий на 127.0.0.1. Второе необходимо, если разработка идёт через какой-нибудь флеш, у которого нет прямого доступа к COM-порту. Но COM пример приложенный к SDK недоработан, устройство часто не цепляется. По сути, единственный способ работать стабильно — через сервер. В конце статьи будет ссылка на GitHub, я там привёл пример того, как всё же можно работать через COM порт (используя сервер для инициализации).
2) Библиотеки. Тестовый пример не запустился. Библиотеки, которые лежат в SDK не работают с последними драйверами. Нужно выкапывать в установленном с драйверами софте последние версии библиотек и использовать их с примерами из SDK.
3) Как бы NeuroSky не хвастался алгоритмами фильтрации помех, но всё же, самые низкочастотные волны не юзабильны (Delta и Theta). Реально использовать от силы 1/2-1/5 данных по ним. При этом нужно подключать либо свою систему фильтрации, либо брать какую-то готовую (например OpenVibe openvibe.inria.fr ).
4) Детектор моргания, которым так хвастается NeuroSky функционален наполовину. В инструкции сказано: «моргайте как можно более естественно». Но тогда моргания не детектируются. Если моргнуть сильно, напрягаясь, то тоже. Нужно где-то посередине. Ах да. COM версия протокола их ещё некорректно передаёт программе. Вот как будут выглядеть сильное/среднее/слабое моргание на графике. Чуть ниже будет пример как выглядит на фурье-спектре. Отличить можно не всегда.
![](https://habrastorage.org/files/862/9a1/e26/8629a1e268a44443989b7e46a27c4275.png)
![](https://habrastorage.org/files/830/745/5fe/8307455fe4a74d1bb152c85380230936.png)
![](https://habrastorage.org/files/b92/2eb/b85/b922ebb85c094b4b8a058784a2b51b73.png)
5) Зараза неудобный. Так и хочется его сдёрнуть с головы. Причём, судя по всему, не я один таков.
Что собственно NeuroSky видит
Но, не всё так плохо:
1) Низкие, высокие альфа, бета, гамма волны видны неплохо. Всплески по ним есть, но фильтруются. Небольшое усреднение + фильтр выбросов даёт объективную картину:
![](https://habrastorage.org/files/764/6e7/7b6/7646e77b656d4f72952deb030775bd8b.png)
2) Есть два параметра, за которые все любят Neurosky: «Медитация» и «Внимание». Они слабо скоррелированы, но ими можно управлять. Я не уверен, что данные параметры означают именно это. Первый из них максимизируется если что-то представить с закрытыми глазами, второй, если начинать вспоминать и ассоциировать различные факторы. Но при игре в Quake | Работе показания весьма средние, хотя оба занятия требуют максимального погружения и внимания. Показатели при прокрастинации для «внимания» даже выше:
![](https://habrastorage.org/files/e4e/9a4/4a2/e4e9a44a2f634c22ae80d322f97004b8.png)
С другой стороны, данными величинами можно научиться более-менее эффективно управлять. Они представляют собой некоторые зависимые от параметров «альфа», «бета», «дельта», «гамма», «тета» величины. У «медитации» максимальная зависимость от альфы:
![](https://habrastorage.org/files/2c3/051/b4c/2c3051b4c0614240913b7c8e03d9e480.png)
Видно, что не всегда, но пики и производные часто зависимы.
3) Сами показания «Альфа-волн» фильтруются устройством. Для теста я сам построил полный спектр входного сигнала, вычислил по нему альфу и сравнил (на рисунке спектр где-то для 0-40Hz):
![](https://habrastorage.org/files/7b1/08e/994/7b108e99420e43be815980a240556683.png)
![](https://habrastorage.org/files/d45/c62/cde/d45c62cde1a94c0889f564246dd5fb2c.png)
В принципе, после закрытия глаз видно, что альфа, вычисленная вручную начала расти. Для преобразование я использовал окно преобразования порядка 1.5-2х секунд. Если сузить окно где-то до 1/3 секунды, то эффект от моргания будет занимать значительно меньше площади.
Я провёл ещё несколько тестов и в целом у меня получилось, что альфа, которую выдаёт прибор, достаточно неплохо фильтруется по сравнению с альфой, которую можно посчитать руками. Но, посчитанное руками будет, безусловно, точнее. Например, если брать короткие выборки без моргания, то лучше всё считать вручную. Если брать среднее, то показания прибора — лучше, если не запариваться с фильтром.
Пару слов о теории
Существует достаточно разветвлённая теория о том, какие электрические колебания генерирует мозг в каких ситуациях. Введение в эту теорию заняло бы всю эту статью. К тому же, я явно не тот, кто сможет это объяснить достаточно подробно ответив на все вопросы. Так что ограничусь ссылкой на Википедию и небольшим резюме:
Разные режимы работы мозга вызывают электрические колебания на разных характеристических частотах. Были выделены несколько групп таких частот и проведена их идентификация с деятельностью. Например глубокий сон вызывает колебания на частотах ниже четырёх герц. Расслабленность и закрытые глаза на частотах порядка 8-12 герц. NeuroSky выводит следующие параметры:
• Дельта волны: <4Hz. Обычно характерны для глубокого сна.
• Тета волны: 4-7 Hz. Быстрый сон, или когда мозг сосредоточен на одном источнике информации.
• Альфа волны: 8-15 Hz. Расслабление, спокойное бодрствование.
• Бета волны: 16-31 Hz. Внимание, напряжение, умственная деятельность.
• Гамма волны: >=32 Hz. Решение задач, максимальное напряжение внимания.
Данные показатели являются некоторой усреднённой метрикой. Для каждой новой головы они могут быть различны или сдвинуты. Зато они достаточно стабильны + для большинства людей могут быть репрезентативны. Например отклик по альфа-волнам для меня для разных состояний:
![](https://habrastorage.org/files/88c/610/725/88c610725df543629524deebc4ae38ab.png)
Согласно теории, чем больше альфа, тем более расслаблен человек. Вроде сходится. Для бета волн вроде как тоже видна зависимость, но уже не такая явная:
![](https://habrastorage.org/files/d96/ee0/a7f/d96ee0a7f52b4dd69c2c17d8b9355f1a.png)
Для Гамма-волн у меня не получилось никакого различия в зависимости от деятельности. Может мозг не тот, может чувствительности прибора не хватает, может 50hz наводки убивают всякие попытки детектировать что-то ощутимое:
![](https://habrastorage.org/files/3f0/ef7/175/3f0ef71755284a55ac2675de1c42f9a1.png)
В принципе, у меня складывается ощущение, что на частотах выше 30Hz какое-то немыслимое количество различных колебаний. Что-то дельное в качестве стабильной метрики на первый взгляд там выцепить сложно (спектр где-то от 0 до 80Hz):
![](https://habrastorage.org/files/94e/635/431/94e635431d0347b1bd022faba4ed83bc.jpg)
Сам прибор втыкается в точку головы Fp1. Говорят, что это не самая оптимальная точка, но вполне репрезентативная. Вроде как точки задней части головы должны более чёткие альфы выдавать.
![](https://habrastorage.org/files/759/c33/a66/759c33a66a254466852d3736eeb2fccd.png)
Ну ладно. Вроде как прибор покрутили, потестировали. Попробуем что-нибудь сделать?
Щенячий восторг вокруг
Начал я с того, что полистал в интернете на тему существующих проектов и идей для MindWave и других устройств на 1-3 электрода. И, если честно, пришёл в ужас.
Во-первых, чудовищное количество бессмысленной движухи вокруг. Тысячи видео на Ютубе где человек показывает свои мозговые сигналы через приложение Brainwave Visualizer или аналоги. Ещё много приложений, которые по переменным «медитация» и «внимание» делают какое-то простейшее действие: управляют вертолётом, или машинкой. Движуха вокруг arduino и то в миллион раз полезнее и интереснее. Тут же всё сводится к двум величинам (
Ещё есть тема. Писать статьи о там как всё это круто, что нейронауки спасут мир. Даже здесь, на Хабре. После статьи обязательно следует предложение либо купить девайсину в соответствующей конторе, либо как-то ещё доставить выгоду писателю статьи. Основное направление таких статей — не «сделать полезное устройство», а «стрясти с пользователя денюжку».
Для устройств с большим числом электродов, того же «Emotiv epoc» применений куда больше. В первую очередь связанных с управлением в играх, или управлением устройств. Но Emotive неплохо детектирует микромимику, на базе которой и строятся такие системы. Управление за счёт мозговой активности практически не встречается.
Серьёзные работы. Да, есть, но они глубоко зарыты.
Закапываемся глубже в мозг
Темы поднятые мной в заголовке статьи не новы. Вообще мало что ново под луной в науке и технике. Можно ли с помощью нескольких электродов определить состояние человека? Устал он, работает, засыпает, водит машину? И как это вообще реализовать?
Наиболее очевидным кажется анализ данных, поступающих с ЭЭГ алгоритмами анализа данных и обучения: SVM, Random Forest, ANN, KNN и.т.д. И действительно. Соответствующий запрос в гугле выдаёт достаточно много работ на эту тему. Не все идеальны, много есть мест, где можно подкопаться, но их достаточно для понимания существующего прогресса и возможностей. Разберём поподробнее.
Во-первых, это coolworld.me/classifying-EEG-SVM. Исследование производилось на MindWave. Автор записал много коротких сетов по 10 секунд со следующими ментальными действиями: «вообразить вращение куба», «вообразить мотор», «вообразить аудиторию». При этом, судя по всему, пробовал комбинировать их с микродвижениями мышц. По каждому сету делалось быстрое фурье-преобразование с базой в 2 секунды. Полученные 5 векторов служили для обучения. Всего делалось по 3 записи каждого действия. Итого 15 векторов.
Уверяет, что получилось классифицировать в 97-100% случаев. Верится, если честно, с трудом. Но, автор описал эксперимент очень плохо. Возможно, используется очень специфический датасет, может, кроме ментальной активности используются микродвижения, может, в 10 секундах записи нет моргания (или вообще писалось с закрытыми глазами), может разделение сетов было бинарно, и.т.д. Вот тут и тут есть чуть больше статей автора.
В целом, автор скорее исследовал не «различие ментальных состояний», а способы через ЭЭГ передавать определённые метки. И на мой взгляд данный способ реально работает. Может не в 97% случаев, но в 90% всё же и можно давать фиксированные команды. При этом отвязанные от «медитации» и «внимания», которые не всегда можно контролировать. Заняты руки — включил мозгом музыку.
Очень немаловажным является отказ автора от использования встроенных величин «альфа», «бета», «дельта», «гамма», «тета» спектров. Автор работал с быстрыми процессами. В показателях MindWave же происходит фильтрация и накопление, что приводит к падению точности и латентности. Автор объясняет данный подход тем, что честно подсчитанный спектр точнее. Но я так не думаю. Как я показал выше — при моргании ошибка будет выше у спектров, которые считаются руками. Плюс у них большая подверженность шумам.
Во-вторых, мне очень понравилась данная статья. Она про Emotiv, а не про NeuroSky. Но тут делается именно то, что на мой взгляд должны делать такие системы. Анализируется возможность детектирования различных ментальных состояний. Авторы записали датасеты с вождением и описали их несколькими способами, как «работа», «удовольствие», «сложность» и.т.д. После чего обучили и протестировали.
![](https://habrastorage.org/files/305/421/302/3054213028aa41ce8729bcf5fc50b624.png)
В работе они показали не только принципиальную возможность классификации. Они проанализировали различные классификаторы и рассчитали их точности. А так же рассмотрели несколько применений, в том числе — анализ ментального состояния водителя (собственно этому и посвящена работа).
Сделано было практически всё, что было можно. Единственный минус — использовался Emotiv EPOC с 14 электродами. А у меня Mindwave с полутора.
Следующая работа. На мой взгляд достаточно средненько, хотя и на Neurosky. Детектировали только засыпание. Единственное, что на мой взгляд хорошо сделали — верифицировали базу при сборе.
Есть работа такая. Она посвящена определению движений по показаниям Emotiv. Я бы не стал так однозначно говорить, что в ней используют именно волны мозга (может статься что мимика тоже причастна).
Ещё есть работа, где всё делалось без обучения, а просто по порогам различным + по хитрой логике. Но на мой взгляд она слабая.
Время что-нибудь сделать
Если честно, то делать я начал ещё до того как изучил все статьи. Решил взять SVM и попробовать распознать деятельность человека на продолжительном участке времени. Работает ли человек, водит, читает, играет, и.т.д. Возможно, я ещё опробую остальные идеи из статей выше, но пока на это не хватило времени.
Первым делом я собрал базу на несколько ситуаций:
• Сижу и работаю (Такое проще всего собрать. 90% времени — прогаю)
• Прокрастинирую. В реальности сложно собрать. Старался записывать те момент когда проглядываю вконтакт, или читаю что-нибудь простое типа гиктаймса. Но иногда ловил себя на мысли, что чересчур погружаюсь.
• Читаю. Сейчас на читалке новый роман Гиббсона, а до этого был Мьевиль. Так что погружение неплохое.
• Вожу машину.
• Сижу с закрытыми глазами, пробую заснуть. Обычно записывал вечером, когда уставший. Из-за схемы крепления MindWave к голове сам сон записать сложно.
• Бегаю на беговой дорожке. Пару сетов данных записал, но на мой взгляд использовать их нельзя. Слишком большие помехи.
• Играю на гитаре. Играю весьма средненько, но для тестирования хватит.
• Играю на компе. Для чистоты эксперимента отдельно записал Quake и пару партий в Starcraft.
Каждый процесс я записывал небольшими кусками где-то по 10-15 минут. Это не очень честный набор базы. Читая, я отвлекался на то, чтобы проверить как идёт запись. Работая я мог отвлечься на скайп. Прокрастинируя, я мог начать думать, и.т.д. Среди полученных данных я пробовал откинуть очевидно некондиционные (MindWave часто имеет плохой контакт). Для автомобиля и для бега очень часто измерения некондиционны.
В работах, упомянутых мной выше очень много внимания уделяли именно корректности базы. За этот счёт получили достаточно неплохие результаты. Но ведь понятно, что в реальных условиях такая база будет некорректной. Люди моргают. Люди отвлекаются. Хотелось добавить именно стабильности. При этом понятно, что точность падает. Поэтому работать с большим числом ситуаций и распознавать их одновременно будет невозможно.
Тут я осветил не все примеры, а на мой взгляд наиболее интересные. Все собранные базы выложены в репозитории (ссылка в конце статьи). Можно потестировать самому.
Что будем подавать на вход. Возможно, это ошибка, а может и нет. Но я решил подавать на вход не спектр DCT, а рассчитанные MindWave величины альфа-бета-… волн + параметры «Медитация» и «Концентрация». По хорошему, нужно другое: подавать исходный спектр, отфильтровав его во времени, как это делается почти во всех статьях. Но праздники закончились и в ближайшее время я это не проверю. Как проверю — либо добавлю главу к этой статье, либо напишу ещё одну.
Сделал я это по двум причинам. Во-первых, на тот момент, как начал собирать базу, я нашёл всего одну статью. Во-вторых, мне показалось, что величины MindWave несколько стабильнее. Особенно к морганию. Не хотелось делать свой алгоритм его подавления.
Понимая, что более двух классов различить сложно, я использовал различие только между двумя классами. В качестве решающей машины я использовал SVM. Судя по всем статьям оно неплохо. Его проще всего настроить. Плюс знаком с несколькими реализациями. Входной вектор был:
Тета, Бета, Альфа1, Альфа2, Бета1, Бета2, Гамма1, Гамма2, Медитация, Концентрация
540 248 374 110 98 181 61 120 64 27
Вектор нормировался, чтобы параметры лежали примерно в одной области. Для одного класса результатом подавался +1, для второго -1.
Примеры работы
Точной статистики приводить не буду. Из-за того, как собиралась база — сложно сказать что-то определённое. Собрать базу на 100 примеров каждого класса по 15 минут почти нереально. Поэтому я строю классификатор для двух классов по выборкам Х1 и У1, а потом смотрю, как распознались примеры X2, X3,..., Xn, Y2, Y3,...Yn.
Вектор «альфа», «бета», «гамма»,… изменяется где-то раз в секунду. Из-за наличия шумов, вызванных морганием, поворотами головы и не смотря на внутренние фильтрации вектор крайне нестабилен. Часто ему нужно 2-3 секунды чтобы вернуться в норму. Поэтому вводим усредняющее окно длинной в 30 секунд. Получается как-то так:
Тест Работа-Прокрастинация
![](https://habrastorage.org/files/ee4/464/477/ee4464477cff4c52894b5ccea2d87cf3.png)
Пример распознавания прокрастинации, где >80% примера распозналось верно. А вот пример записи с работой на 20 минут, где распозналось верно >90%:
![](https://habrastorage.org/files/5c6/b58/c91/5c6b58c9121c44f398eb5becf07a29d9.png)
Всего у меня было 5 записей с работой на 15-25 минут. Из них одна использовалась для обучения. 4 остальных распознались верно. Каждая больше чем на 90% длительности. Из 6 записей прокрастинации одна использовалась как обучение, остальные как тест. Четыре распознались как прокрастинация более чем на 80%, одна как работа почти вся. Вероятно недостаточно прокрастинировал:(
Тест Гитара-Чтение
Не очень полезный тест, но так как по этим двум классам я накопил много примеров — тестировал много. Различается очень хорошо. Для чтения была выборка 9 примеров. Для гитары 6 примеров. По одному на тестирования. Неправильно распозналась только одна гитара (где-то только на 60% определилась как гитара, остальные 40% — чтение). Вот данный пример:
![](https://habrastorage.org/files/2a3/143/3ff/2a31433ff2c545ba822ca6a794a06822.png)
Тест Гитара — Квака
А вот и первый плохо работающий тест. По Q — 4 теста, из них 1 обучение, остальные 3 распознались. Но по игре в Гитару 6 тестов, из них 2 не распознано корректно.
Тест Гитара — прокрастинация
Не работает практически целиком. Переобучается в сторону игры на гитаре. Почти все записи причисляет к игре на гитаре.
Сидение с закрытыми глазами — вождение машины
Вот это очень обидно, но у меня тоже не работает. Всё же я почти уверен, что причина в том, что сидение с закрытыми глазами != засыпание. Засыпание у меня получилось сделать только на одном из четырёх примеров (высокие альфа волны были, пример ниже). Но как собрать базу засыпания в разумные сроки, если честно, не понимаю. Тем более с Mindwave в которым практически невозможно лечь это сложно.
![](https://habrastorage.org/files/314/134/e58/314134e58f0b4ec5ae046b4fa2699480.png)
Что обнадёживает — в статьях, которые были приведены выше отсечку засыпания при вождении дать можно. Даже по уровне альфы. И скорее всего по правильно собранной базе всё заработает
Итоговые мысли где работает где нет
Я бы сказал, что критерий простой: чем сильнее различаются состояния мозга, тем проще отличить что происходит. Но по сути, такой подход сводится к различению двух, максимум трёх состояний мозга. Которые можно обмануть похожими активностями.
А справедливо ли?
А вообще зачем мне нужны были альфа-бета-гамма волны? Может быть достаточно медитации и концентрации? Ведь эти два параметра результирующие?
Такая мысль посетила меня, и я проверил её. Всё же получается, что введение волн значительно уточняет точность распознавания. Привожу примеры для чтения и игры на гитаре. Для остальных классов примерно так же. Видно, что качество улучшилось, хотя общие тренды сохранились:
![](https://habrastorage.org/files/3a9/0d0/b96/3a90d0b96b004833bdd9719cfb47d0c3.png)
![](https://habrastorage.org/files/f32/1c5/361/f321c536181c4de3ae07cbd5e81d8a9d.png)
![](https://habrastorage.org/files/e12/c14/507/e12c1450775244708b57d6a4b57dd46c.png)
![](https://habrastorage.org/files/e71/7a6/78b/e717a678b0db4bc8bcbcd829aae7d670.png)
![](https://habrastorage.org/files/98d/89d/a57/98d89da57344430eb060aa4ea7864952.png)
В принципе, как было и показано во вводных частях, параметры Медитация и Концентрация сильно завязаны на волны и неплохо показывают что волны представляют собой. Но они не несут в себе 100% информации из волн.
Выводы
Такая небольшая статейка получилась на тему EEG. Новогодние выходные были не очень длинными:)
Вернёмся к вопросам, заданным в начале. Почему не произошло бума нейроустройств в потребительском классе? На мой взгляд основная проблема — сложность создания чего-то универсального. Алгоритмы, кроме самых базовых, будут требовать тюнинга под каждого человека. А сделать автоматический тюнинг без того, чтобы пользователь сам вносил настройки — очень сложно.
Вторая проблема — сложность эксплуатации. Датчики нестабильны. Закрепить их, чтобы не было шумов нетривиально. При этом сухой контакт возможен только для лобовой части. Тот же Emotiv желательно крепить с гелем.
В итоге имеем технологию, которая сама по себе нестабильна. Она неплоха для какой-то аналитики. Но как только дело касается какого-то гарантированного результата — сразу проигрывает. Решить ту же проблему с засыпанием водителя можно куда более простыми и дешёвыми способами. Аналитика с ЭКГ куда интереснее, чем ЭЭГ в общем случае.
Да, есть ряд применений, куда можно пробовать развиваться. В конце концов сделать детектор «работает человек» или «прокрастинирует» другими способами сложно (разве что сделать видеоаналитику изображения на мониторе). Но все такие решения требуют очень больших разработок и вряд ли будут работать на 100% людей.
В сухом остатке, на мой взгляд, ниша бюджетных ЭЭГ устройств может занять только рынок игрушек и бесполезных гаджетов. Чем успешно и занимается.
Коды
Ужасные и сырые исходники всего данного дела я выложил тут.
SVM взят из Accord Framework, для простоты отображения подцеплен старый EmguCV. Так же есть библиотеки Neurosky для взаимодействия с MindWawe.