bonlime / pytorch-tools

Tool box for PyTorch
MIT License
183 stars 16 forks source link

Transformers #104

Open bonlime opened 3 years ago

bonlime commented 3 years ago

буду хранить тут дамп статей про трансформеры, которые читаю, либо которые хочу прочитать

An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale - статья где предложили ViT, идея нарезать картику на патчи, пропустить через много блоков трансформра - profit. минусы - нарезание на патчи неоптимальное, большая длинна последовательности и следовательно дорогая и долгая тренировка

DeiT - Date Efficient Vision Transformer

LeViT: a Vision Transformer in ConvNet's Clothing for Faster Inference - статья от FAIR. меняют patch embedding. на 4 conv3x3 (stride=2) слоя, потом трансофрмер но с хаками: 1) уменьшают разрешение фичей со временем, потому что хотим иерархические фичи. они делают это внутри attention, меняя размеры query key value 2) используют какой-то хак внутри attention, что-то там в 2 раза увеличивают, не очень понял :(

MLP-Mixer: An all-MLP Architecture for Vision (upd. 17 May 2021) - нарезали на патчи, поменяли в Transformer self-attention на MLP по пространству и работает! (LN - MLP Spatial + Residual - LN - MLP + Residual). MLP это FC - ACT (GELU) - FC. Закидывают данными и жезелом и говорят что работает нормально

Res-MLP (7 May 2021)

Pay-Attention to MLPs (upd. 1 June 2021) . Говорят что MLP чуть-чуть не хватает выразительности, предлагают две вещи 1) Spatial Gating Unit (todo - приложить картинку). С этим блоков работает нормально, но чуть хуже трансформера на длинных последовательностях, где важно обращать внимание на какие-то отдельные куски. 2) добавляют маленький сэлф-аттеншн с одной головой, называют это aMLP и показывают что вот такая структура работает на уровне с трансформерами

FNet (fourier transform net) - показывают, что любое смешивание в spatial пространстве помогает. если заменить self-attention на Discrete Fourier Transform (по сути матрицу определенного вида), то такое смешивание тоже работает. Пока не очень понимаю это константная матрица или считается от фичей? Есть эксперименты где берут случайную матрицу и в таком случае оно не работает. Добавляют поверх своих блоков пару блоков с обычным аттеншн и тогда работает как трансформер, но параметров меньше и быстрее

Rethinking Semantic Segmentation from a Sequence-to-Sequence Perspective with Transformers (SETR) (30 March 2021)

SegFormer: Simple and Efficient Design for Semantic Segmentation with Transformers (31 Мая 2021) - трансформеры для сегментации. Говорят что хотят иерархические фичи, делают патч эмбединг с размером патча 4х4, что а не 16х16 как в оригинальном ViT. Уменьшают фичи с помощью либо 3х3 (s=2) либо 7х7 (s=4) свертки по пространству. Self-Attention в начале был бы слишком дорогим, поэтому используют Efficient Self-Attention - по сути делают решейп из длины последовательности в каналы + FC чтобы вернуть исходное количество каналов: N x C -> N / R x C * R -> N / R x C таким образом уменьшают сложность селф-аттеншн до O(N^2 / R). R=[64, 16, 4, 1] в 4х блоках соответсвенно. Еще одна проблема трансфомеров - нужен какой-то positional embedding, который не позволяет делать инференс на другом разрешении (или сильно уменьшает качество такого инференса). Предлагается выкинуть PE, а информацию о нем получать с помощью DW-conv3x3: x_out = MLP(GELU(Conv3×3(MLP(x_in)))) + x_in где x_in выход селф-аттеншн. (пока не очень понимаю как это помогает с positional embedding, утверждается что с помощью zero-padding сетки подглядывают где граница находится. Предлагают новый All-MLP Decoder. утверждают что в DeepLab нужен какой-то сложный декодер, потому что им receptive field не хватает, а тут receptive field сразу заебись и на всю картинку, поэтому достаточно 1) сделать FC для всех фичей чтобы привести к какому-то одному количеству выходных каналов С 2) фичи со всех слоёв апсеплятся до 1/4 3) concat фичей, на выходе имеем 4 * C классов. 3) Linear(4 * C, C) -> Linear(C , N_cls) В целом очень классное качество, показывают соту на нескольких датасетах, самое главное, наконец избавились от проблем на очень больших объектах (типо домов или дорог), на которых у сверточных сеток не хватало разрешения, а тут хватает.

