Я был очарован трансферным обучением - методом машинного обучения, в котором мы используем предварительно обученные модели, которые можно переобучить для другого класса входных данных. Это очень популярный способ использовать всю мощь глубокого обучения без необходимости проходить весь процесс обучения сети с нуля. Кроме того, не всегда возможно обучить сеть с нуля из-за отсутствия маркированных данных и / или инфраструктуры, необходимой для этого.

В этом посте я рассмотрю тематическое исследование, в котором я оценил трансферное обучение для проблемы, при которой я обычно использовал бы разные техники. В частности, я хотел посмотреть, можно ли использовать трансферное обучение для классификации частотного содержания сигналов во временной области. Как люди, у нас нет проблем, глядя на экран анализаторов спектра и выявляя основные закономерности частотного содержания входного сигнала. Итак, по крайней мере теоретически, должна быть возможность бросать спектры (в виде изображений) в модель глубокого обучения и заставлять ее изучать разные классы во входных данных.

Определение проблемы

Представьте, что есть устройства, которые выводят сигналы во временной области, как показано ниже. Эти сигналы нанесены на график с осью X, представляющей время, и осью Y, представляющей амплитуду. Сигналы, показанные красным, относительно сигналов, показанных синим, очень незначительно отличаются друг от друга из-за различий в изготовлении устройств. Сигналы красного цвета имеют немного другую частотную составляющую, чем сигналы синего цвета, и нам нужен автоматический способ классификации. Итак, давайте сделаем это с помощью глубокого обучения!

Генерация сигнала

Показанные сигналы были искусственно сгенерированы для этого тематического исследования. Здесь задействованы три частоты, и повсюду добавляется случайный шум как по частоте, так и по фазе и амплитуде. Для тех из вас, кто любит видеть код, взгляните на фрагменты кода (код Go) ниже, чтобы понять, как были созданы эти сигналы.

for i := range theta1 {
   signal[i] = 10*math.Sin(theta1[i]+phase1) +
      5*math.Sin(theta2[i]+phase2) +
      math.Sin(theta3[i]+phase3) +
      3*rand.Float64()
}

где theta1, theta2, phase1 и т. д. определены как:

theta1, err := op.Linspace(0, float64(numCycles+rand.Intn(5))*math.Pi, n)
if err != nil {
   return nil, nil, err
}

и phase1 := rand.Float64 *2 * math.Pi.

op.Linspace - это функция более высокого уровня для генерации линейно разнесенных точек данных.

Частотная область

Теперь сравним сигналы в частотной области. Выполнение преобразования Фурье или FFT для входного сигнала дает следующую сигнатуру в частотной области. Как вы можете видеть, красные v / s синие сигналы теперь можно четко разделить с синими сигналами, показывающими немного более высокую частотную составляющую в каждой из трех частотных полос.

Вычисление БПФ в Go

Я вычислил FFT, используя оператор, построенный с использованием TensorFlow. Для тех, кто заинтересован в создании программных систем с использованием TensorFlow в качестве движка машинного обучения и Go (Golang) в качестве парадигмы программирования, можно создавать оболочки поверх TensorFlow API. Для создания оператора БПФ мы можем начать с кода Python для построения графика TensorFlow:

import tensorflow as tf

my_fft_input = tf.placeholder(tf.complex128, name="myFFTInput")
tf.spectral.fft(my_fft_input, name="fft")

Затем экспортируйте график как файл protobuf:

graph = tf.Session().graph_def
tf.io.write_graph(graph, "./model", "graph.pb", as_text=False)

Такой график можно импортировать в Go и запустить, передав ему данные во время выполнения. Я не буду вдаваться в подробности взаимодействия TensorFlow с Go в этом посте, поскольку я осветил некоторые из этих деталей в другом сообщении. Я просто упомяну, что в конечном итоге у нас появится интерфейс в Go со следующей подписью, позволяющий нам выполнять FFT на срезе float64 данных.

type Operator interface {
   // FFT obtains discrete fast fourier transform over input
   FFT(input []float64) ([]float64, error)
}

Вход для передачи обучения

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

Важно отметить, что классификация изображений не знает концепции частотного содержания сигнала, поэтому для того, чтобы сделать это упражнение значимым, входные данные необходимо контролировать в форме подготовки графика. В частности, трансферное обучение, скорее всего, «узнает» расположение спектральных пиков на графике, поэтому необходимо подготовить все графики с точно таким же масштабом. По сути, мы отображаем шкалу частот на ширину изображения.

Кроме того, необходимо не раскрашивать эти изображения по-разному, потому что мы не хотим, чтобы сеть узнавала различия в этих сигналах на основе цвета. То, что мы скармливаем тренировке, должно выглядеть следующим образом. Три верхних изображения относятся к одному из классов, а три нижних - к другому.

Обучение

Сообщество TensorFlow проделало огромную работу по обеспечению переноса обучения для индивидуального обучения. Пожалуйста, перейдите по ссылке ниже, чтобы узнать, как тренировать свои данные.



Обучение так же просто, как выполнение этой команды: python retrain.py — image_dir=<folder_with_images>

Модель обучается довольно быстро и показывает прогресс на TensorBoard. Вроде сработало! Результатом является еще один график, который можно использовать для вывода новых данных того же типа.

Резюме

Целью было оценить метод обучения передачи для частного случая классификации сигналов на основе их частотного содержания. Мы подготовили наши входные данные в виде jpg изображений, показывающих спектр для каждого из наших сигналов во временной области. Кроме того, код для генерации сигнала и выполнения FFT был написан на Go с использованием TensorFlow в качестве внутреннего механизма машинного обучения.

Используемая модель была Inception V3 обучена Imagenet данным, которые мы переобучили, чтобы идентифицировать классы в нашем наборе данных с помощью трансферного обучения. Результатом стал еще один график, который теперь можно использовать для выводов.

Прибрежные утесы Калифорнии

Береговая линия Калифорнии прекрасна и показывает множество геологических особенностей, таких как эти крутые обрывы, резко поднимающиеся на береговой линии. Я сделал это изображение к югу от залива Хаф-Мун в районе залива Сан-Франциско. Облака были потрясающими, и я сделал снимок с длинной выдержкой, чтобы показать движение волн.