Часть 2: Архитектура и обработка нейронной сети с прямой связью

Это вторая часть серии статей о том, как создавать музыку с помощью нейронных сетей, используя гармонизацию хоровой мелодии Баха. Если вы не читали часть 1 из этой серии, настоятельно рекомендую прочитать ее раньше.

В этой части серии мы более подробно рассмотрим архитектуру нейронной сети и внутреннюю работу нейронной сети.

Цель обучения нейронной сети

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

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

В случае нашей нейронной сети гармонизации мы будем принимать следующие входные данные:

Где каждая строка соответствует ноте данного временного шага. Для каждого из этих временных шагов цель состоит в том, чтобы вывести количество возможных нот для голосов ATB. Эти несколько выходных данных фактически рассчитываются одновременно и формируют следующую матрицу для каждого из голосов ATB:

Где столбец и строки были переставлены. Итак, теперь содержимое столбца содержит оценку, приписываемую каждой из возможных нот для определенного голоса, а строки представляют ноты на каждом временном шаге.

Нейронная сеть с прямой связью

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

Сеть прямой связи, представленная на предыдущей диаграмме, имеет следующие характеристики:

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

Текущая модель сетевой архитектуры

Теперь, когда мы изучили высокоуровневое представление сети с прямой связью, предыдущий код — это наша реализация этой сети с использованием PyTorch. Вот как различные элементы вписываются в архитектуру нейронной сети с прямой связью.

На этапе предварительной обработки время, распределенное одной горячей матрице кодирования, содержащей ноты сопрано, передается как переменная x этой модели. Поскольку это матричная форма, метод torch.flatten преобразует матрицу в вектор. Подробнее об этом процессе — в следующем разделе. Затем этот вектор передается на входной слой.

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

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

Обработка данных и тензорные формы

Чтобы лучше понять, как работает модель, я попытаюсь показать, как данные передаются в модель. В большинстве случаев люди используют математические обозначения, чтобы проиллюстрировать этот момент, но я не силен в написании математических обозначений, поэтому вместо этого я буду использовать диаграммы. Обратите внимание, что я намеренно исключаю пакетное измерение в своих примерах для простоты.

С учетом начального времени распределена одна горячая матрица кодирования сопрано ниже:

Следующая матрица преобразуется в следующую векторную форму с помощью функции torch.flatten:

Затем это входной вектор слоя nn.Linearinput.

Следующие функции hidden, relu и dropout могут быть представлены следующей схемой:

Где предыдущий входной слой nn.Linear передается другому nn.Linearскрытому слою, а сумма входов нейронов этого скрытого слоя создает F.reluфункция активации. Окончательный результат активации нейрона затем передается через функцию nn.Dropout, которая определяет, будут ли нейроны отключены для следующего слоя или нет. Этот процесс повторяется дважды.

Для слоев предварительного вывода голоса ATB векторы из окончательной функции исключения затем преобразуются в матрицы, чтобы принять следующую форму:

Где размеры P и N инвертированы, чтобы удовлетворить условиям функции потерь F.NLLLoss, обсуждаемой в следующем разделе.

Наконец, функция F.log_softmax применяется к предыдущей матрице, чтобы оценить ноты в каждом столбце по вероятности того, что они являются нотами для воспроизведения.

Функция потерь и обучение сети

Чтобы правильно понять, как сеть вычисляет потери, используемые для корректировки сетевых весов, я считаю полезным взглянуть на документацию формы, предоставленную функцией PyTorch NLLLoss:

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

И целевой набор обучающих данных следующего вида:

Функция NLLoss стремится максимизировать оценку элемента в соответствующей строке, указанной индексом класса целевых обучающих данных.

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

Что касается того, как рассчитывается этот убыток, я отсылаю вас к следующей статье, в которой отлично объясняется функция отрицательного логарифмического правдоподобия, а также рассматривается функция softmax.

Заключение

В этой статье мы более подробно рассмотрели, как можно использовать нейронные сети для создания гармонии для мелодии, следуя технике гармонизации хоралов Баха. Я надеюсь, что после прочтения этой статьи вы лучше понимаете нейронные сети и их возможное использование для генерации музыки. Если у вас есть другие вопросы или связанные темы, о которых вы хотели бы, чтобы я написал, не стесняйтесь писать в разделе комментариев!