Функция torch.nn.Embedding в PyTorch
Справочное руководство PyTorch torch.nn
torch.nn.EmbeddingЭто модуль в PyTorch, используемый для встраивания слов.
Он отображает дискретные индексы слов в непрерывное векторное пространство и является одной из самых фундаментальных операций в обработке естественного языка.
Определение функции
torch.nn.Embedding(num_embeddings, embedding_dim, padding_idx=None, max_norm=None, norm_type=2.0, scale_grad_by_freq=False, sparse=False)
Описание параметров:
num_embeddings(int): Размер словаря, то есть количество строк в матрице встраивания.embedding_dim(int): Размерность каждого вектора встраивания.padding_idx(int): Задаёт индекс заполнения, вектор эмбеддинга которого является нулевым вектором. По умолчанию None.max_norm(float): Если не None, векторы эмбеддингов нормализуются к этой норме. По умолчанию None.norm_type(float): Порядок вычисляемой нормы. По умолчанию 2.0.scale_grad_by_freq(bool): Масштабировать ли градиенты на основе частоты слов. По умолчанию False.sparse(bool): Является ли матрица весов разреженной матрицей. По умолчанию False.
Атрибуты:
weight(Tensor): Обучаемые веса формы (num_embeddings, embedding_dim).
Примеры использования
Пример 1: Базовое использование
Создание и использование эмбеддингов слов:
Пример
import torch.nn as nn
# Создать слой эмбеддингов: словарь 10000, размерность эмбеддинга 256
embedding = nn.Embedding(num_embeddings=10000, embedding_dim=256)
# Индексы слов (начиная с 0)
# Форма: (batch, seq_len)
input_indices = torch.tensor([[12, 45, 678], [901, 23, 56]])
# Найти векторы эмбеддингов
output = embedding(input_indices)
print("Форма входных индексов:", input_indices.shape)
print("Форма выходного эмбеддинга:", output.shape) # (2, 3, 256)
# Просмотр формы матрицы встраивания
print("Форма матрицы эмбеддингов:", embedding.weight.shape)
Пример 2: Использование padding_idx
Укажите индекс заполнения:
Пример
import torch.nn as nn
# Создайте слой эмбеддингов с заполнением
embedding = nn.Embedding(num_embeddings=1000, embedding_dim=64, padding_idx=0)
# 0 используется как заполнение
input_indices = torch.tensor([[1, 2, 3], [4, 0, 0]]) # Во втором предложении есть заполнение
output = embedding(input_indices)
print("Форма входных данных:", input_indices.shape)
print("Форма выхода:", output.shape)
print("Вектор эмбеддинга заполнения:", output[1, 1].tolist()) # Все нули
print("Вектор встраивания для не-padding:", output[0, 0].tolist()[:5]) # Ненулевые
Пример 3: Предобученные векторы слов
Загрузите предобученные векторы слов:
Пример
import torch.nn as nn
import numpy as np
# Смоделировать предобученные векторы слов (на практике можно использовать GloVe, Word2Vec и т.д.)
vocab_size = 1000
embedding_dim = 300
# Случайная инициализация (на практике загрузите предобученные векторы)
pretrained_weights = np.random.randn(vocab_size, embedding_dim).astype('float32')
# Создать слой встраивания
embedding = nn.Embedding(vocab_size, embedding_dim)
# Загрузить предобученные веса
embedding.weight.data = torch.from_numpy(pretrained_weights)
# Заморозить слой эмбеддингов (не обучается)
embedding.weight.requires_grad = False
print("Обучаемый слой эмбеддингов:", embedding.weight.requires_grad)
print("Форма матрицы эмбеддингов:", embedding.weight.shape)
Пример 4: Ограничение нормы вектора эмбеддинга
Используйте max_norm для ограничения нормы вектора:
import torch.nn as nn
# Ограничить максимальную норму векторов эмбеддингов значением 1.0
embedding = nn.Embedding(1000, 64, max_norm=1.0)
# Ввод
input_indices = torch.tensor([1, 2, 3])
# Исходная норма весов
original_norm = embedding.weight.data.norm(dim=1)[:3]
print("Исходная норма весов:", original_norm.tolist())
# Норма вектора после выборки
output = embedding(input_indices)
output_norm = output.norm(dim=1)
print("Норма выходного вектора:", output_norm.tolist())
Пример 5: Полная модель классификации текста
Классификация текста с использованием слоя встраивания:
Пример
import torch.nn as nn
class TextClassifier(nn.Module):
def __init__(self, vocab_size, embed_dim, hidden_dim, num_classes=2):
super(TextClassifier, self).__init__()
# Слой встраивания слов
self.embedding = nn.Embedding(vocab_size, embed_dim, padding_idx=0)
# LSTM
self.lstm = nn.LSTM(embed_dim, hidden_dim, batch_first=True)
# Классификатор
self.classifier = nn.Linear(hidden_dim, num_classes)
def forward(self, x):
# x: (batch, seq_len)
embedded = self.embedding(x) # (batch, seq_len, embed_dim)
# LSTM принимает последний выход
_, (hidden, _) = self.lstm(embedded)
hidden = hidden[-1] # Скрытое состояние последнего слоя
# Классификация
logits = self.classifier(hidden)
return logits
# Параметры
VOCAB_SIZE = 10000
EMBED_DIM = 128
HIDDEN_DIM = 256
model = TextClassifier(VOCAB_SIZE, EMBED_DIM, HIDDEN_DIM)
# Вход: batch=4, длина последовательности=50
input_ids = torch.randint(1, VOCAB_SIZE, (4, 50))
output = model(input_ids)
print("Архитектура модели:")
print(model)
print("Форма входа:", input_ids.shape)
print("Форма выхода:", output.shape)
Разница между Embedding и EmbeddingBag
| Type | Ввод | Вывод | Сценарии применения |
|---|---|---|---|
nn.Embedding |
Индексы слов | Последовательность векторов слов | Модели последовательностей, LSTM, Transformer |
nn.EmbeddingBag |
Индексы слов + смещения | Агрегированный вектор | Классификация текста, быстрая обработка |
Часто задаваемые вопросы
Вопрос 1: Как выбрать размерность эмбеддинга?
- Малые наборы данных: 50-100 измерений
- Средние наборы данных: 100-300 измерений
- Большие наборы данных: 300-500 измерений
Вопрос 2: Для чего нужен padding_idx?
Он устанавливает вектор эмбеддинга по указанному индексу в нулевой вектор и не вычисляет его градиент во время обратного распространения.
Вопрос 3: Когда замораживать слой эмбеддингов?
При использовании предобученных векторов слов обычно замораживают слой, некоторое время обучают, а затем дообучают.
Сценарии использования
nn.EmbeddingОсновные сценарии применения включают:
- Векторное представление слов: Преобразование слов в плотные векторы
- Классификация текста: В качестве входного слоя NLP-моделей
- Модели последовательностей: Вход для LSTM, GRU
- Рекомендательные системы: Эмбеддинг-представления пользователей и объектов
Примечание: embedding.weight — это обучаемый параметр, и его можно обучать напрямую в оптимизаторе.
Другие расширения