В чем разница между механизмами Attention и Self-Attention?

Ответ

Attention (Внимание) и Self-Attention (Само-внимание) — это взаимосвязанные механизмы в архитектурах нейронных сетей, но они решают разные задачи.

Attention (Механизм внимания)

Это общий механизм, который позволяет модели сопоставлять две разные последовательности. Классический пример — архитектура encoder-decoder в машинном переводе: декодер (выходная последовательность) "внимательно смотрит" на энкодер (входную последовательность), чтобы решить, какое слово перевести следующим.

  • Вход: Запросы (Queries) от одной последовательности и Пары Ключ-Значение (Keys-Values) от другой.
  • Задача: Найти релевантные части в последовательности-источнике (encoder) для каждого элемента последовательности-цели (decoder).

Self-Attention (Механизм само-внимания)

Это частный случай механизма внимания, где все три компонента (Queries, Keys, Values) происходят из одной и той же последовательности. Это позволяет каждому элементу последовательности взаимодействовать со всеми другими элементами этой же последовательности, улавливая внутренние зависимости (синтаксические, семантические).

  • Вход: Запросы, Ключи и Значения проецируются из одного и того же входного тензора.
  • Задача: Обогатить представление каждого элемента контекстом всей последовательности. Например, понять, к какому существительному относится местоимение в предложении.

Визуализация отличия:

Attention:        Sequence A (Queries)  <--->  Sequence B (Keys/Values)
                 (e.g., Decoder Output)        (e.g., Encoder Output)

Self-Attention:  Sequence A (Queries)  <--->  Sequence A (Keys/Values)
                 (e.g., Input Sentence)        (e.g., Same Input Sentence)

Реализация Scaled Dot-Product Self-Attention (упрощенная):

import torch
import torch.nn.functional as F

def self_attention(input_sequence, d_model=64):
    # input_sequence shape: (batch_size, seq_len, d_model)
    batch_size, seq_len, _ = input_sequence.shape

    # Линейные проекции для получения Q, K, V из одного входа
    W_q = torch.nn.Linear(d_model, d_model, bias=False)
    W_k = torch.nn.Linear(d_model, d_model, bias=False)
    W_v = torch.nn.Linear(d_model, d_model, bias=False)

    Q = W_q(input_sequence)  # (batch, seq_len, d_model)
    K = W_k(input_sequence)  # (batch, seq_len, d_model)
    V = W_v(input_sequence)  # (batch, seq_len, d_model)

    # Вычисление весов внимания
    scores = torch.bmm(Q, K.transpose(1, 2)) / (d_model ** 0.5)  # Масштабирование
    attention_weights = F.softmax(scores, dim=-1)  # (batch, seq_len, seq_len)

    # Применение весов к значениям
    output = torch.bmm(attention_weights, V)  # (batch, seq_len, d_model)
    return output, attention_weights

# Пример вызова
x = torch.randn(2, 10, 64)  # 2 примера, длина последовательности 10, размерность 64
context_vector, attn = self_attention(x)

Итог: Self-Attention — это основа блока Transformer, которая кодирует контекст внутри последовательности. Классический Attention используется для связи между разными последовательностями, например, в seq2seq-моделях.

Ответ 18+ 🔞

Давай разберём эту дичь, чтобы даже кот, который на клавиатуре спит, понял. Тема, конечно, ёперный театр, но мы её разжуём.

Смотри, есть Attention (Внимание). Представь, что ты переводишь текст с английского на русский. Твой мозг (декодер) постоянно оглядывается на английский оригинал (энкодер) и спрашивает: "Э, сабака сука, а на какую часть исходного текста мне сейчас смотреть, чтобы правильно перевести это слово?" Вот это и есть классический механизм внимания — одна последовательность пялится на другую.

А теперь Self-Attention (Само-внимание). Это когда ты читаешь одно предложение на русском и сам с собой разбираешься. Ты видишь слово "он" и думаешь: "Бля, а к кому этот 'он' относится? Ага, к Васе, который упоминался три слова назад". То есть последовательность сама на себя смотрит, чтобы понять внутренние связи. Все три штуки — Запросы (Q), Ключи (K) и Значения (V) — берутся из одного и того же места. Получается такой мощный интроспективный тренажёр для нейросети.

Короче, визуализация отличия, чтобы совсем пиздец стало ясно:

Attention (Внимание):        Твой перевод (Запросы)  <--->  Оригинал (Ключи/Значения)
                             "Как перевести 'cat'?"          "Исходный английский текст"

Self-Attention (Само-внимание):  Русское предложение (Запросы)  <--->  Это же предложение (Ключи/Значения)
                                  "Он пошёл гулять"                 "Он (Вася) пошёл гулять"

Self-Attention — это и есть та самая волшебная хуйня, из-за которой Трансформеры такие умные. Они каждое слово в предложении пропускают через мясорубку контекста со всеми остальными словами.

Вот как это выглядит в коде, если не бздеть:

import torch
import torch.nn.functional as F

def self_attention(input_sequence, d_model=64):
    # input_sequence shape: (batch_size, seq_len, d_model)
    batch_size, seq_len, _ = input_sequence.shape

    # Линейные проекции для получения Q, K, V из одного входа
    W_q = torch.nn.Linear(d_model, d_model, bias=False)
    W_k = torch.nn.Linear(d_model, d_model, bias=False)
    W_v = torch.nn.Linear(d_model, d_model, bias=False)

    Q = W_q(input_sequence)  # (batch, seq_len, d_model)
    K = W_k(input_sequence)  # (batch, seq_len, d_model)
    V = W_v(input_sequence)  # (batch, seq_len, d_model)

    # Вычисление весов внимания
    scores = torch.bmm(Q, K.transpose(1, 2)) / (d_model ** 0.5)  # Масштабирование
    attention_weights = F.softmax(scores, dim=-1)  # (batch, seq_len, seq_len)

    # Применение весов к значениям
    output = torch.bmm(attention_weights, V)  # (batch, seq_len, d_model)
    return output, attention_weights

# Пример вызова
x = torch.randn(2, 10, 64)  # 2 примера, длина последовательности 10, размерность 64
context_vector, attn = self_attention(x)

Итог, чувак:

  • Self-Attention — это когда последовательность сама с собой разбирается, как в блоке Transformer. "Э, бошка думай, кто кому кем приходится".
  • Классический Attention — это когда две разные последовательности друг на друга смотрят, как в старых seq2seq-моделях для перевода. Одна спрашивает, другая отвечает.

Всё, теперь можешь идти и чувствовать себя умнее, чем мартышлюшка, которая только бананы тырит.