Помимо трансформеров с PyNeuraLogic

Feb 08 2023
Демонстрация возможностей нейросимволического программирования В последние несколько лет мы наблюдаем рост числа моделей на основе Transformer¹ с успешным применением во многих областях, таких как обработка естественного языка или компьютерное зрение. В этой статье мы рассмотрим краткий, объяснимый и расширяемый способ выражения моделей глубокого обучения, в частности преобразователей, в виде гибридной архитектуры, т.е.

Демонстрация возможностей нейросимволического программирования

Визуализация графика вычисления внимания с точки зрения одного токена с видимыми отношениями между токенами. Изображение автора.

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

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

— Гэри Маркус²

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

Высокоуровневая визуализация нейросимволической концепции Lifted Relational Neural Networks³ (LRNN), которую реализует (Py)NeuraLogic. Здесь мы показываем простой шаблон (логическую программу) с одним линейным слоем, за которым следует суммирование. Для каждой (входной) выборки строится уникальная нейронная сеть. Изображение автора.

Фреймворк PyNeuraLogic основан на логическом программировании с изюминкой — логические программы содержат дифференцируемые параметры. Фреймворк хорошо подходит для небольших структурированных данных, таких как молекулы, и сложных моделей, таких как преобразователи и графовые нейронные сети. С другой стороны, PyNeuraLogic — не лучший выбор для нереляционных и больших тензорных данных.

Ключевым компонентом фреймворка является дифференцируемая логическая программа, которую мы называем шаблоном. Шаблон состоит из логических правил, которые абстрактно определяют структуру нейронных сетей — мы можем думать о шаблоне как о плане архитектуры модели. Затем шаблон применяется к каждому экземпляру входных данных, чтобы создать (путем заземления и нейтрализации) нейронную сеть, уникальную для входной выборки. Этот процесс полностью отличается от других фреймворков с предопределенной архитектурой, которые не могут приспосабливаться к различным входным образцам. Для более подробного ознакомления с фреймворком вы можете посмотреть, например, предыдущую статью о PyNeuralogic с точки зрения графовых нейронных сетей.

Символические Трансформеры

Архитектура Transformer состоит из двух блоков — энкодера (слева) и декодера (справа). Оба блока имеют сходство — декодер является расширенным кодировщиком; поэтому мы сосредоточимся только на кодере, так как реализация декодера аналогична. Изображение автора, вдохновленное [1].

Обычно мы склонны реализовывать модели глубокого обучения как тензорные операции над входными токенами, объединенными в один большой тензор. Это имеет смысл, потому что фреймворки и аппаратное обеспечение глубокого обучения (например, графические процессоры) обычно оптимизированы для обработки больших тензоров, а не нескольких тензоров разных форм и размеров. Преобразователи не являются исключением, и обычно представления отдельных векторов токенов объединяются в одну большую матрицу и представляют модель как операции над такими матрицами. Тем не менее, такие реализации скрывают, как отдельные входные токены соотносятся друг с другом, что можно продемонстрировать в механизме внимания Transformer.

Механизм внимания

Механизм внимания лежит в основе всех моделей Transformer. В частности, его классическая версия использует так называемое скалярное произведение с несколькими головками. Разложим масштабированное скалярное произведение внимания с одной головой (для наглядности) в простую логическую программу.

Уравнение внимания масштабированного скалярного произведения

Цель внимания состоит в том, чтобы решить, на каких частях входных данных должна сосредоточиться сеть. Внимание делает это, вычисляя взвешенную сумму значений V , где веса представляют совместимость входных ключей K и запросов Q . В этой конкретной версии веса вычисляются с помощью функции softmax скалярного произведения запросов Q и ключей K , деленного на квадратный корень из размерности вектора входных признаков d_k .

