$ cat toc.txt

В серии про основы машинного обучения мы уже разбирали, как алгоритмы подбирают функцию под данные. Но там нейросети оставались чёрным ящиком: «берём много слоёв — работает лучше». Эта серия — про то, что у них внутри. Мы пройдём путь от одного нейрона до обратного распространения ошибки — алгоритма, благодаря которому современные LLM вообще умеют обучаться.

1. Проблема: то, что мозг делает мгновенно, коду не объяснить

Начнём с задачи, которая кажется детской: распознать рукописную цифру. Вы мгновенно понимаете, что вот эта кривоватая закорючка — «3», даже если никогда не видели именно этот почерк. При этом формально описать, как вы это сделали, почти невозможно. Попробуйте написать if-условие для «тройки»: если пиксели образуют два полукруга, соединённые слева… А если полукруги недописаны? Если палочка лишняя? Если это «8», у которой отвалилась середина?

Это типичный случай, где программирование через явные правила проигрывает: человек не знает, как он распознаёт цифры, — он просто умеет. Значит, правила нужно не придумывать, а выучивать из примеров. Для этого и нужны нейросети. Классический полигон для этой задачи — датасет MNIST: десятки тысяч размеченных картинок 28×28 пикселей с рукописными цифрами от 0 до 9. Своего рода «hello, world» глубокого обучения.

2. Нейрон — это просто число

Первое разочарование для тех, кто ждал биологии: нейрон в нейросети — это просто число от 0 до 1. Оно называется активацией. Активация 0.0 — нейрон «молчит», 1.0 — «горит».

Входной слой сети для MNIST — это 784 нейрона: по одному на каждый пиксель картинки 28×28. Активация каждого нейрона — яркость пикселя: 0.0 для белого, 1.0 для чёрного, что-то промежуточное для оттенков серого. Представьте картинку как столбик из 784 чисел — вот и всё, что сеть получает на вход.

Никакой магии на входе нет: мы просто вываливаем сетку пикселей в слой чисел.

3. Слои: 784 → 16 → 16 → 10

Между входом и выходом устраивают один или несколько скрытых слоёв. В нашем примере — два слоя по 16 нейронов. Почему именно два и почему по 16? Честный ответ: выбор произвольный, и архитектура — это именно то, что инженер подбирает под задачу. 16 — просто удобное для примера число.

Выходной слой — 10 нейронов, по одному на каждую цифру. Активация выходного нейрона — это уверенность сети: «думаю, это 7». Ответ сети — цифра, чей нейрон горит сильнее всех.

Вся конструкция:

784 (пиксели)  →  16  →  16  →  10 (цифры)
     вход          скрытые слои     выход

4. Зачем нужны слои: надежда про петли и линии

Почему мы вообще надеемся, что слои что-то дадут? Идея-интуиция такая: любую цифру можно собрать из кусочков. Девятка — это петля сверху и вертикальная линия снизу. Восьмёрка — две петли. У каждой петли есть край, у края — маленькие штрихи.

Хотелось бы верить, что сеть научится такому разложению сама:

  • один слой нейронов распознаёт крайние штрихи — короткие линии и дуги;
  • следующий слой собирает из них петли и длинные линии;
  • выходной слой собирает из петель и линий цифры.

Обратите внимание: когда сеть обучается, никто не прописывает это разложение вручную. Это надежда: может быть, слои сами придут к чему-то столь структурированному. Что они реально выучивают — интересный вопрос, и мы вернёмся к нему в третьей статье серии. (Спойлер из статьи про CNN: в свёрточных сетях иерархия «края → текстуры → части → объекты» наблюдается реально и наглядно.)

5. Веса: чего «хочет» нейрон

Как активация нейрона вычисляется из предыдущего слоя? Каждый нейрон смотрит на все 784 числа входа (или все 16 предыдущего слоя) и берёт взвешенную сумму. Каждая связь имеет свой вес — число, которое говорит: «этот пиксель для меня важен положительно», «этот — важен отрицательно», «а этот не важен вовсе».

Представьте веса нейрона как вторую сетку 28×28 — зелёно-красную карту: зелёные клетки прибавляют, красные вычитают. Хотите нейрон, распознающий горизонтальный край? Дайте ему положительные веса на верхней строке и отрицательные — на нижней. Тогда сумма будет большой только там, где сверху тёмное, а снизу светлое — то есть на краю.

