Векторное представление слов в PyTorch
Векторное представление слов — одна из самых фундаментальных и важных техник в обработке естественного языка.
Векторное представление слов отображает дискретные символы слов в непрерывные плотные векторы, позволяя машинам понимать и обрабатывать текстовые данные.
PyTorch предоставляетnn.Embeddingмодуль для реализации этой функциональности, служащий основой для построения различных моделей NLP.
1. Основные понятия встраивания слов
В компьютере текст по сути представляет собой последовательность целых чисел. Каждому слову присваивается уникальный индексный ID, но у этого дискретного представления есть проблема: семантически похожие слова могут иметь близкое значение, однако их ID совершенно не связаны.
Встраивание слов решает эту проблему путём обученияматрицы встраивания:
\[ E \in \mathbb{R}^{V \times D} \]
Где \(V\) — размер словаря, а \(D\) — размерность встраивания. Каждый ID слова соответствует строке в матрице встраивания, а его векторное представление получается с помощью операции поиска:
\[ \text{embedding} = E[\text{word\_id}] \]
Преимущества встраивания слов включают:
- Преобразование высокоразмерных разреженных one-hot векторов в низкоразмерные плотные векторы, что значительно снижает вычислительные затраты
- Семантически похожие слова находятся ближе в векторном пространстве, и сходство слов можно вычислить с помощью косинусного сходства
- Векторы встраивания являются обучаемыми параметрами и могут автоматически настраиваться с помощью обратного распространения ошибки
2. Подробное объяснение nn.Embedding
nn.Embedding— это слой встраивания слов, предоставляемый PyTorch, инкапсулирующий создание матрицы встраивания и операцию поиска.
2.1 Базовое использование
Пример
import torch.nn as nn
# Создание слоя встраивания
# num_embeddings: размер словаря (vocab_size)
# embedding_dim: размерность встраивания (embedding_dim)
vocab_size = 10000
embedding_dim = 256
embedding = nn.Embedding(num_embeddings=vocab_size, embedding_dim=embedding_dim)
# Просмотр формы матрицы встраивания
print(embedding.weight.shape) # torch.Size([10000, 256])
# Входные индексы слов (LongTensor) для получения векторов встраивания
word_ids = torch.tensor([0, 1, 2, 9999]) # Произвольные индексы слов
embedded = embedding(word_ids)
print(embedded.shape) # torch.Size([4, 256])
# Каждый ID слова соответствует 256-мерному вектору
2.2 Подробности параметров nn.Embedding
Пример
embedding = nn.Embedding(
num_embeddings=10000, # Размер словаря, должен быть больше или равен максимальному значению индекса во входных данных
embedding_dim=256, # Размерность вектора эмбеддинга, обычно 50, 100, 200, 300 и т. д.
padding_idx=None, # Индекс слова-заполнителя; вектор эмбеддинга для слова-заполнителя состоит из нулей
max_norm=None, # Максимальная норма вектора эмбеддинга, используется для нормализации
norm_type=2.0, # Тип нормализации, обычно норма L2
scale_grad_by_freq=False,# Масштабировать градиенты по частоте слов
sparse=False, # Использовать ли разреженные градиенты (экономит память GPU, но обучение медленнее)
_weight=None, # Предопределённые веса, используются для загрузки предобученных эмбеддингов
)
# Просмотр количества параметров
total_params = embedding.num_embeddings * embedding.embedding_dim
print(f"Количество параметров слоя эмбеддингов: {total_params:,}")
# 10000 * 256 = 2,560,000
Число параметров в слое эмбеддингов = размер словаря × размерность эмбеддинга. Это очень большая матрица. Обычно слой эмбеддингов NLP-модели составляет большую долю от общего числа параметров модели.
2.3 Индекс паддинга padding_idx
При обработке последовательностей переменной длины короткие последовательности нужно дополнять. Используяpadding_idx, можно зафиксировать вектор эмбеддинга слова паддинга как нулевой вектор, чтобы содержимое паддинга не влияло на модель:
Пример
import torch.nn as nn
# Установить padding_idx=0, то есть индекс 0 — это слово паддинга
embedding = nn.Embedding(num_embeddings=10000, embedding_dim=128, padding_idx=0)
# Инициализация весов
nn.init.uniform_(embedding.weight, -0.1, 0.1)
# Вектор эмбеддинга для индекса 0 состоит из нулей
word_0 = embedding(torch.tensor([0]))
print(f"Эмбеддинг слова-заполнителя: {word_0}") # Все нули
# Остальные индексы остаются обычными
word_5 = embedding(torch.tensor([5]))
print(f"Эмбеддинг слова 5: {word_5}") # Ненулевые значения
2.4 Нормализация максимальной нормы
Использованиеmax_normможно ограничить норму векторов эмбеддингов, не позволяя им становиться слишком большими во время обучения:
Пример
import torch.nn as nn
# Установите максимальную норму равной 1.0
embedding = nn.Embedding(num_embeddings=1000, embedding_dim=64, max_norm=1.0)
# Введите произвольные индексы слов
ids = torch.tensor([1, 2, 3])
embedded = embedding(ids)
# Проверьте L2-норму каждого вектора
norms = torch.norm(embedded, p=2, dim=1)
print(f"Нормы каждого вектора: {norms}") # Все значения близки к 1.0
3. Загрузка предобученных эмбеддингов слов
Использование предобученных эмбеддингов слов может значительно улучшить производительность модели, особенно когда обучающих данных мало. Распространенные предобученные эмбеддинги слов включают Word2Vec, GloVe, FastText и т. д.
3.1 Разница между обучением с нуля и загрузкой предобученных эмбеддингов
| Метод | Преимущества | Недостатки | Применимые сценарии |
|---|---|---|---|
| Случайная инициализация и обучение | Полностью настраиваемый, адаптируется к конкретным задачам | Требует большого объема обучающих данных | Много предметно-специфичных слов и достаточный объем обучающих данных |
| Загрузка предобученных эмбеддингов | Использует знания из крупномасштабных корпусов, быстрое обучение и хорошие результаты | Ограниченный охват словаря, не может обрабатывать слова вне словаря | Общие задачи, ограниченные обучающие данные |
| Замораживание предобученных эмбеддингов | Быстрое обучение, низкое потребление памяти GPU | Эмбеддинги нельзя дообучить | Ограниченные ресурсы для обучения, фокус только на верхних слоях модели |
| Дообучение предобученных эмбеддингов | Можно адаптировать под конкретные задачи | Более медленное обучение, высокое потребление памяти GPU | Умеренный объём данных, определённые доменные различия |
3.2 Загрузка предобученных векторов слов GloVe
GloVe — это предобученный вектор слов, выпущенный Стэнфордским университетом. Ниже показано, как его загрузить:
Пример
import torch.nn as nn
import numpy as np
# Имитация загрузки векторов слов GloVe (на самом деле нужно скачать файлы GloVe)
# Предположим, что уже есть файл векторов слов со следующим форматом: каждая строка содержит слово, за которым следуют его векторы
def load_glove_embeddings(path, word2idx, embedding_dim=300):
"""
Загрузить предобученные векторы слов GloVe
path: путь к файлу векторов слов
word2idx: словарь, отображающий слова в индексы
embedding_dim: размерность векторов слов
"""
embeddings = np.random.randn(len(word2idx), embedding_dim).astype(np.float32)
word_count = 0
with open(path, 'r', encoding='utf-8') as f:
for line in f:
values = line.strip().split()
word = values[0]
if word in word2idx:
word_idx = word2idx[word]
embeddings[word_idx] = np.asarray(values[1:], dtype=np.float32)
word_count += 1
print(f"Загружено {word_count}/{len(word2idx)} векторов слов")
return torch.from_numpy(embeddings)
# Предположим, что словарь уже существует
word2idx = {'hello': 0, 'world': 1, 'example': 2, 'python': 3}
EMBED_DIM = 300
# Загрузить предобученные эмбеддинги и создать слой эмбеддингов
# pretrained_embeddings = load_glove_embeddings('glove.6B.300d.txt', word2idx, EMBED_DIM)
# embedding = nn.Embedding.from_pretrained(pretrained_embeddings, padding_idx=0)
# Упрощённый пример: используем случайно инициализированную предобученную матрицу
pretrained_embeddings = torch.randn(len(word2idx), EMBED_DIM)
embedding = nn.Embedding.from_pretrained(pretrained_embeddings, padding_idx=0)
print(f"Форма слоя эмбеддингов: {embedding.weight.shape}")
3.3 Замораживание и дообучение слоя эмбеддингов
В зависимости от требований задачи вы можете заморозить или дообучить слой эмбеддингов:
Пример
import torch.nn as nn
embedding = nn.Embedding(num_embeddings=10000, embedding_dim=256)
# Метод 1: заморозить слой эмбеддингов (не участвует в обучении)
embedding.weight.requires_grad = False
# Во время обучения не будут обновляться только параметры с embedding.weight.requires_grad = False
# Метод 2: дообучить слой эмбеддингов (участвует в обучении)
embedding.weight.requires_grad = True
# Метод 3: заморозить часть векторов слов (заморозить высокочастотные слова, такие как "the", "is")
# Предположим, что индексы высокочастотных слов находятся в диапазоне 0-99
embedding.weight.requires_grad = True
with torch.no_grad():
embedding.weight[0:100] *= 0 # Или присвоить фиксированные значения
# Исключить замороженные параметры из оптимизатора
optimizer = torch.optim.Adam(
filter(lambda p: p.requires_grad, embedding.parameters()),
lr=1e-3
)
4. Объединение слоя Embedding с RNN/LSTM
Векторное представление слов — это первый слой NLP-модели. Оно преобразует текстовые ID в плотные векторы, которые затем передаются в последовательностные модели, такие как RNN и LSTM, для обработки.
4.1 Классификация текста с помощью слоя Embedding + LSTM
Пример
import torch.nn as nn
class TextClassifier(nn.Module):
"""
Модель классификации текста на основе Embedding Layer + LSTM
"""
def __init__(self, vocab_size, embed_dim, hidden_size, num_classes, padding_idx=0):
super().__init__()
# Слой встраивания слов
self.embedding = nn.Embedding(
num_embeddings=vocab_size,
embedding_dim=embed_dim,
padding_idx=padding_idx
)
# Слой LSTM
self.lstm = nn.LSTM(
input_size=embed_dim,
hidden_size=hidden_size,
num_layers=2,
batch_first=True,
bidirectional=True,
dropout=0.3
)
# Классификатор
self.fc = nn.Linear(hidden_size * 2, num_classes)
def forward(self, x):
# x: (batch_size, seq_len) - индексы слов
embedded = self.embedding(x) # (batch_size, seq_len, embed_dim)
# Выход LSTM
output, (h_n, c_n) = self.lstm(embedded)
# Взять скрытое состояние последнего временного шага (двунаправленная конкатенация)
# Последнее скрытое состояние прямого направления: h_n[-2]
# Последнее скрытое состояние обратного направления: h_n[-1]
h_combined = torch.cat([h_n[-2], h_n[-1]], dim=-1)
# Классификация
logits = self.fc(h_combined)
return logits
# Создать экземпляр модели
VOCAB_SIZE = 10000
EMBED_DIM = 128
HIDDEN_SIZE = 128
NUM_CLASSES = 2
model = TextClassifier(VOCAB_SIZE, EMBED_DIM, HIDDEN_SIZE, NUM_CLASSES)
# Имитация входа: batch_size=4, длина последовательности=10
batch_input = torch.randint(1, VOCAB_SIZE, (4, 10))
output = model(batch_input)
print(f"Форма входа: {batch_input.shape}") # torch.Size([4, 10])
print(f"Форма выхода: {output.shape}") # torch.Size([4, 2])
4.2 Использование предварительно обученных векторов слов
Пример
import torch.nn as nn
# Предположим, что предварительно обученные векторы слов загружены
pretrained_vectors = torch.randn(10000, 300) # Имитация предварительно обученных векторов
# Создать слой встраивания и загрузить предварительно обученные веса
embedding = nn.Embedding.from_pretrained(
pretrained_vectors,
padding_idx=0,
freeze=False # True: заморозить и не обучать, False: дообучать
)
# При использовании GloVe или других предобученных векторов слов обычно сначала замораживают на несколько эпох, затем размораживают для дообучения
# В течение первых нескольких эпох обучайте только верхние слои модели
embedding.weight.requires_grad = False
# После обучения в течение нескольких эпох разморозьте слой эмбеддингов для дообучения
# embedding.weight.requires_grad = True
5. Позиционное кодирование
В отличие от RNN/LSTM, модель Transformer не включает информацию о позиции. Чтобы модель воспринимала порядок слов в последовательности, необходимо дополнительно добавить позиционное кодирование.
5.1 Принцип позиционного кодирования
Позиционное кодирование использует функции синуса и косинуса для генерации векторов позиций:
\[ \begin{aligned} PE_{(pos, 2i)} &= \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right) \\ PE_{(pos, 2i+1)} &= \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right) \end{aligned} \]
Особенность этого метода кодирования заключается в том, что кодировки на разных позициях могут быть преобразованы друг в друга с помощью линейных преобразований, что позволяет модели легко изучать позиционные взаимосвязи.
5.2 Реализация позиционного кодирования
Пример
import torch.nn as nn
import math
class PositionalEncoding(nn.Module):
"""
Слой позиционного кодирования
"""
def __init__(self, d_model, max_len=5000):
super().__init__()
# Создать матрицу позиционного кодирования
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
# Вычислить член делителя
div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
# Использовать sin для чётных индексов и cos для нечётных индексов
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
# Добавить размерность пакета и зарегистрировать её как буфер, не участвующий в вычислении градиента
pe = pe.unsqueeze(0) # (1, max_len, d_model)
self.register_buffer('pe', pe)
def forward(self, x):
"""
x: (batch_size, seq_len, d_model)
"""
seq_len = x.size(1)
# Взять срез позиционного кодирования соответствующей длины и добавить его
x = x + self.pe[:, :seq_len, :]
return x
# Пример использования
d_model = 256
max_len = 100
pos_encoding = PositionalEncoding(d_model, max_len)
# Смоделированный вход: batch_size=4, seq_len=20, d_model=256
x = torch.randn(4, 20, d_model)
x = pos_encoding(x)
print(f"Форма входа: {x.shape}") # torch.Size([4, 20, 256])
Позиционное кодирование — ключевой компонент архитектуры Transformer. Оно позволяет модели различать слова на разных позициях, даже если их векторы эмбеддингов одинаковы.
5.3 Обучаемое позиционное кодирование
В дополнение к фиксированному позиционному кодированию также можно использовать обучаемое позиционное кодирование:
Пример
import torch.nn as nn
class LearnablePositionalEncoding(nn.Module):
"""
Обучаемое позиционное кодирование
"""
def __init__(self, d_model, max_len=5000):
super().__init__()
self.pos_embedding = nn.Embedding(max_len, d_model)
def forward(self, x):
batch_size, seq_len, d_model = x.size(1), x.size(1), x.size(2)
# Создать индексы позиций [0, 1, 2, ..., seq_len-1]
positions = torch.arange(seq_len, device=x.device).unsqueeze(0).expand(batch_size, -1)
pos_encoded = self.pos_embedding(positions)
return x + pos_encoded
# Пример использования
pos_encoding = LearnablePositionalEncoding(d_model=256, max_len=100)
x = torch.randn(4, 20, 256)
x = pos_encoding(x)
print(f"Форма выхода: {x.shape}") # torch.Size([4, 20, 256])
6. Продвинутые методы для слоёв эмбеддингов
6.1. Снижение использования памяти GPU
Когда словарь очень большой, слой эмбеддингов потребляет много памяти GPU. Для оптимизации можно использовать следующие методы:
Пример
import torch.nn as nn
# Метод 1: Использовать разреженные градиенты (sparse=True)
embedding = nn.Embedding(
num_embeddings=100000,
embedding_dim=256,
sparse=True # Градиенты хранятся в разреженном формате, что экономит память GPU
)
# Техника 2: Использовать квантование
# Преобразование float32 в int8 или float16
embedding_int8 = embedding.to(torch.int8)
# Техника 3: Заморозить редко используемые векторы слов
# В крупномасштабном словаре обучайте только высокочастотные слова; низкочастотные слова оставляйте замороженными
embedding = nn.Embedding(num_embeddings=100000, embedding_dim=256)
embedding.weight.requires_grad = True
# Заморозить векторы слов с индексом больше 50000
with torch.no_grad():
embedding.weight[50000:] *= 0
embedding.weight.requires_grad = False
# Обучать только высокочастотные слова
embedding.weight[1:50000].requires_grad = True
6.2 Обработка слов вне словаря (OOV)
Слова, отсутствующие в словаре (слова вне словаря / OOV), могут появляться в тестовом наборе и требуют специальной обработки:
Пример
import torch.nn as nn
class EmbeddingWithOOV(nn.Module):
"""
Слой эмбеддингов, поддерживающий слова вне словаря
"""
def __init__(self, vocab_size, embed_dim, oov_idx=Отсутствует):
super().__init__()
self.embedding = nn.Embedding(vocab_size + 1, embed_dim, padding_idx=0)
self.oov_idx = oov_idx if oov_idx is not None else vocab_size # Использовать последний индекс как OOV
def forward(self, x):
# Заменить индексы OOV-слов на oov_idx
oov_mask = x >= self.vocab_size
x = x.clone()
x[oov_mask] = self.oov_idx
return self.embedding(x)
# Использовать методы хеширования для обработки больших словарей
class HashEmbedding(nn.Module):
"""
Слой эмбеддингов с использованием хеширования для обработки словарей произвольного размера
"""
def __init__(self, num_buckets, embed_dim):
super().__init__()
self.num_buckets = num_buckets
self.embedding = nn.Embedding(num_buckets, embed_dim)
def forward(self, x):
# Хеширование индексов слов в бакеты
# Использовать метод хеширования словаря Python
hashed = torch.remainder(x, self.num_buckets)
return self.embedding(hashed)
6.3 Субсловные эмбеддинги
Для языков с богатой морфологией (таких как немецкий и русский) субсловные эмбеддинги могут эффективно справляться с проблемой слов вне словаря:
Пример
import torch.nn as nn
class SubwordEmbedding(nn.Module):
"""
Упрощённый пример субсловных эмбеддингов
На практике для токенизации следует использовать такие алгоритмы, как BPE и WordPiece
"""
def __init__(self, vocab_size, embed_dim, char_dim=50):
super().__init__()
# Эмбеддинг на уровне символов
self.char_embedding = nn.Embedding(vocab_size, char_dim)
# Эмбеддинг на уровне слов
self.word_embedding = nn.Embedding(vocab_size, embed_dim - char_dim)
# LSTM на уровне символов для объединения векторов символов
self.char_lstm = nn.LSTM(
char_dim, char_dim,
batch_first=True, bidirectional=True
)
def forward(self, word_ids, char_ids):
"""
word_ids: индексы слов (batch_size, seq_len)
char_ids: индексы символов (batch_size, seq_len, max_word_len)
"""
# Векторное представление слов
word_emb = self.word_embedding(word_ids)
# Символьный эмбеддинг + LSTM
batch_size, seq_len, max_word_len = char_ids.shape
char_ids_flat = char_ids.view(-1, max_word_len) # (batch_size * seq_len, max_word_len)
char_emb = self.char_embedding(char_ids_flat) # (batch_size * seq_len, max_word_len, char_dim)
char_output, (h_n, _) = self.char_lstm(char_emb)
# Взять финальные скрытые состояния двунаправленного слоя и конкатенировать
char_rep = torch.cat([h_n[-2], h_n[-1]], dim=-1) # (batch_size * seq_len, char_dim * 2)
char_rep = char_rep.view(batch_size, seq_len, -1) # (batch_size, seq_len, char_dim * 2)
# Объединить эмбеддинг слова и символьное представление
combined = torch.cat([word_emb, char_rep], dim=-1)
return combined
7. Полный практический пример: модель классификации текста
Ниже приведён полный пример модели классификации текста, включая слой эмбеддингов, LSTM и классификатор:
Пример
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# ── Параметры конфигурации ──────────────────────────────────────
VOCAB_SIZE = 10000
EMBED_DIM = 128
HIDDEN_SIZE = 128
NUM_LAYERS = 2
NUM_CLASSES = 5
DROPOUT = 0.3
MAX_LEN = 200
# ── Определение модели ──────────────────────────────────────
class TextClassificationModel(nn.Module):
def __init__(self, vocab_size, embed_dim, hidden_size,
num_layers, num_classes, dropout=0.3, padding_idx=0):
super().__init__()
# Слой эмбеддингов
self.embedding = nn.Embedding(
vocab_size,
embed_dim,
padding_idx=padding_idx
)
# BiLSTM
self.lstm = nn.LSTM(
embed_dim,
hidden_size,
num_layers=num_layers,
batch_first=True,
bidirectional=True,
dropout=dropout if num_layers > 1 else 0
)
# Классификатор
self.dropout = nn.Dropout(dropout)
self.fc = nn.Linear(hidden_size * 2, num_classes)
def forward(self, x):
# x: (batch_size, seq_len)
embedded = self.embedding(x) # (batch_size, seq_len, embed_dim)
# LSTM
output, (h_n, c_n) = self.lstm(embedded)
# Объединить финальные скрытые состояния двунаправленной сети
h_forward = h_n[-2] # (batch_size, hidden_size)
h_backward = h_n[-1] # (batch_size, hidden_size)
h_combined = torch.cat([h_forward, h_backward], dim=-1)
# Классификация
dropped = self.dropout(h_combined)
logits = self.fc(droped)
return logits
# ── Набор данных ──────────────────────────────────────
class TextDataset(Dataset):
def __init__(self, texts, labels, vocab, max_len=200):
self.texts = texts
self.labels = labels
self.vocab = vocab
self.max_len = max_len
def __len__(self):
return len(self.texts)
def __getitem__(self, idx):
text = self.texts[idx][:self.max_len]
# Преобразовать слова в индексы, неизвестные слова обозначены 1 (<UNK>)
ids = [self.vocab.get(word, 1) for word in text]
# Дополнить нулями до фиксированной длины
if len(ids) < self.max_len:
ids += [0] * (self.max_len - len(ids))
return torch.tensor(ids), torch.tensor(self.labels[idx])
# ── Функция обучения ──────────────────────────────────────
def train_epoch(model, loader, optimizer, criterion, device):
model.train()
total_loss = 0
correct = 0
total = 0
for inputs, labels in loader:
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
total_loss += loss.item() * inputs.size(0)
_, predicted = outputs.max(1)
correct += predicted.eq(labels).sum().item()
total += labels.size(0)
return total_loss / total, correct / total
# ── Инициализация и обучение ──────────────────────────────────
# Предполагается, что словарь уже существует
word2idx = {'<PAD>': 0, '<UNK>': 1} # Словарь нужно построить на основе реального корпуса
model = TextClassificationModel(
VOCAB_SIZE, EMBED_DIM, HIDDEN_SIZE,
NUM_LAYERS, NUM_CLASSES, DROPOUT
).to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=1e-3)
# Имитация обучения
print("Начало обучения...")
for epoch in range(10):
train_loss, train_acc = train_epoch(model, None, optimizer, criterion, device)
print(f"Epoch {epoch+1}: Loss={train_loss:.4f}, Acc={train_acc:.4f}")
8. Краткий справочник по API
8.1 Общие операции с nn.Embedding
| Действие | Code |
|---|---|
| Создать слой эмбеддингов | nn.Embedding(num_embeddings, embedding_dim) |
| Загрузить предобученные эмбеддинги | nn.Embedding.from_pretrained(weights) |
| Поиск по таблице для получения эмбеддингов | embedding(word_ids) |
| Заморозить эмбеддинги | embedding.weight.requires_grad = False |
| Получить векторы эмбеддингов | embedding.weight[idx] |
8.2 Ресурсы предобученных векторов слов
| Ресурс | Измерение | Особенности |
|---|---|---|
| GloVe | 50, 100, 200, 300 | Статистика совместной встречаемости слов, быстрое обучение |
| Word2Vec | 50-500 | Обучен Google, широкий охват |
| FastText | 300 | Поддерживает субслова, хорошо справляется с OOV |
| BERT | 768+ | Зависит от контекста, наилучшая производительность |
8.3 Рекомендации по выбору слоя эмбеддингов
数据量小(< 10K)
-> 使用预训练词向量(GloVe/FastText)+ 冻结或微调
数据量中等(10K ~ 100K)
-> 使用预训练词向量 + 微调
数据量大(> 100K)
-> 可考虑从头训练,或使用大规模预训练模型
领域差异大
-> 使用领域相关预训练模型或增量训练
资源受限
-> 冻结嵌入层,使用较小的嵌入维度
Другие расширения