Нейросеть с осциллятором
Применение нейросетей для анализа сигналов
Развитие нейросетевых технологий в последние годы происходит
для самых разных типов задач.
Для неспециалистов сейчас очевидны два основных направления,
в которых задействованы нейросети: работа с графическими изображениями и с
речью. Во втором случае это или онлайн-переводчики, или «искусственный
интеллект».
Менее известны широкой публике задачи распознавания
сигналов. Это могут быть сигналы от датчиков, человеческая речь, музыка. Не
буду подробно описывать все направления исследований в этой области, так как
про большинство из них мне известно в основном то, что и так «написано в
интернете».
Предлагаемый метод и программный продукт ориентированы на
анализ сигналов, характеризующих физические процессы или функционирование
механизмов и различных устройств. Исходная информация, полученная от датчика,
преобразуется в образы, которые подаются на нейросеть, сначала – с целью ее
обучения, затем – для распознавания типа сигнала.
Идея образа дифференциального уравнения
Итак, мы имеем оцифрованный сигнал, то есть
последовательность действительных чисел, полученных с известной частотой
дискретизации.
Как создать образ этого сигнала, то есть небольшой набор
чисел для подачи на входной слой нейросети? Очевидно, что подавать кусок
сигнала – нерационально, так как этот кусок, скорее всего, слишком велик
(тысячи или миллионы чисел). А входной слой нейросети обычно содержит только
десятки или сотни узлов. Поэтому нужно сначала выделить из сигнала какие-то его
численные характеристики. Чаще всего для этого вычисляют его спектральные
характеристики или вероятностные параметры (дисперсия и т.п.).
Наш метод использует другой подход – построение по
наблюдаемым данным дифференциального уравнения. За основу берется уравнение
определенного типа и подгоняются его коэффициенты. Получившийся набор
коэффициентов и является образом сигнала.
В качестве нейросети используется многослойный персептрон,
который обучается с учителем. В программном приложении реализована возможность
выбирать количество и архитектуру слоев, выбирать разные функции активации для
выходного и остальных слоев, использовать алгоритм Dropout.
Таким образом, общий алгоритм обучения и распознавания
состоит из 2-х этапов. Сначала – подгонка коэффициентов уравнения по некоторому
отрезку сигнала, затем – обработка образа нейросетью.
Важное примечание, уточняющее суть алгоритма. Мы используем
уравнение определенного типа. Понятно, что оно вообще-то не описывает точно
любой сигнал, встречающийся на практике. Можно даже сказать, что сигнал,
который является его решением, на практике встретится с вероятностью ноль.
Поэтому, когда программа, получая порции сигнала, подгоняет
по ним коэффициенты уравнения, то для каждой порции получается свой результат.
Предположим, мы учимся отличать сигналы типа A от сигналов
типа B. Пространство найденных наборов коэффициентов, являющееся обучающим
набором для A, отличается от такого же пространства для B. В идеале, эти
пространства не должны пересекаться.
При обучении нейросетей важно, чтобы образы, принадлежащие к
одному из распознаваемых типов, обладали разнообразием. Приведу банальный
пример по распознаванию графических изображений. Пусть мы хотим научить сеть
различать рисунки попугая и вороны. Если мы будем все время предъявлять белого
попугая и черную ворону, нейросеть, увидев белую ворону, с большой вероятностью
скажет: «это попугай». Поэтому надо обучать на разных воронах и разных
попугаях.
Неоднозначный результат подгонки коэффициентов уравнения как
раз обеспечивает многообразие наборов для обучения. То есть нестабильность
получающихся наборов коэффициентов – это в нашем случае не недостаток, а
достоинство.
Уравнение и подгонка коэффициентов
Общий вид уравнения:
C0 * X'' + f(t) * X = 0,
где f(t) = C1 + C2 * t + ... + Cn+1
* tn, то есть многочлен n-й степени.
Понятно,
что к-ты можно сократить на C0, но, извините, так запрограммировано.
Класс для подгонки коэффициентов я написал лет 15 назад, он предназначен для
более широкого класса задач, его исходники много лет доступны в интернете и
поэтому корректировать их я не стал.
Почему выбрано уравнение такого вида?
Это, скажем так, расширенный осциллятор. Он описывает сигнал, обладающий
свойством «колеблемости». Колеблющимся называется решение уравнения, обладающее
свойством: для любого t1 > t0 найдется точка t2
> t1, в которой функция меняет знак. Проще говоря, функция рано
или поздно вернется на нулевой уровень. Определение колеблемости можно
прочитать здесь или здесь здесь.
Большинство сигналов, характеризующих реальные процессы, именно так и устроены;
например, температура воздуха время от времени пересекает значение средней
температуры в данном регионе, а не уходит в бесконечность.
Тем, кому интересно погрузиться в эту
тему со стороны матанализа, предлагаю почитать статью И.В.Каменева Об одном интегральном признаке
колеблемости линейных дифференциальных уравнений второго порядка,
там как раз рассматриваются уравнения вида X'' + f(t) * X = 0. Здесь – архив
статей И.В.Каменева и других авторов, развивающих эту тему.
В двух словах про реализованный
алгоритм подгонки.
В очередной момент времени мы получаем
M значений сигнала. Составляем по ним систему линейных уравнений относительно
коэффициентов Ci. У нас все для этого есть: сами значения сигнала Xj
(j = 0, ..., M - 1), их 2-е производные Xj'' легко
вычисляются, значения времени tj также известны.
Вообще говоря, эта система уравнений –
несовместная. Поэтому решаем ее приближенным методом, состоящим из двух этапов.
Сначала система приводится к квадратному виду методом МНК. Затем она решается с
помощью проекционного алгоритма.
Реализованные в программе алгоритмы
(МНК и проекционный) снабжены несколькими настроечными коэффициентами,
позволяющими адаптировать подгонку к разным типам сигналов.
Посмотреть исходники на C++ метода
подгонки уравнения и демонстрационную программу можно здесь.
Предварительная обработка данных
Часто бывает так, что спектр
анализируемых сигналов сконцентрирован в правой части, то есть характеризующие
его частоты близки к частоте опросов. Это плохо, сильно мешает дискретный шум.
Иначе говоря, на каждом периоде колебаний высокой частоты помещаются всего
несколько точек.
Чтобы от этого уйти, можно применить
цифровой гетеродин. Несмотря на такое «заумное» название, все просто: значения
сигнала умножаются на sin(wh * t), где wh – частота
гетеродина.
Из формулы умножения sin(a) * sin(b) = 1/2 * cos(a – b) – 1/2 *
cos(a + b) следует, что каждая из частот сигнала распадается на 2 гармоники,
высокую и низкую.
Далее мы можем наложить на
преобразованный сигнал узкополосный фильтр, отсекающий высокие частоты, чтобы
работать только с низкими.
Узкополосный фильтр можно применять и
сам по себе, если мы считаем, что вся интересная информация находится в
некоторой части спектра.
После этих операций бывает полезно
подпустить в сигнал шум. Это делается для того, чтобы разнообразить обучающую
выборку.
Также сделана возможность изменить
средний уровень сигнала.
Про «переобучение» нейронной сети
Мне больше нравится слово
«переобученность», но что поделаешь, принято говорить «переобучение».
Это основной негативный эффект, с
которым приходится бороться при настройке.
Переобучение нейросети заключается в
том, что она хорошо обучается распознавать образы из обучающей выборки, но не
может научиться распознавать общие закономерности. То есть, например, как в
случае с белой вороной – раз белая, значит, попугай.
Это стандартное определение термина
«переобучение».
Переобучение происходит по следующим
причинам:
– недостаточно репрезентативный
обучающий набор;
– слишком сильный шум в обучающем
наборе;
– слишком долгое обучение – в этом случае
сеть начинает запоминать лишнюю информацию, содержащуюся в наборе;
– слишком сложная модель сети (обычно –
когда слишком много слоев) – то же самое, начинается запоминание лишних данных.
Также переобучением можно назвать
ситуацию, с которой приходится постоянно сталкиваться на этапе конструирования
сети. А именно, сеть начинает хорошо идентифицировать образы из одного класса,
но не хочет учиться распознавать образы из других классов. Например, упорно
идентифицирует объекты класса B как принадлежащие к классу A, то есть «больше
любит» класс A.
Для борьбы с этим явлением используются
разные подходы. Среди них – алгоритм Dropout. Этот алгоритм заключается в том,
что на каждой итерации обучения каждый нейрон с некоторой вероятностью выпадает
из структуры, веса и пороги для него на этой итерации не корректируются.
В нашей программе вероятности выпадения
по Dropout можно задавать послойно, то есть для каждого слоя – своя
вероятность.