Моё мнение про возможные улучшения: 1) не убирать свертки из первых блоков энкодера (но это ко всем статьям выше применимо) 2) не убирать свертки из самой последней операции декодера. upd. походу это потому, что они ориентировались на статью про SETR которую я не читал и там как раз сложный декодер из conv3x3, а они наоборот хотели сделать легкий. в SETR правда декодер сложноват, но все еще считаю что тут можно было воткнуть conv3x3

CoAtNet: Marrying Convolution and Attention for All Data Sizes (9 Jun 2021) Статья от гугла, где смотрят как лучше совмещать свертки и трансформеры. Используют 5 блоков, нулевой это просто conv3x3 - conv3x3, первый MBConv, в дальше уже смотрят на что лучше менять. C - C - T - T работает примерно так же как C - T - T - T, что подтверждает идею, что для локальных фичей трансформер не очень то и нужен. Говорят что хорошо бы добавить в self-attention блок relative positional encoding, на практике для каждого аттеншн размера H x W добавляют (2H - 1) x (2W - 1) параметров и для каждой пары индексов берут positional embedding из этой матрицы. на инференсе можно один раз взять эти выученные эмбеды и объеденить с каким-нибудь из слоёв, т.е. будет беспалатно. для картинок бОльшего разрешения делают bilinear upsample для этого embedding. TODO: когда выложат веса, посмотреть как этот pos. embed вообще выглядит. Используют pre-activatation везде где можно, в том числе в MBConv блоках. В трансфомере разрешение жмут через maxpool (s=2), в MBConv s=2 в первой свертке (что кмк очень не правильно, но авторы говорят что для жирных сеток разницы где делать нет. я бы делал один BlurPool перед блоком вообще).

Возможные улучшения: 1) втыкают SE в первые блоки, без ablation реально ли он там нужен, ведь у нас потом все равно идут трансформеры, а GAP в начале это дорогая операция (но учитывая что они вообще скорость не мерят, может им и пофиг). 2) expansion rate 4 и в MBConv и в FFN 3) BlurPool (!)

Задумался о positional embedding в статье выше и где находится оптимум. они не говорят о том, как инитят матрицу эмбедингов, но скорее всего случайно. что если 1) заинитить её косинусами как в модных статьях, возможно это ускорит сходимость / сразу кинет нас ближе к оптимуму 2) потребовать симметричность pos embedding. этого можно добиться, если сделать матрицу размером (H - 1) x (W - 1) и брать элементы оттуда. это конечно будет какое-то наложенное нами ограничение, но ограничение разумное

Статья которую нужно прочитать и понять внимательнее чтобы разобраться с embedding: Master Positional Encoding: Part I

статья в тему, по которой чуть пробежался и ничего не понял - Relative Positional Encoding for Transformers with Linear Complexity

Beyond Self-attention: External Attention using Two Linear Layers for Visual Tasks - только пробежался, но предлагают альтернативу self-attention у которой linear complexity

VOLO: Vision Outlooker for Visual Recognition

Предлагают новый outlook attention. Говорят что большая проблема текущих трансформеров в том, что те плохо кодируют fine-grained информацию о фичах. Это можно улучшить разбивая на патчи поменьше, но это в свою очередь делает последовательность длиньше, а аттеншн растет квадратично от длинны. Outlook выглядит чуть сложновато, но суть в том, что это локальный self-attention, т.е. Вход разбивается на окна 3х3 и для каждого окна считается self-attention, матрица получается HW x K^2 x K^2, что меньше чем HW x H*W в обычном аттеншн почти в 10 раз для типичного входа 28х28. Говорят что такой блок эффективнее в плане параметров чем свертка, но не такой дорогой как self-attention. После 4х outlook блоков уменьшают разрешение в 2 раза и добавляют поверх обычный трансформер. Кмк авторы просто всё сделали хорошо, но работает не из-за их волшебного блока. Возможно что если взять обычный трансформер и в MLP projection сделать conv3x3 вместо 1x1, то это тоже докинет. В итоге для самой маленькой модели используют 4 Outlook (6 heads, dim 192, mlp ratio 3) + 14 Transformer (12 heads, dim 384, mlp ratio 3). В ablation показывают что их блок чуть лучше чем свертки (но не показывают что там по скорости, там скорее всего сильно грустнее).

