2. Простые модификации Трансформера -- в основном, полученные усечением функциональности.
Из относительно интересных модификаций мне попались такие:
2.1. Non-Autoregressive Neural Machine Translation, Salesforce, конец 2017
Статья: https://arxiv.org/abs/1711.02281
Блогопост: https://blog.einstein.ai/fully-parallel-text-generation-for-neural-machine-translation/
Тут товарищи придумали параллелить генерацию выхода -- каждое слово выхода считается независимо, т.к. декодеры смотрят на немного переделанный вход сети, а не на то, что на прошлом шаге сгенерировали. В итоге выход генерируется за один проход, скорость растёт. Качество падает, но на их тестах не фатально.
2.2. Character-Level Language Modeling with Deeper Self-Attention, Гугл, лето 2018
Статья: https://arxiv.org/abs/1808.04444
Код: https://github.com/nadavbh12/Character-Level-Language-Modeling-with-Deeper-Self-Attention-pytorch
Грубо говоря, взяли от Трансформера только стек декодера, увеличили его глубину до 64 слоёв и сделали на его базе char based LM. Получили SOTA на ряде тестов (до этого SOTA были RNN модели)
2.3. Improving Language Understanding by Generative Pre-Training, OpenAI, лето 2018
Официальный пост про GPT-1: https://openai.com/blog/language-unsupervised/
Статья: https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf
Код: https://github.com/openai/finetune-transformer-lm
Товарищи из OpenAI тем же способом сделали свой GPT-1 aka OpenAI Transformer -- по сути своей это тоже же LM на базе декодерного стека от Трансформера, только word-based (и недавно нашумевшая GPT-2 относится сюда же, только она сильно больше размером + они поменяли схему нормализации и первичную инциализацию).
2.4 Masked BERT, Гугл, осень 2018
Подробный разбор: http://jalammar.github.io/illustrated-bert/
Если очень упрощать, то тут товарищи решили сделать bidirectional LM на базе Трансформера. Для этого они используют не декодер, а стек энкодеров, а слово под вопросом они маскируют во входной строке.
Из относительно интересных модификаций мне попались такие:
2.1. Non-Autoregressive Neural Machine Translation, Salesforce, конец 2017
Статья: https://arxiv.org/abs/1711.02281
Блогопост: https://blog.einstein.ai/fully-parallel-text-generation-for-neural-machine-translation/
Тут товарищи придумали параллелить генерацию выхода -- каждое слово выхода считается независимо, т.к. декодеры смотрят на немного переделанный вход сети, а не на то, что на прошлом шаге сгенерировали. В итоге выход генерируется за один проход, скорость растёт. Качество падает, но на их тестах не фатально.
2.2. Character-Level Language Modeling with Deeper Self-Attention, Гугл, лето 2018
Статья: https://arxiv.org/abs/1808.04444
Код: https://github.com/nadavbh12/Character-Level-Language-Modeling-with-Deeper-Self-Attention-pytorch
Грубо говоря, взяли от Трансформера только стек декодера, увеличили его глубину до 64 слоёв и сделали на его базе char based LM. Получили SOTA на ряде тестов (до этого SOTA были RNN модели)
2.3. Improving Language Understanding by Generative Pre-Training, OpenAI, лето 2018
Официальный пост про GPT-1: https://openai.com/blog/language-unsupervised/
Статья: https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf
Код: https://github.com/openai/finetune-transformer-lm
Товарищи из OpenAI тем же способом сделали свой GPT-1 aka OpenAI Transformer -- по сути своей это тоже же LM на базе декодерного стека от Трансформера, только word-based (и недавно нашумевшая GPT-2 относится сюда же, только она сильно больше размером + они поменяли схему нормализации и первичную инциализацию).
2.4 Masked BERT, Гугл, осень 2018
Подробный разбор: http://jalammar.github.io/illustrated-bert/
Если очень упрощать, то тут товарищи решили сделать bidirectional LM на базе Трансформера. Для этого они используют не декодер, а стек энкодеров, а слово под вопросом они маскируют во входной строке.
👍1
3. Сложные модификации Трансформера -- борьба с ограничениями.
Базовых ограничений у Трансформера несколько:
* не может быть контекста длиннее длины входа
* тяжело увеличивать длину входа (attention это квадрат от входа по сложности)
* не Turing Complete
Соответственно, последние полгода народ активно работает над снятием этих ограничений. Тут мне попались такие штуки:
3.1. Universal Transformers, Google, написан в прошлом году, попал на ICLR2019
Статья: https://arxiv.org/abs/1807.03819
Блогопост: https://ai.googleblog.com/2018/08/moving-beyond-translation-with.html
Свежий разбор: http://mostafadehghani.com/2019/05/05/universal-transformers/
Мотивация -- трасформеры не Turing Complete и у трасформеров нет Recurrent Inductive Bias, а оно, говорят, очень полезно для генерализации структуры.
Давайте сделаем реккурентную сеть поверх трансформерной ячейки.
Ячейка -- один энкодерный слой из трансформера, на каждом такте она обрабатывает все входы и выдаёт самой себе выход на следующий шаг.
При этом надо как-то понять когда остановиться -- делаем вычисляемый признак остановки -- отдельный для каждой позиции входа.
Такая конструкция называется Adaptive universal transformer (идея adaptive остновки взята из аналогичных более старых работ про RNN).
Если для какой-то позиции случалась остановка -- стейт этой позиции замораживаем и копируем дальше на входы внимания другим словам на более поздних итерациях.
Утверждается, что UT существенно более эффективен, чем обычный Трансформер на задачах, где мало входных данных.
3.2. Transformer-XL, начало 2019, Google Brain + CMU
Статья: https://arxiv.org/abs/1901.02860
Разбор: https://towardsdatascience.com/transformer-xl-explained-combining-transformers-and-rnns-into-a-state-of-the-art-language-model-c0cfe9e5a924
Боремся с проблемой фиксированной длины входа. Transformer-XL это модификация LM over vanilla Transformer, позволяющая откусить больше, чем в рот помещается. Полезная для понимания схема -- ниже.
Логика простая:
* Пусть у нас есть допустимый вход длины Х. И входное предложение длины Y>X.
* Порежем входное предложение на куски длины Х.
* Первый кусок пропустим как обычно, но будем сохранять промежуточные стейты.
* Дальше будем обрабатывать следующий кусок, плюс подавать на вход ещё и стейты с предыдущего куска (и запоминать новые).
Такая схема позволяет, сохраняя историю стейтов равную высоте стэка, имитировать длинное окно входа. Это не совсем честно, т.к. градиент на прошлый кусок уже не уйдёт, но всё равно не так плохо. Есть ещё одна загвоздка -- в оригинальном Трансформере у нас есть абсолютное позиционное кодирование. Здесь вместо него предлагается использовать относительное: при расчёте внимания со слова в позиции А на слово в позиции В считать вес внимания отдельно по совпадению Query/Key (без позиционного сигнала) + часть веса добавлять как функицю от разности (В-А). И такую конструкцию, в отличие от оригинального Трансформера, следует делать на каждом слое сети.
Показано, что такой подход даёт SOTA на задачах, где нужно держать длинный контекст.
Базовых ограничений у Трансформера несколько:
* не может быть контекста длиннее длины входа
* тяжело увеличивать длину входа (attention это квадрат от входа по сложности)
* не Turing Complete
Соответственно, последние полгода народ активно работает над снятием этих ограничений. Тут мне попались такие штуки:
3.1. Universal Transformers, Google, написан в прошлом году, попал на ICLR2019
Статья: https://arxiv.org/abs/1807.03819
Блогопост: https://ai.googleblog.com/2018/08/moving-beyond-translation-with.html
Свежий разбор: http://mostafadehghani.com/2019/05/05/universal-transformers/
Мотивация -- трасформеры не Turing Complete и у трасформеров нет Recurrent Inductive Bias, а оно, говорят, очень полезно для генерализации структуры.
Давайте сделаем реккурентную сеть поверх трансформерной ячейки.
Ячейка -- один энкодерный слой из трансформера, на каждом такте она обрабатывает все входы и выдаёт самой себе выход на следующий шаг.
При этом надо как-то понять когда остановиться -- делаем вычисляемый признак остановки -- отдельный для каждой позиции входа.
Такая конструкция называется Adaptive universal transformer (идея adaptive остновки взята из аналогичных более старых работ про RNN).
Если для какой-то позиции случалась остановка -- стейт этой позиции замораживаем и копируем дальше на входы внимания другим словам на более поздних итерациях.
Утверждается, что UT существенно более эффективен, чем обычный Трансформер на задачах, где мало входных данных.
3.2. Transformer-XL, начало 2019, Google Brain + CMU
Статья: https://arxiv.org/abs/1901.02860
Разбор: https://towardsdatascience.com/transformer-xl-explained-combining-transformers-and-rnns-into-a-state-of-the-art-language-model-c0cfe9e5a924
Боремся с проблемой фиксированной длины входа. Transformer-XL это модификация LM over vanilla Transformer, позволяющая откусить больше, чем в рот помещается. Полезная для понимания схема -- ниже.
Логика простая:
* Пусть у нас есть допустимый вход длины Х. И входное предложение длины Y>X.
* Порежем входное предложение на куски длины Х.
* Первый кусок пропустим как обычно, но будем сохранять промежуточные стейты.
* Дальше будем обрабатывать следующий кусок, плюс подавать на вход ещё и стейты с предыдущего куска (и запоминать новые).
Такая схема позволяет, сохраняя историю стейтов равную высоте стэка, имитировать длинное окно входа. Это не совсем честно, т.к. градиент на прошлый кусок уже не уйдёт, но всё равно не так плохо. Есть ещё одна загвоздка -- в оригинальном Трансформере у нас есть абсолютное позиционное кодирование. Здесь вместо него предлагается использовать относительное: при расчёте внимания со слова в позиции А на слово в позиции В считать вес внимания отдельно по совпадению Query/Key (без позиционного сигнала) + часть веса добавлять как функицю от разности (В-А). И такую конструкцию, в отличие от оригинального Трансформера, следует делать на каждом слое сети.
Показано, что такой подход даёт SOTA на задачах, где нужно держать длинный контекст.
🔥1
3.3. Sparse Transformer, 2019 april, OpenAI
Блогопост: https://openai.com/blog/sparse-transformer/
Статья: https://arxiv.org/abs/1904.10509
Код: https://github.com/openai/sparse_attention
Модификация механизма внимания, позволяющая увеличить длину входа. На self-reported тестах более эффективен чем Transformer-XL
При высчислении обычного внимания сложность вычислений Х^2, где Х -- длина входа, т.к. мы считаем внимание с каждого элемента на каждый. Другими словами, внимание это квадратная симметричная матрица. Оказывается, если долго смотреть на эти матрицы, можно узреть паттерны -- часто возникающие схемы внимания, которые сильно проще чем Х^2 и легко факторизуются. Это позволяет считать внимание не по всем элементам, а по небольшому подмножеству, перейдя от Х^2 почти к О(Х). Авторы предлагают две простые факторизации внимания -- strided и fixed. Как следствие это позволяет сильно увеличить размер окна -- обрабатывать Трансформером сырой звук и картинки, что раньше не делали именно из-за того, что в него сложно впихнуть что-то длинное. На текстах они сделали какой-то один SOTA замер, надо последить, что дальше будет.
Поясняющую картинку см выше.
На этом у меня пока всё.
Если что-то важное забыл, пишите в личку, @altsoph.
Блогопост: https://openai.com/blog/sparse-transformer/
Статья: https://arxiv.org/abs/1904.10509
Код: https://github.com/openai/sparse_attention
Модификация механизма внимания, позволяющая увеличить длину входа. На self-reported тестах более эффективен чем Transformer-XL
При высчислении обычного внимания сложность вычислений Х^2, где Х -- длина входа, т.к. мы считаем внимание с каждого элемента на каждый. Другими словами, внимание это квадратная симметричная матрица. Оказывается, если долго смотреть на эти матрицы, можно узреть паттерны -- часто возникающие схемы внимания, которые сильно проще чем Х^2 и легко факторизуются. Это позволяет считать внимание не по всем элементам, а по небольшому подмножеству, перейдя от Х^2 почти к О(Х). Авторы предлагают две простые факторизации внимания -- strided и fixed. Как следствие это позволяет сильно увеличить размер окна -- обрабатывать Трансформером сырой звук и картинки, что раньше не делали именно из-за того, что в него сложно впихнуть что-то длинное. На текстах они сделали какой-то один SOTA замер, надо последить, что дальше будет.
Поясняющую картинку см выше.
На этом у меня пока всё.
Если что-то важное забыл, пишите в личку, @altsoph.
Небольшой follow-up со ссылками и замечаниями от читателей + то, что я сам ещё нашёл по теме.
1. Идею, похожую на Relative Positional Encoding из TXL, предлагали ещё в марте 2018 в Self-Attention with Relative Position Representations (https://arxiv.org/abs/1803.02155), но дальше не развили. Кстати, интересно, судя по коду BERT или реализации GPT-2 от huggingface, видно, что там вообще не заморачиваются с трюками в духе кодирования позиций гармониками из оригинальной статьи -- просто учат на каждую позицию отдельный эмбеддинг.
2. В оригинальной статье про Трансформер используется LDAN порядок слоев (Layer, Dropout, Add, Normalize). На практике все (в том числе официальная реализация в t2t) использует NLDA порядок, это сильно улучшает стабильность обучения и позволяет учить более глубокие архитектуры.
3. Была ещё статья Image Transformer (https://arxiv.org/abs/1802.05751), она посвящена модификации Т для работы с изображениями.
Если я правильно понял из беглого просмотра, основные модификации такие:
* делается кодирование двумерных координат пикселей
* делается локальное внимание в небольшом окне, чтобы избежать X^2
4. Бонус -- практические советы по обучению реализации трансформера из официального пакета Гугла: https://arxiv.org/abs/1804.00247
1. Идею, похожую на Relative Positional Encoding из TXL, предлагали ещё в марте 2018 в Self-Attention with Relative Position Representations (https://arxiv.org/abs/1803.02155), но дальше не развили. Кстати, интересно, судя по коду BERT или реализации GPT-2 от huggingface, видно, что там вообще не заморачиваются с трюками в духе кодирования позиций гармониками из оригинальной статьи -- просто учат на каждую позицию отдельный эмбеддинг.
2. В оригинальной статье про Трансформер используется LDAN порядок слоев (Layer, Dropout, Add, Normalize). На практике все (в том числе официальная реализация в t2t) использует NLDA порядок, это сильно улучшает стабильность обучения и позволяет учить более глубокие архитектуры.
3. Была ещё статья Image Transformer (https://arxiv.org/abs/1802.05751), она посвящена модификации Т для работы с изображениями.
Если я правильно понял из беглого просмотра, основные модификации такие:
* делается кодирование двумерных координат пикселей
* делается локальное внимание в небольшом окне, чтобы избежать X^2
4. Бонус -- практические советы по обучению реализации трансформера из официального пакета Гугла: https://arxiv.org/abs/1804.00247
Conditional BERT Contextual Augmentation
Xing Wu, Shangwen Lv, Liangjun Zang, Jizhong Han, Songlin Hu
Статья: https://arxiv.org/abs/1812.06705
Предложили метод аугментации данных с использованием BERT’а, назвали Conditional BERT Contextual Augmentation. Можно использовать в том числе для текстового переноса стиля.
Главная идея: глубокая модель BERT’а должна работать лучше, чем предыдущие кейсы с однонаправленной моделью или конкатенацией неглубоких forward и backward моделей. А с добавлением контекста всё должно стать ещё лучше.
Для достижения цели авторы сделали замену masked language model на conditional masked language model (C-MLM). Разница с том, что теперь маскируемое слово предсказывается с учётом метки класса.
Архитектура BERT’а осталась той же, изменились эмбеддинги и процедура обучения.
Вместо segmentation embeddings BERT’а (были нужны для разделения первого и второго предложений, A и B) теперь используются label embeddings (содержат метку класса).
Обучение заключается в fine-tuning’е BERT’а с изменением эмбеддингов.
В качестве эксперимента сравнили аугментацию датасета обычным BERT’ом с аугментацией C-BERT’ом. Показали, что на разных задачах текстовой классификации (SST, Subj, MPQA, RT, TREC) C-BERT даёт лучшие результаты.
Показали, что подход переносится на задачу переноса стиля (перефразирование с сохранением стилистических свойств без изменения интента). Правда примеры с изменением стиля скорее являются примерами с изменением сентимента.
Xing Wu, Shangwen Lv, Liangjun Zang, Jizhong Han, Songlin Hu
Статья: https://arxiv.org/abs/1812.06705
Предложили метод аугментации данных с использованием BERT’а, назвали Conditional BERT Contextual Augmentation. Можно использовать в том числе для текстового переноса стиля.
Главная идея: глубокая модель BERT’а должна работать лучше, чем предыдущие кейсы с однонаправленной моделью или конкатенацией неглубоких forward и backward моделей. А с добавлением контекста всё должно стать ещё лучше.
Для достижения цели авторы сделали замену masked language model на conditional masked language model (C-MLM). Разница с том, что теперь маскируемое слово предсказывается с учётом метки класса.
Архитектура BERT’а осталась той же, изменились эмбеддинги и процедура обучения.
Вместо segmentation embeddings BERT’а (были нужны для разделения первого и второго предложений, A и B) теперь используются label embeddings (содержат метку класса).
Обучение заключается в fine-tuning’е BERT’а с изменением эмбеддингов.
В качестве эксперимента сравнили аугментацию датасета обычным BERT’ом с аугментацией C-BERT’ом. Показали, что на разных задачах текстовой классификации (SST, Subj, MPQA, RT, TREC) C-BERT даёт лучшие результаты.
Показали, что подход переносится на задачу переноса стиля (перефразирование с сохранением стилистических свойств без изменения интента). Правда примеры с изменением стиля скорее являются примерами с изменением сентимента.
ACT: Adaptive Computation Time
Есть такая хорошая и малоизвестная тема под названием Adaptive Computation Time (ACT). Недавно стала чуть более известна благодаря Universal Transformer, но в целом всё равно для многих является экзотикой. Хочется рассказать.
Идея в том, что можно динамически решать, как долго проводить вычисления: сколько гонять их через один слой в случае RNN или трансформера, или когда остановиться при проходе через residual block (причём своё решение может быть принято для каждой отдельной части изображения). Для сложных элементов последовательности, возможно, есть смысл пообрабатывать их подольше, а простым может хватить и одного прохода/слоя.
Первоначальная работа:
Alex Graves,
“Adaptive Computation Time for Recurrent Neural Networks”,
https://arxiv.org/abs/1603.08983
Это тот самый Alex Graves, который придумал многомерные RNN, CTC, Grid-LSTM, работал над NTM и DNC, а также над много чем ещё интересным. Начинал в лаборатории Шмидхубера, сейчас работает в DeepMind. Рекомендую следить за его работами, если ещё не.
Итак,
#1. RNN with ACT
В обычных рекурретных сетях текущее состояние s_t зависит от предыдущего состояния s_{t-1} и от входа x_t:
s_t = S(s_{t-1}, x_t)
В случае ACT этот шаг модифицируется так, что рекуррентный слой может крутить внутри себя данные несколько раз, функция S теперь может применяться n раз, на n-ом шаге беря на вход результат n-1 шага:
s^n_t = S(s_{t-1}, x^1_t) для n=1
s^n_t = S(s^{n-1}_t, x^n_t) для других n.
Входной x также дополняется бинарным флажком про увеличение индекса входа, чтобы сеть могла различать повтор в последовательности от шагов последовательной обработки такой вот модифицированной функцией.
Вопрос в том, какой выбрать n, сколько шагов повторять эту процедуру.
Для определение необходимости останова заводится отдельный сигмоидальный halting unit, выход которого, h, определяет, что пора прекращать обработку. Обработка прекращается, когда сумма выходов halting unit за прошедшие шаги становится близка к единице (1 - epsilon, где epsilon -- это гиперпараметр, в работе выбран 0.01). Последнее значение h заменяется на остаток, чтобы сумма всех h была равна единице.
После этого состояние s_t определяется как взвешенная сумма состояний за разные временные шаги с весами, полученными описанным выше способом. Идейно похоже на механизм soft attention.
То есть, если halting unit выдавал на последовательных шагах значения: 0.1, 0.3, 0.4, 0.4, то получим массив весов: [0.1, 0.3, 0.4, 0.2] (последнее значение урезалось). И конечным состоянием слоя будет s_t = 0.1*s^1_t + 0.3*s^2_t + 0.4*s^3_t + 0.2*s^4_t.
Чтобы у сети не было стимула крутить данные внутри как можно дольше в функцию потерь добавляется так называемый ponder cost (с ещё одним гиперпараметром, time penalty -- весом, который надо подбирать), отражающий, как долго обрабатывался каждый отдельный элемент входной последовательности.
Этот ponder cost не является непрерывным в точках, где изменяется количество обработок элемента последовательности, но на это забивают и в остальном градиенты halting activations вычисляются нормально и всё обучается backprop’ом.
Проверяют на задачках, где это может сыграть: проверка чётности входного вектора (который подаётся целиком за один раз, а не как последовательность), логические функции над входом-вектором, сложение элементов последовательности (где каждый элемент представлен последовательностью цифр) и сортировка небольшого набора чисел.
Сети с ACT справляются ощутимо лучше, но надо подбирать параметр time penalty (здесь подбирали grid search’ем).
Ещё один интересный эксперимент -- предсказание следующего символа на датасете из Википедии. Получаются красивые графики, над каким символом сеть сколько (ponder time) думала.
(продолжение скоро)
Если обнаружите неточности или есть комментарии, пишите @che_shr_cat
Есть такая хорошая и малоизвестная тема под названием Adaptive Computation Time (ACT). Недавно стала чуть более известна благодаря Universal Transformer, но в целом всё равно для многих является экзотикой. Хочется рассказать.
Идея в том, что можно динамически решать, как долго проводить вычисления: сколько гонять их через один слой в случае RNN или трансформера, или когда остановиться при проходе через residual block (причём своё решение может быть принято для каждой отдельной части изображения). Для сложных элементов последовательности, возможно, есть смысл пообрабатывать их подольше, а простым может хватить и одного прохода/слоя.
Первоначальная работа:
Alex Graves,
“Adaptive Computation Time for Recurrent Neural Networks”,
https://arxiv.org/abs/1603.08983
Это тот самый Alex Graves, который придумал многомерные RNN, CTC, Grid-LSTM, работал над NTM и DNC, а также над много чем ещё интересным. Начинал в лаборатории Шмидхубера, сейчас работает в DeepMind. Рекомендую следить за его работами, если ещё не.
Итак,
#1. RNN with ACT
В обычных рекурретных сетях текущее состояние s_t зависит от предыдущего состояния s_{t-1} и от входа x_t:
s_t = S(s_{t-1}, x_t)
В случае ACT этот шаг модифицируется так, что рекуррентный слой может крутить внутри себя данные несколько раз, функция S теперь может применяться n раз, на n-ом шаге беря на вход результат n-1 шага:
s^n_t = S(s_{t-1}, x^1_t) для n=1
s^n_t = S(s^{n-1}_t, x^n_t) для других n.
Входной x также дополняется бинарным флажком про увеличение индекса входа, чтобы сеть могла различать повтор в последовательности от шагов последовательной обработки такой вот модифицированной функцией.
Вопрос в том, какой выбрать n, сколько шагов повторять эту процедуру.
Для определение необходимости останова заводится отдельный сигмоидальный halting unit, выход которого, h, определяет, что пора прекращать обработку. Обработка прекращается, когда сумма выходов halting unit за прошедшие шаги становится близка к единице (1 - epsilon, где epsilon -- это гиперпараметр, в работе выбран 0.01). Последнее значение h заменяется на остаток, чтобы сумма всех h была равна единице.
После этого состояние s_t определяется как взвешенная сумма состояний за разные временные шаги с весами, полученными описанным выше способом. Идейно похоже на механизм soft attention.
То есть, если halting unit выдавал на последовательных шагах значения: 0.1, 0.3, 0.4, 0.4, то получим массив весов: [0.1, 0.3, 0.4, 0.2] (последнее значение урезалось). И конечным состоянием слоя будет s_t = 0.1*s^1_t + 0.3*s^2_t + 0.4*s^3_t + 0.2*s^4_t.
Чтобы у сети не было стимула крутить данные внутри как можно дольше в функцию потерь добавляется так называемый ponder cost (с ещё одним гиперпараметром, time penalty -- весом, который надо подбирать), отражающий, как долго обрабатывался каждый отдельный элемент входной последовательности.
Этот ponder cost не является непрерывным в точках, где изменяется количество обработок элемента последовательности, но на это забивают и в остальном градиенты halting activations вычисляются нормально и всё обучается backprop’ом.
Проверяют на задачках, где это может сыграть: проверка чётности входного вектора (который подаётся целиком за один раз, а не как последовательность), логические функции над входом-вектором, сложение элементов последовательности (где каждый элемент представлен последовательностью цифр) и сортировка небольшого набора чисел.
Сети с ACT справляются ощутимо лучше, но надо подбирать параметр time penalty (здесь подбирали grid search’ем).
Ещё один интересный эксперимент -- предсказание следующего символа на датасете из Википедии. Получаются красивые графики, над каким символом сеть сколько (ponder time) думала.
(продолжение скоро)
Если обнаружите неточности или есть комментарии, пишите @che_shr_cat
arXiv.org
Adaptive Computation Time for Recurrent Neural Networks
This paper introduces Adaptive Computation Time (ACT), an algorithm that allows recurrent neural networks to learn how many computational steps to take between receiving an input and emitting an...
Продолжение про ACT
#1b: Repeat-RNN
Comparing Fixed and Adaptive Computation Time for Recurrent Neural Networks
Daniel Fojo, Víctor Campos, Xavier Giro-i-Nieto
https://arxiv.org/abs/1803.08165
Любопытная работа с ICLR 2018. А что если дело не в динамическом определении, сколько раз прогонять каждый слой, а просто в том, чтобы прогонять каждый слой несколько раз?
Сделали новый бейзлайн под названием Repeat-RNN, который выполняет фиксированное количество шагов (>1) на каждом элементе. Это по сути ablation полноценного ACT. Число повторов здесь является гиперпараметром.
Это также эквивалентно кратному увеличению количества каждого входного элемента с дополнительным флажком про то новый это токен или повторный.
Неожиданно оказалось, что Repeat-RNN научается решать задачи за меньшее число шагов SGD и с меньшим количеством повторов, чем ACT. Получилось, что предложенный baseline не хуже или лучше, чем ACT.
И в ACT, и в Repeat-RNN надо тюнить гиперпараметры, но гиперпараметр в Repeat-RNN более интуитивно понятный.
Открытым остаётся вопрос, почему именно итеративное обновление состояния для каждого токена перед тем, как начать обрабатывать следующий, улучшает способности сеток. То ли это понуждает сети итеративно улучшать оценки фич, то ли по факту увеличенное количество применённых нелинейностей даёт возможность моделировать более сложные функции при том же числе параметров модели.
(продолжение следует)
#1b: Repeat-RNN
Comparing Fixed and Adaptive Computation Time for Recurrent Neural Networks
Daniel Fojo, Víctor Campos, Xavier Giro-i-Nieto
https://arxiv.org/abs/1803.08165
Любопытная работа с ICLR 2018. А что если дело не в динамическом определении, сколько раз прогонять каждый слой, а просто в том, чтобы прогонять каждый слой несколько раз?
Сделали новый бейзлайн под названием Repeat-RNN, который выполняет фиксированное количество шагов (>1) на каждом элементе. Это по сути ablation полноценного ACT. Число повторов здесь является гиперпараметром.
Это также эквивалентно кратному увеличению количества каждого входного элемента с дополнительным флажком про то новый это токен или повторный.
Неожиданно оказалось, что Repeat-RNN научается решать задачи за меньшее число шагов SGD и с меньшим количеством повторов, чем ACT. Получилось, что предложенный baseline не хуже или лучше, чем ACT.
И в ACT, и в Repeat-RNN надо тюнить гиперпараметры, но гиперпараметр в Repeat-RNN более интуитивно понятный.
Открытым остаётся вопрос, почему именно итеративное обновление состояния для каждого токена перед тем, как начать обрабатывать следующий, улучшает способности сеток. То ли это понуждает сети итеративно улучшать оценки фич, то ли по факту увеличенное количество применённых нелинейностей даёт возможность моделировать более сложные функции при том же числе параметров модели.
(продолжение следует)
arXiv.org
Comparing Fixed and Adaptive Computation Time for Recurrent Neural Networks
Adaptive Computation Time for Recurrent Neural Networks (ACT) is one of the
most promising architectures for variable computation. ACT adapts to the input
sequence by being able to look at each...
most promising architectures for variable computation. ACT adapts to the input
sequence by being able to look at each...
Продолжение про ACT, часть 3-я.
#2: ResNet & SACT
Интересная работа про применение ACT к свёрточным сетям, конкретно к ResNet’ам. Главный автор -- Миша Фигурнов, который теперь тоже работает в DeepMind.
Пользуясь случаем передаю Мише привет :)
Spatially Adaptive Computation Time for Residual Networks
Michael Figurnov, Maxwell D. Collins, Yukun Zhu, Li Zhang, Jonathan Huang, Dmitry Vetrov, Ruslan Salakhutdinov
Статья: https://arxiv.org/abs/1612.02297
Код: https://github.com/mfigurnov/sact
Идея работы в том, что для разных участков изображения можно было бы регулировать количество вычислений, следуя интуиции, что одни участки изображения важнее других и “сложность” у них тоже разная. Для простых и менее важных регионов могло бы хватить одного-двух слоёв в residual блоке, для более важных и сложных требуется больше.
Эта вариация ACT называется Spatially Adaptive Computation Time (SACT).
Идейно внутри всё похоже на предыдущие варианты, только теперь применено не в рекуррентных сетях, а в (почти) обычных feed-forward -- ResNet’ах. Это своего рода встраивание механизма внимания в ResNet’ы. Мы прекращаем обрабатывать конкретную позицию изображения, как только её фичи стали “достаточно хорошими”.
ResNet’ы состят из блоков (block), каждый из которых содержит пачку слоёв (units). К выходу каждого юнита добавляется ветка, считающая halting score. Как только накопленная сумма halting scores для конкретной позиции достигла единицы (в реальности здесь тоже фигурирует небольшой epsilon как в оригинальной работе), все последующие юниты этого блока пропускаются. Все halting scores превращаются в распределение (усечением веса для последнего сработавшего юнита и занулением весов всех последующих, так чтобы сумма весов была равна единице). И наконец выход блока считается взвешенной суммой выходов юнитов этого блока с весами полученными описанным выше способом.
Визуализация SACT даёт карты, похожие на карты, продуцируемые механизмами внимания, что можно использовать для интерпретации результата и получения некой интуиции про работу сети.
В отличие от рекуррентных сетей здесь есть новые тонкости, например, можно получить мёртвые юниты (последние юниты в блоке), которые не получают достаточно сигнала для обучения. В случает RNN такой проблемы не было благодаря шарингу весов. В работе эта проблема решается.
SACT даёт лучшее качество и производительность по сравнению с обычным ACT или бейзлайновыми резнетами.
Поскольку механизм полносвёрточный, то всё это применимо и к разным разрешениям, и к разным задачам (классификация, детекция, …)
По-прежнему надо тюнить гиперпараметр про вклад ACT в функцию потерь.
(продолжение следует)
#2: ResNet & SACT
Интересная работа про применение ACT к свёрточным сетям, конкретно к ResNet’ам. Главный автор -- Миша Фигурнов, который теперь тоже работает в DeepMind.
Пользуясь случаем передаю Мише привет :)
Spatially Adaptive Computation Time for Residual Networks
Michael Figurnov, Maxwell D. Collins, Yukun Zhu, Li Zhang, Jonathan Huang, Dmitry Vetrov, Ruslan Salakhutdinov
Статья: https://arxiv.org/abs/1612.02297
Код: https://github.com/mfigurnov/sact
Идея работы в том, что для разных участков изображения можно было бы регулировать количество вычислений, следуя интуиции, что одни участки изображения важнее других и “сложность” у них тоже разная. Для простых и менее важных регионов могло бы хватить одного-двух слоёв в residual блоке, для более важных и сложных требуется больше.
Эта вариация ACT называется Spatially Adaptive Computation Time (SACT).
Идейно внутри всё похоже на предыдущие варианты, только теперь применено не в рекуррентных сетях, а в (почти) обычных feed-forward -- ResNet’ах. Это своего рода встраивание механизма внимания в ResNet’ы. Мы прекращаем обрабатывать конкретную позицию изображения, как только её фичи стали “достаточно хорошими”.
ResNet’ы состят из блоков (block), каждый из которых содержит пачку слоёв (units). К выходу каждого юнита добавляется ветка, считающая halting score. Как только накопленная сумма halting scores для конкретной позиции достигла единицы (в реальности здесь тоже фигурирует небольшой epsilon как в оригинальной работе), все последующие юниты этого блока пропускаются. Все halting scores превращаются в распределение (усечением веса для последнего сработавшего юнита и занулением весов всех последующих, так чтобы сумма весов была равна единице). И наконец выход блока считается взвешенной суммой выходов юнитов этого блока с весами полученными описанным выше способом.
Визуализация SACT даёт карты, похожие на карты, продуцируемые механизмами внимания, что можно использовать для интерпретации результата и получения некой интуиции про работу сети.
В отличие от рекуррентных сетей здесь есть новые тонкости, например, можно получить мёртвые юниты (последние юниты в блоке), которые не получают достаточно сигнала для обучения. В случает RNN такой проблемы не было благодаря шарингу весов. В работе эта проблема решается.
SACT даёт лучшее качество и производительность по сравнению с обычным ACT или бейзлайновыми резнетами.
Поскольку механизм полносвёрточный, то всё это применимо и к разным разрешениям, и к разным задачам (классификация, детекция, …)
По-прежнему надо тюнить гиперпараметр про вклад ACT в функцию потерь.
(продолжение следует)
arXiv.org
Spatially Adaptive Computation Time for Residual Networks
This paper proposes a deep learning architecture based on Residual Network that dynamically adjusts the number of executed layers for the regions of the image. This architecture is end-to-end...