Вес — это и есть «знание» сети. 13 002 таких чисел (мы их посчитаем через секунду) — всё, что сеть «умеет».

6. Смещение и сигмоида: порог и «сплющивание»

Взвешенная сумма — число, например 3.2 или −10. Но активация по нашему определению должна жить в диапазоне от 0 до 1. Нужны ещё два ингредиента.

Смещение (bias) — число, которое вычитается из суммы перед активацией: сумма − 10. Это порог чувствительности: нейрон с большим отрицательным смещением сработает только при очень сильном совпадении с шаблоном. Так настраивается «сколько доказательств надо, чтобы поверить».

Функция активации «сплющивает» результат в диапазон (0, 1). Классика жанра — сигмоида:

$$ \sigma(x) = \frac{1}{1 + e^{-x}} $$

Это S-образная кривая: сильно отрицательные числа — почти 0, сильно положительные — почти 1, вокруг нуля — плавный переход. (В современных сетях чаще используют ReLU — max(0, x) — она проще и лучше ведёт себя при обучении глубоких сетей. Мы обсуждали это в контексте CNN.) Итак:

активация = σ( (взвешенная сумма входов) + смещение )

7. 13 002 ручки и одна формула

Посчитаем параметры нашей игрушечной сети:

  • связи 784 → 16: 784 × 16 весов + 16 смещений = 12 560
  • связи 16 → 16: 16 × 16 весов + 16 смещений = 272
  • связи 16 → 10: 16 × 10 весов + 10 смещений = 170

Итого 13 002 обучаемых параметра. Для сравнения: у GPT-класса моделей таких «ручек» миллиарды. Но механика — ровно та же.

Переход между слоями записывается одной строчкой на языке линейной алгебры:

$$ a^{(1)} = \sigma\left(W a^{(0)} + b\right) $$

где $a^{(0)}$ — вектор активаций предыдущего слоя, $W$ — матрица весов, $b$ — вектор смещений. Никакой новой математики: умножение матрицы на вектор, прибавление числа, поэлементное применение сигмоиды. Вся сеть — эта формула, применённая трижды подряд.

8. Вся сеть — это просто функция

Соберём картину целиком. Нейросеть — это функция, которая принимает 784 числа и выдаёт 10 чисел:

784 числа (пиксели)  →  [ σ(W₁x + b₁) → σ(W₂· + b₂) → σ(W₃· + b₃) ]  →  10 чисел (уверенности)

Звучит почти обидно просто после всех разговоров про «искусственный интеллект». Но в этой простоте — вся суть: у нас есть функция с 13 002 параметрами, форма которой (слои, связи, сигмоиды) удобна для распознавания паттернов. Остался один вопрос — главный: как подобрать эти 13 002 числа? Человек не сможет прокрутить каждую ручку вручную даже в этой игрушечной сети, не говоря о миллиардах параметров в LLM.

Ответ на этот вопрос — обучение — и есть тема следующей статьи: градиентный спуск, то есть как сеть, отталкиваясь от случайных весов, сама находит числа, при которых работает.

9. Почему это важно знать инженеру

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

Понимание LLM. GPT, Claude, Llama — это та же самая конструкция, только вместо сигмоиды и 13 002 параметров там Transformer-блоки и миллиарды весов. Вход — не пиксели, а токены, выход — вероятности следующего токена. Когда вы читаете про fine-tuning или квантование, речь всегда идёт об этих самых весах.

Размер модели = число параметров. Когда выбираете модель для Ollama («а возьму-ка я 7B вместо 70B»), вы выбираете, сколько таких чисел придется хранить и перемножать. 7B параметров в 4-битном квантовании ≈ 4–5 ГБ — арифметика прямиком из этой статьи.

Никакой магии. Нейросеть — детерминированная математическая функция. Это помогает и при отладке, и при оценке громких заявлений: «модель поняла» пока означает «функция выдала числа, похожие на осмысленные».

Заключение

Мы разобрали скелет: нейрон — число, слой — вектор чисел, связь — вес, сеть — функция $\sigma(Wx + b)$, применённая несколько раз. Ничего мистического, но уже видна и сила подхода: гибкая функция с тысячами настраиваемых параметров, способная выразить очень сложные зависимости.

Всё обучение нейросетей — это ответ на вопрос «как найти правильные значения 13 002 чисел?». Этим мы займёмся в следующей статье: как нейросети учатся — градиентный спуск и цена ошибки.

← все посты [поделиться] [rss]