(R.weights(V.I, V.J) <= (R.d_k, R.k(V.J).T, R.q(V.I))) | [F.product, F.softmax_agg(agg_terms=[V.J])],
(R.attention(V.I) <= (R.weights(V.I, V.J), R.v(V.J)) | [F.product]

Затем второе правило вычисляет произведение между этим вектором весов и соответствующим j -м вектором значений и суммирует результаты по различным j для каждого соответствующего i -го токена.

Маскировка внимания

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

(R.weights(V.I, V.J) <= (
    R.d_k, R.k(V.J).T, R.q(V.I), R.special.leq(V.J, V.I)
)) | [F.product, F.softmax_agg(agg_terms=[V.J])],

Обычные фреймворки глубокого обучения ограничивают внимание с помощью маскировки (слева). Сначала вычисляется вся матрица QK^T, затем значения маскируются путем переопределения с низкими значениями (белые перечеркнутые ячейки), чтобы имитировать внимание только к соответствующим токенам (синие ячейки). В PyNeuraLogic мы вычисляем только необходимые скалярные значения, применяя символическое ограничение (справа) — поэтому нет лишних вычислений. Это преимущество становится еще более значительным в следующих версиях с вниманием. Изображение автора.

Помимо стандартной агрегации внимания

Конечно, символическая «маскировка» может быть совершенно произвольной. Большинство из нас слышали о GPT-3⁴ (или его приложениях, таких как ChatGPT ), основанном на Sparse Transformers.⁵ Внимание Sparse Transformer (версия с шагами) имеет два типа головок внимания:

  • Тот, который обслуживает только предыдущие n жетонов (0 ≤ i − j ≤ n)
  • Тот, который посещает только каждый n -й предыдущий токен ( (i − j) % n = 0 )

(R.weights(V.I, V.J) <= (
    R.d_k, R.k(V.J).T, R.q(V.I),
    R.special.leq(V.D, 5), R.special.sub(V.I, V.J, V.D),
)) | [F.product, F.softmax_agg(agg_terms=[V.J])],
(R.weights(V.I, V.J) <= (
    R.d_k, R.k(V.J).T, R.q(V.I),
    R.special.mod(V.D, 5, 0), R.special.sub(V.I, V.J, V.D),
)) | [F.product, F.softmax_agg(agg_terms=[V.J])],

      
                
The Relational Attention equations

(R.weights(V.I, V.J) <= (R.d_k, R.k(V.I, V.J).T, R.q(V.I, V.J))) | [F.product, F.softmax_agg(agg_terms=[V.J])],
(R.attention(V.I) <= (R.weights(V.I, V.J), R.v(V.I, V.J)) | [F.product],

R.q(V.I, V.J) <= (R.n(V.I)[W_qn], R.e(V.I, V.J)[W_qe]),
R.k(V.I, V.J) <= (R.n(V.J)[W_kn], R.e(V.I, V.J)[W_ke]),
R.v(V.I, V.J) <= (R.n(V.J)[W_vn], R.e(V.I, V.J)[W_ve]),

Кодер-трансформер

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

Вложения

Мы уже видели в реляционном внимании, как можно реализовать вложения. Для традиционного Трансформера вложения будут очень похожими. Мы проецируем входной вектор на три вектора встраивания — ключи, запросы и значения.

R.q(V.I) <= R.input(V.I)[W_q],
R.k(V.I) <= R.input(V.I)[W_k],
R.v(V.I) <= R.input(V.I)[W_v],

Вложения запросов суммируются с выводом внимания через соединение с пропуском. Полученный вектор затем нормализуется и передается в многослойный персептрон (MLP).

(R.norm1(V.I) <= (R.attention(V.I), R.q(V.I))) | [F.norm],

(R.mlp(V.I)[W_2] <= (R.norm(V.I)[W_1])) | [F.relu],

(R.norm2(V.I) <= (R.mlp(V.I), R.norm1(V.I))) | [F.norm],

Мы собрали все необходимые детали для создания кодировщика Transformer. В декодере используются те же компоненты; следовательно, его реализация будет аналогичной. Давайте объединим все блоки в одну дифференцируемую логическую программу, которую можно встроить в скрипт Python и скомпилировать в нейронные сети с помощью PyNeuraLogic.

R.q(V.I) <= R.input(V.I)[W_q],
R.k(V.I) <= R.input(V.I)[W_k],
R.v(V.I) <= R.input(V.I)[W_v],

R.d_k[1 / math.sqrt(embed_dim)],
(R.weights(V.I, V.J) <= (R.d_k, R.k(V.J).T, R.q(V.I))) | [F.product, F.softmax_agg(agg_terms=[V.J])],
(R.attention(V.I) <= (R.weights(V.I, V.J), R.v(V.J)) | [F.product],

(R.norm1(V.I) <= (R.attention(V.I), R.q(V.I))) | [F.norm],
(R.mlp(V.I)[W_2] <= (R.norm(V.I)[W_1])) | [F.relu],
(R.norm2(V.I) <= (R.mlp(V.I), R.norm1(V.I))) | [F.norm],

В этой статье мы проанализировали архитектуру Transformer и продемонстрировали ее реализацию в нейросимволическом фреймворке под названием PyNeuraLogic . Благодаря этому подходу мы смогли реализовать различные типы трансформеров с небольшими изменениями в коде, демонстрируя, как каждый может быстро изменить и разработать новую архитектуру трансформеров. Это также указывает на безошибочное сходство различных версий Трансформеров и Трансформеров с GNN.

[1]: Васвани А., Шазир Н., Пармар Н., Ушкорейт Дж., Джонс Л., Гомес А., Кайзер Л. и Полосухин И.. (2017). Внимание — это все, что вам нужно.

[2]: Маркус, Г.. (2020). Следующее десятилетие ИИ: четыре шага к надежному искусственному интеллекту.

[3]: Густав Шоурек, Филип Железный и Ондржей Кужелка (2021). За пределами графовых нейронных сетей с поднятыми реляционными нейронными сетями . Машинное обучение, 110 (7), 1695–1738.

[4]: Браун Т., Манн Б., Райдер Н., Суббиа М., Каплан Дж., Дхаривал П., Нилакантан А., Шьям П., Састри Г., Аскелл , А., Агарвал, С., Герберт-Восс, А., Крюгер, Г., Хениган, Т., Чайлд, Р., Рамеш, А., Циглер, Д., Ву, Дж., Винтер, К. , Гессе К., Чен М., Сиглер Э., Литвин М., Грей С., Чесс Б., Кларк Дж., Бернер К., МакКэндлиш С., Рэдфорд А. , Суцкевер, И., и Амодей, Д.. (2020). Языковые модели — это ученики с небольшим количеством шансов.

[5]: Чайлд Р., Грей С., Рэдфорд А. и Суцкевер И.. (2019). Генерация длинных последовательностей с разреженными трансформаторами.

[6]: Диао, К., и Лойнд, Р.. (2022). Реляционное внимание: обобщение преобразователей для графоструктурированных задач.

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