Zero to Hero, лекция 3: MLP-модель имён по Бенджио (makemore, часть 2)
Подробный конспект лекции Карпатого: от таблицы биграмм к нейросетевой языковой модели Бенджио 2003 года. Эмбеддинги символов, скрытый слой, устройство тензоров, F.cross_entropy, мини-батчи, поиск learning rate и разбиение на train/dev/test.
Коротко
Заголовок раздела «Коротко»- Биграммная таблица не растёт: с каждым символом контекста строк становится в 27 раз больше. Карпатый переходит к модели из статьи Бенджио и соавторов 2003 года. Каждый символ получает короткий обучаемый вектор — эмбеддингэмбеддинг, векторное представлениеEN embedding. Векторы трёх символов окна склеиваются, идут через скрытый слой с tanh, а на выходе — 27 логитов и softmax.
- Попутно — внутренности
torch.Tensor. Данные всегда лежат в памяти одной лентой, аviewлишь меняет способ на неё смотреть. Поэтому склейка векторов черезviewбесплатна, а черезtorch.cat— нет. - Почему вместо самописного softmax и NLL берут
F.cross_entropy: меньше памяти, проще обратный проход и защита от переполнения экспоненты. - Основы машинного обучения на живом примере: переобучение одного батча как проверка кода, мини-батчимини-батчEN mini-batchНебольшая случайная порция примеров, по которой считается одна оценка градиента и делается один шаг., поиск learning rate по графику, его затухание, разбиение на train/dev/test, недообучениенедообучениеEN underfitting и что с ним делать.
- Результат — 2.17 на валидации против 2.45 у биграмм. На двумерных эмбеддингах видно, что сеть сама сгруппировала
гласные, а
qи служебная точка оказались в стороне.
Как смотреть вместе с курсом
Заголовок раздела «Как смотреть вместе с курсом»Курс повторяет лекцию на русских именах в уроке 4.1.4 «Нейросетевая языковая модель: MLP по Бенджио (2003)». Удобнее всего сначала посмотреть лекцию, потом пройти урок: он медленнее объясняет кривые обучения и добавляет раздел про ручной backprop. Перед лекцией полезно освежить softmax и его ловушку с переполнением (1.3.2) и мини-батчевый спуск (1.4.1). Про эмбеддинги слов в духе статьи Бенджио подробно рассказывает урок 4.3.1.
Новичку можно бегло посмотреть главу про устройство тензора (18:38) — главное запомнить, что view не копирует
данные. Главы про learning rate (45:41) и про разбиение данных (53:22) пропускать не надо: на них держится
вся дальнейшая практика.
Код лекции — ноутбук makemore_part2_mlp.ipynb
(MIT), данные names.txt — в репозитории karpathy/makemore. Статья:
Bengio et al., A Neural Probabilistic Language Model
(JMLR, 2003). Китайская учебная версия с переведёнными пояснениями —
003_makemore_MLP.
Карта лекции
Заголовок раздела «Карта лекции»Таймкоды — из глав в описании видео.
| Время | Глава в оригинале | О чём |
|---|---|---|
| 0:00 | intro | почему таблица биграмм тупиковая |
| 1:48 | Bengio et al. 2003 (MLP language model) paper walkthrough | разбор статьи |
| 9:07 | (re-)building our training dataset | окно из трёх символов |
| 12:21 | implementing the embedding lookup table | таблица C и индексация |
| 18:38 | implementing the hidden layer + internals of torch.Tensor: storage, views | скрытый слой, view, хранилище тензора |
| 29:17 | implementing the output layer | выходной слой |
| 29:58 | implementing the negative log likelihood loss | NLL вручную |
| 32:22 | summary of the full network | вся сеть целиком |
| 32:52 | introducing F.cross_entropy and why | зачем встроенная функция |
| 37:58 | implementing the training loop, overfitting one batch | цикл обучения, переобучение 32 примеров |
| 41:30 | training on the full dataset, minibatches | весь набор, мини-батчи |
| 45:41 | finding a good initial learning rate | поиск learning rate |
| 53:22 | splitting up the dataset into train/val/test splits and why | разбиение данных |
| 1:00:51 | experiment: larger hidden layer | шире скрытый слой |
| 1:05:28 | visualizing the character embeddings | картинка эмбеддингов |
| 1:07:17 | experiment: larger embedding size | эмбеддинги длиннее |
| 1:11:50 | summary of our final code, conclusion | итоговый код, 2.17 на валидации |
| 1:13:24 | sampling from the model | генерация имён |
| 1:14:59 | google collab (new!!) notebook advertisement | ноутбук в Colab |
1. Почему таблица не годится
Заголовок раздела «1. Почему таблица не годится»Биграмма видит один символ, и имена выходят плохими. Хочется дать больше контекста, но таблица растёт экспоненциально. При одном символе контекстов 27, при двух — , при трёх — почти 20 тысяч. Строк слишком много, а примеров на каждую слишком мало. Нужна модель, у которой число параметров не взрывается с длиной контекста.
2. Статья Бенджио 2003 года
Заголовок раздела «2. Статья Бенджио 2003 года»Карпатый оговаривается: это не первая работа, где нейросеть предсказывает следующий токен, но очень влиятельная и хорошо написанная. Её часто цитируют как символ самой идеи. В статье модель словесная: словарь около 17 тысяч слов, у каждого слова — вектор признаков длины, например, 30. Сначала векторы случайны, а при обучении backprop двигает их в этом пространстве. Слова с похожим смыслом оказываются рядом.
Зачем это нужно, показывает пример из статьи. Модели нужно продолжить фразу «a dog was running in a …», а такой фразы в данных не было. Зато была «the dog was running in a …». Если сеть выучила, что «a» и «the» взаимозаменяемы, их векторы окажутся рядом, и знание перенесётся. Так же можно перенести знания между «cat» и «dog» или «walking» и «running». Таблица так не умеет: для неё каждый контекст — отдельная строка.
flowchart LR X["3 номера<br/>символов"] --> C["таблица C<br/>общая для всех позиций"] C --> E["3 вектора<br/>склеены в один"] E --> H["скрытый слой<br/>tanh"] H --> O["выходной слой<br/>27 логитов"] O --> S["softmax →<br/>P(следующий)"]
Устройство сети по статье:
- Три предыдущих слова — номера от 0 до 16 999.
- Таблица
Cразмером : номер выбирает строку. Таблица одна для всех трёх позиций. - Три вектора дают входной слой из 90 чисел.
- Скрытый слой полносвязный, с tanh. Его размер — гиперпараметргиперпараметрEN hyperparameterНастройка, которую не учат градиентом, а выбирают по валидации — степень полинома, λ, learning rate, число слоёв.: выбор проектировщика, его подбирают экспериментами.
- Выходной слой — 17 тысяч нейронов, по логиту на слово. Здесь больше всего вычислений.
- Softmax и максимизация лог-правдоподобия правильного слова. Учатся все параметры: оба слоя и таблица
C.
Пунктирные стрелки на схеме из статьи — прямые связи со входа на выход. Это вариант модели, который Карпатый не реализует.
3. Датасет с окном
Заголовок раздела «3. Датасет с окном»block_size — длина контекста: сколько символов смотрим, чтобы предсказать следующий. В начале имени окно
заполнено точками, затем сдвигается на символ за шагом. Из emma получаются пять примеров: ... → e, ..e → m,
.em → m, emm → a, mma → .. Код из ноутбука лекции (MIT), комментарии наши:
block_size = 3 # длина контекста: сколько символов видим перед следующим
def build_dataset(words): X, Y = [], [] for w in words: context = [0] * block_size # в начале имени окно из одних '.' for ch in w + '.': ix = stoi[ch] X.append(context) # вход: три предыдущих символа Y.append(ix) # ответ: следующий символ context = context[1:] + [ix] # сдвигаем окно: отрезали старый, добавили новый return torch.tensor(X), torch.tensor(Y)Пока код пишется, Карпатый берёт только первые пять имён — это 32 примера. Окно можно сделать любым: при
block_size = 10 модель видела бы десять символов.
4. Таблица эмбеддингов
Заголовок раздела «4. Таблица эмбеддингов»Для 27 символов не нужно 30 измерений. Карпатый начинает с крошечного пространства: C = torch.randn((27, 2)).
Эмбеддинг символа 5 можно получить двумя способами:
- просто индексацией:
C[5]; - как в прошлой лекции:
F.one_hot(torch.tensor(5), num_classes=27).float() @ C.
Результат одинаковый — умножение на one-hot выбирает строку. По дороге Карпатый нарочно ловит две ошибки:
one_hot требует тензор, а не число, а целочисленный тензор нельзя умножить на вещественный, нужен .float().
Вывод: таблицу эмбеддингов можно считать первым слоем сети — линейным, без нелинейности, с матрицей весов C
и one-hot на входе. Но индексация намного быстрее, поэтому дальше используется она.
Индексация в PyTorch гибкая. Можно брать строки списком (C[[5, 6, 7]]), тензором, с повторами, и даже двумерным
тензором номеров: C[X] для X формы даёт тензор — для каждого номера своя
строка таблицы. В курсе это слой эмбеддинговслой эмбеддингов (таблица эмбеддингов)EN embedding layerМатрица V × d; по номеру токена возвращает его строку. Эквивалентно one-hot × матрица. В PyTorch — nn.Embedding.; в PyTorch — nn.Embedding.
5. Скрытый слой и устройство тензора
Заголовок раздела «5. Скрытый слой и устройство тензора»Скрытому слою нужен вход формы : три двумерных вектора подряд. А у нас . Карпатый показывает три способа и заодно учит, что в огромной библиотеке PyTorch обычно есть несколько путей, и некоторые лучше:
import torch
emb = torch.randn(32, 3, 2) # 32 примера × 3 символа × 2 числа
# 1) руками склеить три среза — не обобщается на другой block_sizex1 = torch.cat([emb[:, 0, :], emb[:, 1, :], emb[:, 2, :]], 1)# 2) unbind режет по оси 1 на список срезов любой длиныx2 = torch.cat(torch.unbind(emb, 1), 1)# 3) view — просто посмотреть на те же числа как на 32×6x3 = emb.view(32, 6) # или emb.view(-1, 6): PyTorch сам вычислит 32
print((x1 == x3).all().item(), (x2 == x3).all().item()) # True Trueprint(x3.data_ptr() == emb.data_ptr()) # True: view использует ту же памятьprint(x1.data_ptr() == emb.data_ptr()) # False: cat выделил новуюПочему view бесплатен. У каждого тензора есть хранилище (storage) — числа одной лентой, как они лежат
в памяти. Форма, шаги (strides) и смещение — лишь служебные атрибуты: они говорят, как читать ленту в виде
многомерного массива. view меняет только эти атрибуты, ничего не копируя. Так 18 чисел можно увидеть как
, или . А torch.cat всегда создаёт новый тензор с новой памятью.
Подробнее Карпатый советует блог-пост Эдварда Янга «PyTorch internals».
Скрытый слой — h = torch.tanh(emb.view(-1, 6) @ W1 + b1) при W1 формы . Здесь стоит проверить
broadcasting: . Вектор смещения дополняется до строки и копируется вниз.
Каждому примеру прибавляется одно и то же смещение — то, что нужно. Карпатый советует такие места проверять
всегда.
6. Выходной слой, loss и F.cross_entropy
Заголовок раздела «6. Выходной слой, loss и F.cross_entropy»Выходной слой: W2 формы , b2 из 27 чисел, логиты . Дальше, как в прошлой лекции:
экспонента, нормировка, выбор вероятностей правильных символов, минус среднее логарифма. Со случайными весами
loss около 17. Всего параметров в этой версии около 3400.
Затем эти строки заменяются одной: loss = F.cross_entropy(logits, Y). Число то же, но Карпатый называет три
причины никогда не писать это вручную на практике:
- Память и скорость прямого прохода. Ручная версия создаёт промежуточные тензоры (счётчики, вероятности). PyTorch объединяет операции в одно ядро (fused kernel) и лишнего не хранит.
- Обратный проход проще. Как с tanh в micrograd: если продифференцировать составное выражение целиком, формула часто сильно упрощается. Для cross-entropy она совсем короткая — её выводят в пятой лекции.
- Численная устойчивость. Экспонента большого логита не помещается в float. Но к логитам можно прибавить любую константу — softmax не изменится. Поэтому PyTorch вычитает из логитов максимум: самый большой становится нулём, остальные отрицательными, и переполнения нет.
import torchimport torch.nn.functional as F
logits = torch.tensor([-2.0, 3.0, -3.0, 0.0, 100.0]) # один логит очень большойcounts = logits.exp() # e^100 = inf во float32print(counts / counts.sum()) # tensor([0., 0., 0., 0., nan]) — сломалосьprint(F.softmax(logits, 0)) # почти [0, 0, 0, 0, 1] — встроенная версия вычитает максимумКурс разбирает эту ловушку в разделе «Ловушка: переполнение» урока 1.3.2 и пишет устойчивый softmax руками.
7. Обучение: переобучить один батч, потом мини-батчи
Заголовок раздела «7. Обучение: переобучить один батч, потом мини-батчи»Цикл обучения — тот же, что в micrograd: обнулить градиенты (p.grad = None), loss.backward(), шаг
p.data += -lr * p.grad. Не забудьте requires_grad = True у всех параметров. Сначала сеть учится на тех же
32 примерах из пяти имён, и loss быстро падает почти до нуля. Около 3400 параметров на 32 примера — сеть просто
запоминает данные. Это переобучение одного батча, полезная проверка, что код вообще способен учиться.
В курсе она входит в «три проверки перед долгим запуском».
Ровно ноль не получается, и Карпатый объясняет почему. Один и тот же вход ... (начало имени) встречается
с ответами e, o, a, s — у пяти имён разные первые буквы. Предсказать их все сразу невозможно.
На всём наборе примеров уже около 228 тысяч, и каждый шаг идёт долго. Решение — мини-батчи: на каждом шаге
выбираются 32 случайных примера (torch.randint), и прямой проход, обратный проход и шаг делаются только
на них. Градиент по батчу — лишь оценка настоящего, но, по словам Карпатого, лучше сделать много шагов
с приблизительным градиентом, чем мало шагов с точным. Обучение становится почти мгновенным. Раз loss одного
батча шумный, Карпатый время от времени оценивает loss на всём наборе.
8. Как найти learning rate
Заголовок раздела «8. Как найти learning rate»Шаг 0.1 был взят наугад. Карпатый показывает простой способ его найти:
- Грубо найти границы. При 0.001 loss почти не падает, при 1 падает, но скачет, при 10 обучение разваливается. Значит, хороший шаг где-то между 0.001 и 1.
- Сделать 1000 шагов, на каждом увеличивая learning rate. Растить его нужно экспоненциально, а не линейно:
lre = torch.linspace(-3, 0, 1000)— показатели степени,lrs = 10**lre— сами шаги. - Построить график loss от показателя степени. Слева loss почти не меняется, потом наступает «долина», справа начинается неустойчивость. Хороший шаг — в долине. У Карпатого она около , то есть 0.1. Исходная догадка оказалась удачной, но теперь в ней есть уверенность.
Дальше — долгое обучение с 0.1, а когда loss выходит на плато — затухание (decay): шаг уменьшается в 10 раз и делается ещё немного шагов. Так получается около 2.3 — уже лучше биграммы (2.45). Карпатый признаёт, что это кустарно и в продакшене делают иначе, но порядок действий именно такой. В курсе этот приём называется lr finderпоиск learning rate по графику (lr finder)EN learning rate finder (LR range test)Короткий прогон, в котором learning rate растёт экспоненциально от шага к шагу. По графику «loss от lr» берут значение в несколько раз меньше того, где loss начинает расти., и урок 4.1.4 проходит его на своих данных.
9. Train, dev и test
Заголовок раздела «9. Train, dev и test»Тут Карпатый себя поправляет: «лучше» пока сказать нельзя. Маленькая модель на 3400 параметров не может просто запомнить данные. Но чем больше параметров, тем лучше сеть умеет переобучатьсяпереобучениеEN overfitting: loss на обучающих данных падает почти до нуля, сеть выдаёт имена прямо из набора, а на новых именах loss большой.
Стандартное решение — три части данных:
| Часть | Доля | Для чего |
|---|---|---|
| trainобучающая выборка (train)EN training set | 80% | подбирать параметры градиентным спуском |
| dev / validationвалидационная выборка (val, dev)EN validation setНужна для выбора гиперпараметров и ранней остановки. Тест при этом не трогаем. | 10% | подбирать гиперпараметры: размер слоёв, эмбеддингов, силу регуляризации |
| testтестовая выборка (test)EN test setСмотрим на неё один раз — в самом конце, чтобы честно оценить качество. | 10% | одна финальная оценка в самом конце |
Тест можно смотреть очень редко. Каждый раз, когда вы что-то узнаёте по тесту и меняете модель, вы немного учитесь
и на нём. Имена перемешиваются с random.seed(42), из 32 033 имён получается 25 626 для обучения, 3203 для
валидации и 3204 для теста. В ноутбуке это 182 441, 22 902 и 22 803 примера соответственно.
После обучения на train loss на train и на dev почти одинаковый, около 2.3. Значит, переобучения нет, сеть слишком мала — недообучение. Лечится оно ростом модели.
10. Эксперименты: шире слой, длиннее эмбеддинги
Заголовок раздела «10. Эксперименты: шире слой, длиннее эмбеддинги»Скрытый слой 300 нейронов — около 10 тысяч параметров. Кривая loss «толстая»: батч из 32 примеров даёт много шума. Улучшение есть, но небольшое: после пары уменьшений шага — 2.23 на train и 2.24 на dev. Карпатый подозревает, что узкое место — двумерные эмбеддинги: 27 символов втиснуты в два числа.
Картинка эмбеддингов. Пока векторы двумерные, их можно нарисовать. У сети появилась структура: гласные
a, e, i, o, u собрались рядом — сеть считает их похожими и почти взаимозаменяемыми. q стоит особняком, и
служебная точка тоже далеко от остальных. Курс рисует ту же картинку для русских имён в уроке
4.1.4.
Эмбеддинги длины 10, скрытый слой 200 — 11 897 параметров. Карпатый строит график не loss, а log10(loss):
логарифм сжимает «хоккейную клюшку» в начале обучения, и кривую лучше видно. Loss на train и dev начинают
понемногу расходиться — сеть подходит к границе переобучения. Итоговый рецепт: 200 тысяч шагов, первые 100 тысяч
с шагом 0.1, остальные с 0.01. Лучший результат Карпатого — 2.17 на валидации. В ноутбуке остались train
2.126 и dev 2.170. Вот этот код целиком (MIT), комментарии наши:
import randomimport torchimport torch.nn.functional as F
random.seed(42)random.shuffle(words)n1, n2 = int(0.8 * len(words)), int(0.9 * len(words))Xtr, Ytr = build_dataset(words[:n1]) # 80% — учим параметрыXdev, Ydev = build_dataset(words[n1:n2]) # 10% — подбираем гиперпараметрыXte, Yte = build_dataset(words[n2:]) # 10% — финальная оценка
g = torch.Generator().manual_seed(2147483647)C = torch.randn((27, 10), generator=g) # эмбеддинги: 10 чисел на символW1 = torch.randn((30, 200), generator=g) # 3 символа × 10 = 30 входов, 200 нейроновb1 = torch.randn(200, generator=g)W2 = torch.randn((200, 27), generator=g) # 27 логитовb2 = torch.randn(27, generator=g)parameters = [C, W1, b1, W2, b2] # всего 11 897 чиселfor p in parameters: p.requires_grad = True
for i in range(200000): ix = torch.randint(0, Xtr.shape[0], (32,)) # мини-батч из 32 примеров emb = C[Xtr[ix]] # (32, 3, 10) h = torch.tanh(emb.view(-1, 30) @ W1 + b1) # (32, 200) logits = h @ W2 + b2 # (32, 27) loss = F.cross_entropy(logits, Ytr[ix]) for p in parameters: p.grad = None loss.backward() lr = 0.1 if i < 100000 else 0.01 # ступенчатое затухание шага for p in parameters: p.data += -lr * p.gradНа CPU 200 тысяч шагов занимают несколько минут. Для проверки идеи хватит и 20 тысяч: у нас за 20 секунд вышло 2.30 на train и 2.31 на dev.
11. Генерация имён
Заголовок раздела «11. Генерация имён»Генерация повторяет прошлую лекцию, только вход теперь — окно из трёх символов. Начинаем с ..., считаем
эмбеддинги и скрытый слой, получаем вероятности через F.softmax (он, как и cross_entropy, защищён от
переполнения), выбираем символ, сдвигаем окно — пока не выпадет .:
g = torch.Generator().manual_seed(2147483647 + 10)for _ in range(20): out, context = [], [0] * block_size # начинаем с '...' while True: emb = C[torch.tensor([context])] # (1, 3, 10): батч из одного примера h = torch.tanh(emb.view(1, -1) @ W1 + b1) probs = F.softmax(h @ W2 + b2, dim=1) ix = torch.multinomial(probs, num_samples=1, generator=g).item() context = context[1:] + [ix] # сдвигаем окно out.append(ix) if ix == 0: # выпал '.', имя закончилось break print(''.join(itos[i] for i in out))В ноутбуке — carmahela, jhovi, kimrin, thil, halanna, jazhien, amerynci, nellara, kaleigh, ham.
Заметно ближе к именам, чем у биграммы, но до хороших ещё далеко.
12. Задание: побейте 2.17
Заголовок раздела «12. Задание: побейте 2.17»В конце Карпатый предлагает побить его результат и перечисляет «ручки»:
- число нейронов скрытого слоя;
- длина эмбеддингов;
- длина контекста — сколько символов подаётся на вход;
- детали оптимизации: сколько шагов, какой шаг, как и когда его уменьшать;
- размер батча — от него зависит, насколько быстро в секундах сеть сходится.
И советует прочитать статью Бенджио: 19 страниц, но теперь большая их часть будет понятна, а идей для улучшений там много. Последняя минута видео — реклама Colab: ноутбук можно запустить прямо в браузере, ничего не устанавливая.
Где курс объясняет то же самое и что есть сверх курса
Заголовок раздела «Где курс объясняет то же самое и что есть сверх курса»| Тема лекции | Где в курсе | Что в лекции сверх курса |
|---|---|---|
| Модель Бенджио, окно, эмбеддинги, скрытый слой | 4.1.4 (на русских именах) | разбор самой статьи и примера «a dog / the dog» |
| Эмбеддинги как векторы смысла | 4.3.1 | — |
view, хранилище, шаги (strides) | 0.3.1 (то же в NumPy), 4.1.4 | сравнение cat, unbind и view в PyTorch |
F.cross_entropy, устойчивый softmax | 1.3.2, 3.3.2 | три причины в одном месте: память, обратный проход, переполнение |
| Переобучение одного батча | 3.3.3 | почему loss не доходит до нуля на неоднозначных входах |
| Мини-батчи, learning rate, затухание | 1.4.1, 4.1.4 | поиск шага руками по экспоненциальной сетке |
| Train / dev / test, недо- и переобучение | 4.1.4 | — |
| Ручной backprop через эту сеть | 4.1.4, раздел «Backprop руками» | в лекции его нет — он в пятой лекции |
Урок 4.1.4 идёт дальше лекции в двух местах: подробнее читает кривые обучения и добавляет weight decay. Обратите внимание на масштаб: в курсе 242 русских имени, у Карпатого — 32 тысячи. Поэтому в курсе переобучение наступает гораздо раньше.
Что сделать руками
Заголовок раздела «Что сделать руками»Упражнения из описания видео (копия с пояснениями на китайском — 003_makemore_MLP/MLP_exercises.ipynb в
репозитории karpathy-zero-to-hero-zh-transcripts):
- Подберите гиперпараметры так, чтобы побить лучший результат Карпатого на валидации.
- Инициализация в лекции небрежная. Какой loss был бы, если бы на старте все 27 вероятностей были одинаковыми? (Подсказка: .) Какой loss получается на самом деле? Подберите инициализацию так, чтобы стартовый loss был близок к идеальному. Это тема следующей лекции.
- Прочитайте статью Бенджио, реализуйте любую идею оттуда (например, прямые связи со входа на выход) и проверьте, помогла ли она.
И ещё несколько наших:
- Проверьте сами, что
C[5]иF.one_hot(torch.tensor(5), 27).float() @ Cсовпадают. - Найдите learning rate своим графиком для
block_size = 5. Сдвинулась ли «долина»? - Обучите модель на русских именах из урока 4.1.2 и сравните loss на валидации с английскими. Учтите, что данных в сто раз меньше.
Словарик
Заголовок раздела «Словарик»| EN | RU |
|---|---|
| multilayer perceptron (MLP) | многослойный перцептрон |
context length, block_size | длина контекста |
| embedding, lookup table | эмбеддинг, таблица поиска (таблица эмбеддингов) |
| feature vector | вектор признаков |
| hidden layer, hyperparameter | скрытый слой, гиперпараметр |
| storage, view, stride | хранилище, представление (view), шаг |
| concatenate | склеить (конкатенировать) |
| fused kernel | объединённое ядро |
| numerical stability, overflow | численная устойчивость, переполнение |
| overfitting one batch | переобучение одного батча |
| minibatch | мини-батч |
| learning rate decay | затухание learning rate |
| train / dev (validation) / test split | обучающая / валидационная / тестовая выборка |
| overfitting / underfitting | переобучение / недообучение |
| log loss plot, “hockey stick” | график логарифма loss, «хоккейная клюшка» |