Тутор для новичка
Если вы никогда не обучали нейросеть — эта страница для вас. Никакой математики с порога. Только объяснения, что происходит на экране и почему.
Что делает нейросеть #
Нейросеть — это функция с очень многими параметрами (весами). Она принимает на вход числа и выдаёт числа на выходе. Обучение — это поиск таких весов, при которых выход совпадает с правильным ответом.
Представьте, что у вас есть таблица: 3000 точек с координатами (x, y) и подписью «класс 0», «класс 1» или «класс 2». Нейросеть смотрит на пары (x, y) и учится угадывать класс. Сначала она угадывает случайно — треть точек правильно (3 класса). Потом, постепенно меняя веса, начинает угадывать всё лучше. К концу обучения — больше 90%.
Задача: Spirals #
Пресет spirals — классическая задача проверки нейросетей. Три спирали, перемотанные вокруг центра, одна поверх другой. Линейная модель (прямая линия) не может их разделить — нужна нелинейная граница. Именно поэтому задача интересная: она требует, чтобы сеть научилась «изгибать» пространство.
Данные: 3000 точек, 2 признака (x, y), 3 класса. На входе сеть получает координаты точки — на выходе даёт три числа: «вероятность класса 0», «вероятность класса 1», «вероятность класса 2». Правильный ответ — тот класс, у которого вероятность максимальная.
Конфиг человеческим языком #
Вот конфиг пресета spirals — разберём каждый блок:
{
"project": "spiral-classifier", // имя — для ваших записей
"task": "supervised", // тип задачи: supervised или rl
"model": {
"input_dim": 2, // 2 числа на вход: x и y координата
"output_dim": 3, // 3 числа на выход: вероятность каждого класса
"layers": [
{ "type": "linear", "units": 64 }, // скрытый слой
{ "type": "relu" }, // нелинейность
{ "type": "linear", "units": 64 }, // ещё один
{ "type": "relu" }
]
},
"data": {
"source": "builtin:spirals",
"n_samples": 3000, // сколько точек генерировать
"val_split": 0.2, // 20% — валидационная выборка
"batch_size": 64 // обрабатывать по 64 точки за раз
},
"train": {
"epochs": 40, // сколько раз прочитать все данные
"loss": "cross_entropy",
"optimizer": {
"name": "adamw",
"lr": 0.003 // скорость обучения
}
}
}
Эпоха — что это #
Эпоха = один полный проход по всем обучающим данным.
Представьте, что вы учитесь читать по учебнику. Один раз прочитали учебник — это одна эпоха. Прочитали снова — вторая эпоха. С каждым прочтением понимаете лучше.
В Кузне: при 3000 точках и batch_size=64, за одну эпоху сеть делает
примерно 3000 × 0.8 / 64 = 37 шагов обновления весов.
За 40 эпох — около 1 500 шагов.
Learning rate — скорость обучения #
Learning rate (lr) — это насколько сильно сеть меняет веса за один шаг.
Представьте, что вы ищете самую низкую точку в тёмной долине наощупь, маленькими шагами.
Шаги слишком большие — перепрыгиваете через минимум. Лосс скачет или вовсе растёт. Обучение не сходится.
Лосс плавно снижается, без скачков. Сеть уверенно идёт к минимуму.
Лосс снижается, но очень медленно. За 40 эпох сеть почти не выучит ничего — нужно в 10 раз больше эпох.
Для большинства задач 0.001–0.003 с оптимизатором AdamW — хорошая отправная точка. Именно такой используется в пресете spirals.
cosine: LR начинает с 0.003 и плавно падает к нулю к концу.
Это позволяет быстро выучить грубую структуру, а к концу «дошлифовать» точно.
Batch size — размер батча #
Сеть не смотрит на все 2400 обучающих точек сразу (это дорого по памяти).
Она берёт случайную подборку из batch_size штук, делает шаг обновления,
берёт следующую подборку — и так пока не пройдёт все данные.
Маленький батч (8–16): обновлений много, но шумные. Большой батч (256+): обновлений меньше, они точные, но нужно больше памяти. Батч 64 — хорошее значение для большинства задач на CPU.
Валидационная выборка — зачем #
val_split: 0.2 означает: откладываем 20% данных в сторону и
не даём сети их видеть при обучении.
После каждой эпохи проверяем точность на этих «спрятанных» данных.
Зачем? Чтобы знать, умеет ли сеть обобщать. Сеть легко может «заучить» тренировочные данные наизусть — но это бесполезно, если в реальности ей встретятся новые точки. Валидационная выборка имитирует «новые данные».
Хороший признак: train loss и val loss снижаются примерно одинаково.
Плохой признак: train падает, а val остаётся на месте или растёт.
Это переобучение.
Кривая потерь — как читать #
На экране Кузни — два графика: оранжевый — train loss (потери на обучающих данных), зелёный/голубой — val loss (потери на валидации).
Что хорошо выглядит:
- Обе кривые снижаются со временем.
- Val loss немного выше train loss — это нормально.
- К концу кривые выравниваются (сеть достигла предела).
Что плохо выглядит:
- Лосс вообще не снижается — слишком маленький LR или неправильная архитектура.
- Лосс скачет хаотично — слишком большой LR.
- Val loss начинает расти, пока train падает — переобучение.
- Лосс стал
NaN— взрыв градиентов (снизьте LR или включите grad_clip).
Переобучение — что делать #
Переобучение (overfitting) — сеть выучила тренировочные данные «наизусть», но потеряла способность обобщать. На графике это выглядит так: train loss падает, а val loss в какой-то момент останавливается или растёт.
Что делать при переобучении
Варианты от простого к сложному:
- Включить early stopping (уже включён по умолчанию).
"early_stop": { "enabled": true, "patience": 10 }— остановит обучение через 10 эпох без улучшения val loss. - Добавить Dropout — слой, который случайно «выключает» часть нейронов при обучении:
{ "type": "linear", "units": 64 }, { "type": "relu" }, { "type": "dropout", "p": 0.2 }, // выключает 20% нейронов - Добавить weight decay — L2-регуляризация в оптимизаторе:
"weight_decay": 0.01 - Уменьшить сеть — меньше нейронов в слоях, меньше слоёв.
- Добавить данных — больший датасет снижает переобучение.
Карта решений — как читать #
Карта решений показывает, как нейросеть делит плоскость по классам. Кузня строит её для задач с 2D-входом (например, spirals).
- Цвет области — предсказанный класс для каждой точки плоскости.
- Насыщенность цвета — уверенность сети. Яркий = уверен, бледный = сомневается.
- Граница между цветами — линия решения. Идеально: она должна совпасть со спиралями.
- Точки на карте — настоящие данные. Совпадают ли цвет точки с цветом фона — правильный ответ?
Ползунок эпох позволяет смотреть на любую промежуточную карту. В эпоху 1 — каша. К эпохе 40 — чёткие спиральные области.
Полоса градиентов #
Полоса grad/weight показывает «здоровье» обучения по слоям. Каждый столбик — один слой, высота — отношение градиента к весу.
- Все столбики низкие и равномерные — хорошо. Обучение идёт ровно.
- Столбики первых слоёв почти нулевые — затухание градиентов (vanishing). Сеть глубокая, первые слои не учатся. Попробуйте LayerNorm или другую активацию.
- Один столбик резко выбивается вверх — взрыв градиентов (exploding). Уменьшите LR или проверьте grad_clip.
Обучение на своём CSV #
Когда spirals освоена, следующий шаг — загрузить свои данные. Кузня читает CSV автоматически: распознаёт заголовок и разделитель.
Формат файла
Требования к CSV:
- Последняя колонка — метка (класс или целевое значение для регрессии).
- Остальные колонки — признаки (числа).
- Заголовок опционален — Кузня определит автоматически.
Пример файла iris.csv:
sepal_len,sepal_wid,petal_len,petal_wid,species
5.1,3.5,1.4,0.2,0
4.9,3.0,1.4,0.2,0
6.3,3.3,6.0,2.5,2
...
Конфиг для CSV
{
"project": "iris-classifier",
"task": "supervised",
"model": {
"input_dim": 4, // число признаков (колонок минус метка)
"output_dim": 3, // число классов
"layers": [
{ "type": "linear", "units": 32 },
{ "type": "relu" },
{ "type": "linear", "units": 32 },
{ "type": "relu" }
]
},
"data": {
"source": "data/iris.csv", // путь к вашему файлу
"val_split": 0.2,
"batch_size": 32,
"normalize": true // всегда включайте для числовых признаков
},
"train": {
"epochs": 60,
"loss": "cross_entropy",
"optimizer": { "name": "adamw", "lr": 0.001 },
"early_stop": { "enabled": true, "patience": 15 }
}
}
input_dim
под реальное число признаков в файле — так что можно не считать вручную.
Просто укажите примерное значение, в логе появится предупреждение с правильным числом.
Регрессия (числовой выход)
Если метка — не класс, а число (например, цена квартиры), поменяйте:
"model": {
"output_dim": 1 // один выход
},
"train": {
"loss": "mse" // MSE вместо cross_entropy
}
Проверить перед запуском
kuz check my.json
Команда проверяет конфиг и данные, не запуская обучение. Выведет: количество примеров в train/val, тип задачи, число параметров.