Пока читал в очередной раз задумался о том, что должен быть какой-то способ применять self-attention не ко всем токенам (а может к уменьшенному разрешению?) потому что это overkill и ограничивает возможность применимости в реальности. Кажется что-то такое было в Lamda Networks

XCiT: Cross-Covariance Image Transformers (Это скорее convnet, а не трансформер, название для хайпа). По сути их Cross-Covariance Attention это динамическая 1x1 свертка, т.е. наверно её можно воткнуть вместо SE блока в resnet лол. Утверждается что можно поменять порядок перемножения матриц, потому что у них будут одинаковые собственные числа, которые можно получить друг из друга. но при этом получается уменьшить сложность с N x N до d x d, в дополнение они разбивают attention на heads, сокращая количество вычисления (и одновременно повышая качество), говорят что идея такая же почему GroupNorm работает лучше LayerNorm, важно быть не самой сильной активацией среди всех, а самой сильной в группе, это повышает выразительность. Дополнительно нормируют K & V на единичную сферу, говорят стабилизирует тренировку. добавляют параметр t (температуру) перед softmax, чтобы была возможность повысить / понизить выразительность. Чтобы было какое-то смешивание каналов добавляют Local patch interaction block (который по сути две DW свертки) + FFN сетку, которая смешивает все каналы. Используют sinusoidal pos. embedding, это отличается от многих других статей, которые используют learned pos.embeddings, замешивают только в начало.

идеи для улучшения: learned relative pos. embeddings, единственное они потребуют resize при увеличение разрешения, но должно работать лучше заменить conv embedding из LeVit чем-нибудь получше уменьшение разрешения по ходу сетки, как делают в conv-net

RePr: Improved Training of Convolutional Filters Нашел интересную статью, где авторы задаются вопросом о том, что раз большие сетки можно хорошо прунить, значит в них есть redundancy в фильтрах, валидируют свою идею тем, что учат маленькую (2 x conv3x3 (32)) сетку на CIFAR-10 которая сильно хуже чем VGG или другие сети (53 top-1 accuracy) и говорят что по-хорошему все фильтры должны быть максимально разными, чтобы как можно лучше работать вместе, но такого не происходит. Предлагают прямо во время обучения делать прунинг, учить только 70% фильтров, а потом случайно инициализировать новые фильтры.

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

All You Need is Beyond a Good Init: Exploring Better Solution for Training Extremely Deep Convolutional Neural Networks with Orthonormality and Modulation Идея похожа на ту что сверху - хочется форсить хорошее распределение фильтров, но тут это делается с помощью отдельного лосса, который штрафует норму матрицы корреляции

bonlime commented 3 years ago

TODOs: (рисерчерские идеи, которые приходят в голову)

Посмотреть на первые слои последних сеток типо EffNet и сравнить их с первыми слоями TResNet, который использует SpaceToDepth, чтобы посмотреть, может ли сетка эффективно понимать, что перед ней решейп одной картинки. Для S2D посмотреть на веса до решейпа и после обратного решейпа

Как выглядит первая свертка для ResNet50 image

Для ResNeXt101_33x8d image

Для tf_efficientnet_b3_ns image тут просто каша из пикселей

efficientnetv2_rw_s image тут очень классные и понятные фильтры

TResNet M image тут интересно, видно что сетка хорошо выучивает пространственную структуру фильтров. чтобы их нарисовать, сделал обратный Depth-To-Space для предобученных весов из 64 x 48 x 3 x 3 в 64 x 3 x 12 x 12. но что смущает, что есть пустые фильтры и бОльшая часть из них плохо заполнены (особенно если сравнивать с фильтрами для EffNet v2, которые прям супер хорошо обучены)

То же самое для моих весов bresnet image фильтры супер четкие как и в примере выше, т.е. у сетки нет проблем с понимаем того, что space2depth это на самом деле spatial пространство

И для bresnet_agn (обученных с GroupNorm + WeightStandardization) image тут фильтры как-будто чуть похуже

Для bnet с space2depth (2x2) на входе image

выглядит прям совсем плохо, не понятно почему.

bonlime commented 11 months ago

1#Accessories#5#Jewelry#16474778632_40148a6fbc_o 1#Accessories#5#Jewelry#14617861777_a7b01742df_o test_image

bonlime commented 11 months ago

image