/
Текст
Введение: Почему эта книга для вас.
Вы когда-нибудь думали: «Нейросети — это круто, но я никогда не смогу их
программировать»?
Я вас понимаю. Когда я впервые увидел код нейросети, у меня было то же чувство.
Сотни строк, непонятные функции, магические числа... Казалось, что это доступно
только гениям с докторской степенью по математике.
Спойлер: это не так.
Нейросети — это просто. Да, вы не ослышались. За всей этой шумихой и сложными
терминами скрывается удивительно простая идея: возьми много чисел,
перемножь их, сложи, повтори много раз, и компьютер сам найдёт нужные
закономерности. Всё остальное — лишь детали.
Для кого эта книга
Эта книга написана для вас, если:
Вы никогда не писали код для нейросетей (или вообще не программировали)
Вы боитесь математики и думаете, что без неё нельзя
Вы уже пробовали, но сдались после первого же «CUDA out of memory»
Вы хотите понять, как работают ChatGPT, Midjourney и другие ИИ-чудеса, но не на
уровне «магия», а на уровне «я знаю, как это устроено»
Вы просто любопытны и готовы потратить пару вечеров на то, чтобы заставить
компьютер думать
Что вы узнаете и чему научитесь
Мы пройдём путь от полного нуля до создания вашей первой работающей
нейросети. Вот карта нашего путешествия:
text
┌─────────────────────────────────────────────────────────────────┐
│
ВАШ ПУТЬ ЗА 7 ГЛАВ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Глава 1: Что такое нейросеть на самом деле
│
│
(без формул, только на пальцах)
│
│
│
│
│
▼
│
│
Глава 2: Установка — вы сделаете это за 10 минут
│
│
(Python + PyTorch, даже если вы никогда не устанавливали)
│
│
│
│
│
▼
│
│
Глава 3: Ваша первая программа на PyTorch
│
│
(тензоры — это просто таблицы с числами)
│
│
│
│
│
▼
│
│
Глава 4: Как нейросеть учится — без страшной математики
│
│
(градиентный спуск на пальцах)
│
│
│
│
│
▼
│
│
Глава 5: Ваша первая нейросеть — распознаём рукописные цифры
│
│
(MNIST — "Hello, World!" нейросетей)
│
│
│
│
│
▼
│
│
Глава 6: Немного магии — как улучшить модель
│
│
(добавляем слои, меняем активации, смотрим на результат)
│
│
│
│
│
▼
│
│
Глава 7: Ваш первый проект — нейросеть, которая видит
│
│
(классифицируем картинки кошек и собак)
│
│
│
└─────────────────────────────────────────────────────────────────┘
Почему мы используем PyTorch, а не что-то другое
Есть много фреймворков для нейросетей. TensorFlow, Keras, JAX... Мы
выбрали PyTorch по трём причинам:
1. Он похож на обычный Python — нет странного синтаксиса, всё выглядит как
обычный код
2. Он самый популярный — все современные модели (ChatGPT, Stable Diffusion)
используют PyTorch
3. Он понятный — вы видите, что происходит, а не просто вызываете магические
функции
Что нужно для старта
Минимальные требования:
Компьютер (подойдёт даже старый ноутбук)
Желание учиться
2-3 свободных вечера
Не нужно:
Знать высшую математику
Иметь мощную видеокарту
Понимать, что такое «gradient descent»
Иметь опыт программирования
Базовое знакомство с Python (знаете, что такое переменная, цикл, функция) — это
плюс. Но даже если нет — мы начнём с самых азов в главе 2.
Как читать эту книгу
1. Читайте по порядку — главы построены так, чтобы каждая опиралась на
предыдущую
2. Пишите код руками — не копируйте, печатайте сами. Руки запоминают быстрее
головы
3. Не бойтесь ошибок — красные сообщения в консоли — это не провал, а обратная
связь
4. Экспериментируйте — меняйте числа, добавляйте слои, смотрите, что будет
Обещание
После прочтения этой книги вы:
Напишете свою первую нейросеть, которая распознаёт цифры
Поймёте, как нейросети «видят» и «учатся»
Сможете читать код нейросетей и понимать, что там происходит
Будете готовы к более серьёзным проектам
Перестанете бояться ИИ и начнёте его создавать
Как читать схемы в этой книге.
Введение: Зачем нужны схемы.
В этой книге мы используем особый язык визуализации — схемы, которые
помогают увидеть то, что невозможно показать словами. Нейросети — это
сложные системы с множеством связей, и схемы позволяют "заглянуть" внутрь них,
увидеть структуру и поток данных.
text
┌─────────────────────────────────────────────────────────────────┐
│
ПОЧЕМУ СХЕМЫ ВАЖНЫ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Слова описывают:
Схемы показывают:
│
┌───────────────┐
┌─────────────────────────────────────┐
│
│ "Нейросеть
│
│
ВХОД → СЛОЙ 1 → СЛОЙ 2 → ВЫХОД
│
│ состоит из
│
│
┌───┐
┌───┐
│
│
│
│ слоёв, данные │
│
│ ● │ → │ ● │ → │ ● │ → │ ● │
│
│
│
│ проходят
│
│
└───┘
│
│
│
│ через них"
│
└─────────────────────────────────────┘
│
└───────────────┘
┌───┐
└───┘
│
┌───┐
└───┘
└───┘
│
│
│
│
│
│
│
│
Схема = 1000 слов.
│
│
│
└─────────────────────────────────────────────────────────────────┘
1. Основные элементы схем
Все схемы в книге строятся из небольшого набора базовых элементов. Научившись
читать их, вы сможете понимать любую схему.
text
┌─────────────────────────────────────────────────────────────────┐
│
БАЗОВЫЕ ЭЛЕМЕНТЫ СХЕМ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
🔲 ПРЯМОУГОЛЬНИК — блок, операция, слой
│
│
┌─────────────────────────────────────────────────┐
│
│
│
│
│
└─────────────────────────────────────────────────┘
│
│
│
│
Означает: конкретное действие или преобразование
│
│
│
└─────────────────────────────────────────────────────────┘
Слой 1
│
│
│
│
│
│
│
│
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
═══ СТРЕЛКА — поток данных, переход, направление
│
│
│
│
ВХОД ────────────────────────────────→ ВЫХОД
│
│
│
│
Означает: данные движутся в этом направлении
│
│
│
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
│
● ТОЧКА/УЗЕЛ — данные, значение, нейрон
│
│
│
│
│
│
│
●───●───●───●
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
Означает: отдельная сущность (число, пиксель, нейрон)│
│
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
├──┤ РАЗВЕТВЛЕНИЕ — несколько потоков
│
│
│
│
┌─→ Поток 1
│
│
Данные┤
│
│
└─→ Поток 2
│
│
│
│
Означает: данные разделяются на части
│
│
│
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
┬───┐ ОБЪЕДИНЕНИЕ — слияние потоков
│
│
│
│
│
│
│
├─→ Результат
│
│
└───┘
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
Означает: несколько потоков объединяются
│
│
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
2. Как читать схемы нейросетей
Схема 1: Простая нейросеть (MLP)
text
┌─────────────────────────────────────────────────────────────────┐
│
КАК ЧИТАТЬ СХЕМУ ПРОСТОЙ НЕЙРОСЕТИ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
ВХОД
СКРЫТЫЙ СЛОЙ
ВЫХОД
│
784 числа
128 нейронов
10 чисел
│
│
│
│
│
┌────┐
│
┌────┐
┌────┐
│
│ 0.2│ ─────→ │ ×
│ ───────────→ │ 0.9│ ← вероятность 0
│
│
├────┤
│
├────┤
│
│
│ 0.7│ ─────→ │ ×
│ ───────────→ │ 0.1│ ← вероятность 1
│
│ ×
│
├────┤
│
│ ×
├────┤
│
│ 0.1│ ─────→ │ ×
│ ───────────→ │ 0.0│ ← вероятность 2
│
│
├────┤
│
│
│
│ ...│ ─────→ │ ×
│
└────┘
│ ×
│
├────┤
│ ───────────→ │ ...│
└────┘
│
└────┘
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
ЧТО ПОКАЗАНО:
│
│
• Стрелки → данные движутся слева направо
│
│
│
│
• 784 числа (пиксели) попадают в скрытый слой
│
│
│
│
• Скрытый слой обрабатывает их → 128 чисел
│
│
│
│
• Выходной слой выдаёт 10 вероятностей (0-9)
│
│
│
│
• Самая большая вероятность → ответ нейросети
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Как читать: Читайте слева направо. Сначала входные данные, затем каждый слой
по порядку, затем выход. Стрелки показывают направление движения данных.
Схема 2: Сверточная нейросеть (CNN)
text
┌─────────────────────────────────────────────────────────────────┐
│
КАК ЧИТАТЬ СХЕМУ СВЕРТОЧНОЙ НЕЙРОСЕТИ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
ВХОД
СЛОИ
│
28×28×1
ВЫХОД
│
(изображение)
│
│
│
│
│
▼
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
Свёртка 1: 32 фильтра 3×3 → 28×28×32
│
│
│
│
ReLU (активация)
│
│
│
│
Пулинг (MaxPool): уменьшаем размер → 14×14×32
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
▼
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
Свёртка 2: 64 фильтра 3×3 → 14×14×64
│
│
│
│
ReLU
│
│
│
│
Пулинг: уменьшаем размер → 7×7×64
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
▼
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
Выпрямляем (Flatten): 7×7×64 → 3136 чисел
│
│
Полносвязный слой: 3136 → 128
│
│
ReLU
│
│
│
│
Полносвязный слой: 128 → 10 (цифры 0-9)
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
│
▼
│
│
ВЫХОД: вероятности для каждой цифры
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
ЧТО ПОКАЗАНО:
│
│
• Каждый блок: свёртка + активация + пулинг
│
│
│
│
• Размеры картинки уменьшаются (28→14→7)
│
│
│
│
• Число каналов растёт (1→32→64)
│
│
• После свёрток — полносвязные слои
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Как читать: Следуйте вертикальному потоку. Каждый блок — это слой. Размеры
показывают, как меняется картинка на каждом этапе.
Схема 3: Процесс обучения
text
┌─────────────────────────────────────────────────────────────────┐
│
КАК ЧИТАТЬ СХЕМУ ОБУЧЕНИЯ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
1. Случайно задаём веса → Ответ → Ошибка (огромная!)
│
↓
│
│
│
2. Смотрим, как изменится ошибка, если чуть-чуть
│
│
изменить каждый вес → Вычисляем «градиент»
│
│
│
↓
3. Меняем веса в сторону уменьшения ошибки → Ответ лучше
│
│
│
│
↓
│
4. Повторяем шаги 1-3 тысячу раз → Ошибка минимальна!
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
ЧТО ПОКАЗАНО:
│
│
│
│
│
• Круговая стрелка → цикл повторяется
│
│
│
│
• Каждый шаг → одна итерация обучения
│
│
│
│
• Стрелки вниз → последовательность действий
│
│
│
│
• Результат → ошибка уменьшается
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
└─────────────────────────────────────────────────────────────────┘
Как читать: Читайте сверху вниз, как инструкцию. Каждый шаг — это действие.
Повторяйте цикл много раз.
3. Как читать схемы данных
Схема 4: Что такое тензор
text
┌─────────────────────────────────────────────────────────────────┐
│
КАК ЧИТАТЬ СХЕМУ ТЕНЗОРА
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
0D: Скаляр (одно число)
42
│
│
│
│
1D: Вектор (список)
[1, 2, 3]
│
│
│
│
2D: Матрица (таблица)
[[1,2], [3,4]]
│
│
│
│
3D: Трёхмерный массив (куб)
[[[1,2], [3,4]], │
│
│
│
[[5,6], [7,8]]]
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
4D: Батч картинок (вот это уже круто!)
│
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
ЧТО ПОКАЗАНО:
│
│
• Каждая строка → новый уровень размерности
│
│
• Слева → размерность (0D, 1D, 2D...)
│
│
│
│
• Справа → пример данных и название
│
│
│
│
• Чем больше D → тем более сложные данные
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Как читать: Сверху вниз, от простого к сложному. Каждый уровень добавляет
новое измерение.
Схема 5: Размеры картинок в CNN
text
┌─────────────────────────────────────────────────────────────────┐
│
КАК ЧИТАТЬ РАЗМЕРЫ В CNN
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Размеры показываются как: [БАТЧ, КАНАЛЫ, ВЫСОТА, ШИРИНА]
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
Начало:
[1, 3, 224, 224]
│
← 1 картинка, 3 канала, │
высота 224, ширина 224
│
│
│
│
После свёртки: [1, 64, 224, 224]
← 64 канала
│
│
│
│
После пулинга: [1, 64, 112, 112]
← размер уменьшен
│
│
│
│
После flatten: [1, 64*112*112]
← один большой вектор│
│
│
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
ЧТО ПОКАЗАНО:
│
│
• Первое число → батч (сколько картинок)
│
│
• Второе число → каналы (RGB = 3)
│
│
• Третье и четвёртое → размер картинки
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Как читать: Четыре числа всегда означают [батч, каналы, высота, ширина].
Следите, как они меняются на каждом слое.
4. Как читать схемы кода
Схема 6: Цикл обучения (поток данных)
text
┌─────────────────────────────────────────────────────────────────┐
│
КАК ЧИТАТЬ СХЕМУ ЦИКЛА ОБУЧЕНИЯ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
1. optimizer.zero_grad()
│
│
┌─────────────────────────────────────────────────────┐
│
│
│
"Подготовься! Сейчас будем учиться."
│
│
│
│
Обнуляем старые градиенты, чтобы не смешать их.
│
│
│
└─────────────────────────────────────────────────────┘
│
│
│
│
│
▼
│
│
2. output = model(images)
│
│
┌─────────────────────────────────────────────────────┐
│
│
│
"Посмотри на эту картинку, что ты видишь?"
│
│
│
│
Прямой проход — нейросеть выдаёт предсказание.
│
│
│
└─────────────────────────────────────────────────────┘
│
│
│
│
│
▼
│
│
3. loss = criterion(output, labels)
│
│
┌─────────────────────────────────────────────────────┐
│
│
│
"Сравни ответ с правильным. Какая ошибка?"
│
│
│
│
Вычисляем, насколько мы ошиблись.
│
│
│
└─────────────────────────────────────────────────────┘
│
│
│
│
│
▼
│
│
4. loss.backward()
│
│
┌─────────────────────────────────────────────────────┐
│
│
│
"Понял! Сейчас пойму, как исправить ошибку."
│
│
│
│
Вычисляем градиенты (куда крутить веса).
│
│
│
└─────────────────────────────────────────────────────┘
│
│
│
│
│
▼
│
│
5. optimizer.step()
│
│
┌─────────────────────────────────────────────────────┐
│
│
│
"Исправляю!"
│
│
│
Крутим все веса в правильную сторону.
│
└─────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
ЧТО ПОКАЗАНО:
│
│
• Каждый шаг — строка кода
│
│
• Стрелки → последовательность выполнения
│
│
• Текст в кавычках — что делает эта строка
│
│
│
│
• Всё вместе — цикл обучения
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Как читать: Сверху вниз, как выполняются строки кода. Каждая строка — один шаг
в обучении. Повторяется много раз.
5. Как читать схемы сравнения
Схема 7: MLP vs CNN
text
┌─────────────────────────────────────────────────────────────────┐
│
КАК ЧИТАТЬ СХЕМУ СРАВНЕНИЯ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
├─────────────────────────────────────────────────────────┤
│
│
│
│
│
│
Картинка → Распрямить → Слои → Ответ
│
│
[784 чисел]
│
│
│
│
Картинка → Свёртка → Пулинг → Слои → Ответ
│
│
[28x28]
│
└─────────────────────────────────────────────────────────┘
MLP (Полносвязная)
CNN (Сверточная)
│
│
│
│
[128]
│
[10]
│
│
│
│
[28x28]
[14x14]
[128]
[10]
│
│
│
│
│
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
ЧТО ПОКАЗАНО:
│
│
• Две колонки → два подхода
│
│
│
│
• Стрелки → поток данных в каждом подходе
│
│
│
│
• Размеры → как меняются данные
│
│
│
│
• Легко увидеть разницу: MLP теряет структуру,
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
CNN сохраняет её
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Как читать: Сравнивайте колонки слева и справа. Видите, как по-разному
обрабатываются данные.
6. Как читать схемы архитектур
Схема 8: Структура книги
text
┌─────────────────────────────────────────────────────────────────┐
│
КАК ЧИТАТЬ СХЕМУ СТРУКТУРЫ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Глава 1: Что такое нейросеть на самом деле
│
│
(без формул, только на пальцах)
│
│
│
│
│
▼
│
│
Глава 2: Установка — вы сделаете это за 10 минут
│
│
(Python + PyTorch, даже если вы никогда не устанавливали)
│
│
│
│
│
▼
│
│
Глава 3: Ваша первая программа на PyTorch
│
│
(тензоры — это просто таблицы с числами)
│
│
│
│
│
▼
│
│
...и так далее...
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
ЧТО ПОКАЗАНО:
│
│
• Каждый блок → одна глава
│
│
│
│
• Стрелки вниз → последовательность чтения
│
│
│
│
• Текст в скобках → что вы узнаете
│
│
│
│
• Читайте сверху вниз, не пропуская блоки
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Как читать: Сверху вниз, как оглавление. Каждая глава — следующий шаг.
7. Быстрый справочник по чтению схем
text
┌─────────────────────────────────────────────────────────────────┐
│
БЫСТРЫЙ СПРАВОЧНИК
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
├─────────────────────────────────────────────────────────┤
│
│
🔲 Прямоугольник = блок, слой, операция
│
│
│
│
═══ Стрелка = поток данных, направление
│
│
ЧТО ОЗНАЧАЮТ ЭЛЕМЕНТЫ:
│
│
│
│
│
│
● Точка/узел = данные, нейрон, значение
│
│
│
│
├──┤ Разветвление = данные разделяются
│
│
│
│
┬───┐ Объединение = данные сливаются
│
│
│
│
▼ Вертикальная стрелка = читайте сверху вниз
│
│
│
│
→ Горизонтальная стрелка = читайте слева направо
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
├─────────────────────────────────────────────────────────┤
│
│
• Схема нейросети → слева направо (вход → выход)
│
│
│
│
• Схема обучения → сверху вниз (шаг за шагом)
│
│
│
│
• Схема данных → от простого к сложному
│
│
│
│
• Схема сравнения → сравнивайте колонки
│
│
│
│
• Схема структуры → сверху вниз (как оглавление)
│
└─────────────────────────────────────────────────────────┘
КАК ЧИТАТЬ РАЗНЫЕ СХЕМЫ:
│
│
│
│
│
│
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
├─────────────────────────────────────────────────────────┤
│
│
│
│
│
│
│
│
│
│
Всматривайтесь в схему, пока не увидите
│
│
│
│
то, что автор хотел показать.
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
│
ГЛАВНОЕ ПРАВИЛО:
│
│
│
│
СХЕМА ПОКАЗЫВАЕТ ТО, ЧТО НЕЛЬЗЯ СКАЗАТЬ СЛОВАМИ.
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
8. Практика: прочитайте эту схему
text
┌─────────────────────────────────────────────────────────────────┐
│
ПРАКТИЧЕСКОЕ ЗАДАНИЕ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Перед вами схема. Попробуйте ответить на вопросы:
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
│
│
│
ДАННЫЕ → ПРЕДОБРАБОТКА → МОДЕЛЬ → ОЦЕНКА
│
│
(сырые)
│
(нормализация)
(CNN)
(точность)
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
Вопрос 1: В каком направлении читать эту схему?
│
│
Ответ: ➜ Слева направо
│
│
│
│
Вопрос 2: Что делает "Предобработка"?
│
│
Ответ: Нормализует данные
│
│
│
│
Вопрос 3: Какая модель используется?
│
│
Ответ: CNN
│
│
│
│
Вопрос 4: Что мы получаем в конце?
│
│
Ответ: Точность (оценку качества)
│
│
│
└─────────────────────────────────────────────────────────────────┘
Заключение: Схемы — ваш друг
text
┌─────────────────────────────────────────────────────────────────┐
│
ПОЧЕМУ СХЕМЫ ВАЖНЫ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
1. Схемы показывают СТРУКТУРУ
│
│
│
Как устроена система, из каких частей она состоит │
│
│
2. Схемы показывают ПОТОК
Как данные движутся от входа к выходу
│
│
│
│
│
│
3. Схемы показывают СВЯЗИ
│
│
│
│
│
Как части системы влияют друг на друга
│
4. Схемы показывают ПОРЯДОК
Что за чем происходит, какая последовательность
│
│
│
│
│
│
5. Схемы ПОМОГАЮТ ЗАПОМНИТЬ
Визуальная память сильнее текстовой
│
│
│
│
│
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
│
│
✦
✦
✦
│
│
│
│
│
│
│
│
│
│
Не бойтесь схем. Они здесь, чтобы помочь вам.
│
│
Каждая схема в этой книге нарисована так, чтобы
│
│
│
│
вы могли увидеть то, что словами описать сложно.
│
│
│
│
│
│
Возвращайтесь к этому приложению, если что-то
│
│
│
│
в схеме непонятно.
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
│
✦
✦
✦
│
│
└─────────────────────────────────────────────────────────────────┘
Теперь вы умеете читать любую схему в этой книге!
Начнём?
Переверните страницу. Мы начнём с самого простого вопроса: «Что такое
нейросеть на самом деле?». Без формул. Без страшных слов. Просто и понятно.
Добро пожаловать в мир, где вы создаёте интеллект своими руками.
Глава 1. Что такое нейросеть на самом деле
1.1. Откровение: нейросеть — это просто «чёрный
ящик» с числами
Представьте, что вы — учитель. У вас есть ученик, который ничего не знает. Вы
даёте ему задачу: «Вот картинка. Скажи, это кот или собака?». Ученик сначала
отвечает наугад. Вы говорите: «Нет, это кот! Запомни». Ученик запоминает.
Потом вы даёте ему другую картинку. Он снова ошибается. Вы снова поправляете.
И так много-много раз. Через какое-то время ученик начинает угадывать. Он не
знает, почему это кот, он просто чувствует закономерность.
Нейросеть работает точно так же.
Это просто математическая «машина», у которой есть миллионы маленьких ручекрегуляторов (их называют веса). Когда мы «учим» нейросеть, мы просто крутим эти
ручки до тех пор, пока она не начнёт давать правильные ответы.
text
┌─────────────────────────────────────────────────────────────────┐
│
ЧТО ТАКОЕ НЕЙРОСЕТЬ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
ВХОД
│
(числа)
«ЧЁРНЫЙ ЯЩИК»
ВЫХОД
│
(миллионы чисел)
(ответ)
│
│
│
│
┌─────────┐
│
│ Пиксели │
│
│
┌─────────────────┐
────→
┌─────────┐ │
│
×
×
×
×
×
│
│ картинки│
│
×
×
×
×
×
│
│ 92%
└─────────┘
│
×
×
×
×
×
│
└─────────┘ │
│
────→
│
Кот
└─────────────────┘
│ │
│ │
│
│
│
│
Внутри чёрного ящика — просто сложение и умножение.
│
│
Никакой магии. Только числа, которые мы подгоняем
│
│
под правильный ответ.
│
│
│
└─────────────────────────────────────────────────────────────────┘
1.2. Аналогия: нейросеть = кулинарная книга
Представьте, что вы хотите научить компьютер готовить идеальный борщ. Вы даёте
ему рецепт, но не в словах, а в числах:
Свёкла: 0.3 (много)
Капуста: 0.2 (средне)
Мясо: 0.4 (много)
Соль: 0.05 (чуть-чуть)
Сахар: 0.01 (щёпотку)
Это веса. Компьютер берёт эти числа, умножает их на ингредиенты и получает
«вкус». Потом вы пробуете и говорите: «Слишком кисло, убавь свёклу, добавь
сахара». Компьютер меняет числа.
И так 1000 раз. Через тысячу попыток у него будет идеальный рецепт. Он не
знает, почему это идеально, он просто подобрал числа, которые работают.
Нейросеть делает то же самое, только с картинками, текстами и звуками.
1.3. Из чего состоит нейросеть: три простых блока
В любой нейросети есть три основных элемента. Даже в самых сложных, вроде
ChatGPT или Midjourney.
Блок 1: Вход (Input)
Это просто числа. Если это картинка — каждый пиксель становится числом (от 0 до
1). Если это текст — каждое слово становится числом. Если это звук — каждая
миллисекунда становится числом.
Всё, что видит нейросеть, — это просто список чисел.
Блок 2: Скрытые слои (Hidden Layers)
Это сердце нейросети. Здесь числа перемножаются, складываются и
преобразуются. Представьте, что у вас есть несколько «этажей»-обработчиков:
1.
2.
3.
4.
Первый этаж смотрит на отдельные пиксели
Второй этаж ищет линии и края
Третий этаж ищет формы (уши, глаза)
Четвёртый этаж решает: «Это похоже на кота!»
Каждый этаж — это просто умножение чисел на другие числа (веса).
Блок 3: Выход (Output)
Это ответ. Может быть одно число («вероятность, что это кот — 92%») или много
чисел (например, «это кот на 92%, собака на 5%, птица на 3%»).
text
┌─────────────────────────────────────────────────────────────────┐
│
СТРУКТУРА НЕЙРОСЕТИ (ОЧЕНЬ ПРОСТО)
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
ВХОД →
│
(числа)
СЛОЙ 1
→
(числа)
СЛОЙ 2
→
(числа)
СЛОЙ 3
→
(числа)
ВЫХОД
│
(ответ)
│
│
│
│
┌────┐
┌────┐
│
│ 0.2│ ──→│ ×
│
├────┤
│
│ 0.7│ ──→│ ×
│
├────┤
┌────┐
│ ──→ │ ×
│ 0.5│
│ 0.1│
│ ──→ │ ×
│ 0.3│
│ ──→ │ ×
┌────┐
│ 0.8│
│ ──→ │ ×
│ 0.9│
│ ──→
│ ──→
│ 0.2│
┌────┐
│
│Кот │
│
│92% │
│
└────┘
│
│
│
│ 0.1│ ──→│ ×
│
└────┘
│ ──→ │ ×
└────┘
│ ──→ │ ×
└────┘
│
│
└────┘
│
│
│
│
ВСЁ! Просто берём числа, умножаем, складываем, повторяем.
│
│
│
└─────────────────────────────────────────────────────────────────┘
1.4. Как нейросеть учится (самая важная идея)
Запомните это раз и навсегда:
Обучение нейросети — это подгонка чисел (весов) так, чтобы ошибка стала
минимальной.
Процесс выглядит так:
text
┌─────────────────────────────────────────────────────────────────┐
│
КАК РАБОТАЕТ ОБУЧЕНИЕ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
1. Случайно задаём веса → Ответ → Ошибка (огромная!)
│
↓
│
│
│
2. Смотрим, как изменится ошибка, если чуть-чуть
│
│
изменить каждый вес → Вычисляем «градиент»
│
│
│
│
│
↓
3. Меняем веса в сторону уменьшения ошибки → Ответ лучше
│
│
↓
4. Повторяем шаги 1-3 тысячу раз → Ошибка минимальна!
│
│
│
│
│
Это называется ГРАДИЕНТНЫЙ СПУСК.
│
│
Это сложное слово, но идея простая:
│
│
«Делай шаг в ту сторону, где ошибка меньше».
│
│
│
└─────────────────────────────────────────────────────────────────┘
Вывод: нейросеть учится не потому, что она умная. Она учится, потому что мы
тысячу раз подряд подгоняем числа, пока они не начнут работать.
1.5. Почему не нужна высшая математика
Да, в статьях про нейросети полно формул. Но для того, чтобы написать свою
первую нейросеть, вам не нужно их понимать.
Вот что вам нужно знать на самом деле:
Умножение — в школе учили
Сложение — в школе учили
Возведение в квадрат — в школе учили
Умение читать код — научимся на следующей странице
Вот и всё. Вся «сложная математика» спрятана внутри PyTorch. Вы просто говорите:
«Пожалуйста, посчитай градиенты» — и он считает. Вы говорите: «Пожалуйста,
обнови веса» — и он обновляет. Вы — как водитель: вы не знаете, как устроен
двигатель, но вы умеете нажимать на педали.
1.6. Главное, что нужно запомнить из этой главы
1.
2.
3.
4.
Нейросеть — это просто числа, которые мы подгоняем под правильные ответы
Внутри нейросети — только умножение и сложение (никакой магии)
Обучение = многократная подгонка чисел для уменьшения ошибки
PyTorch делает всю сложную работу за вас — вы просто пишете, ЧТО делать
Проверьте себя
Вопрос 1: Что такое «вес» нейросети?
Ответ: это число, которое мы подгоняем во время обучения.
Вопрос 2: Что такое «обучение» нейросети?
Ответ: это процесс многократной подгонки весов, чтобы ошибка стала
минимальной.
Вопрос 3: Нужно ли знать высшую математику, чтобы написать нейросеть?
Ответ: нет. Нужно уметь умножать, складывать и читать простой код.
В следующей главе мы установим Python и PyTorch. Это займёт 10 минут. И вы
напишете свою первую программу для нейросетей. Даже если вы никогда не
устанавливали ничего сложнее игр.
Поехали!
Глава 2. Установка Python и PyTorch за 10 минут
2.1. Почему это будет легко
Вы наверняка слышали страшилки про установку Python: "нужно что-то там
настраивать", "библиотеки конфликтуют", "у меня ничего не работает". Забудьте.
Мы сделаем всё в три шага. Без командной строки (почти). Без страшных ошибок.
Просто скачаем, запустим, проверим.
text
┌─────────────────────────────────────────────────────────────────┐
│
УСТАНОВКА ЗА 3 ШАГА
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
┌─────────────┐
┌─────────────┐
┌─────────────┐
│
│
│
ШАГ 1
│ →
│
│
│
│
│
│
Скачать
│
│
Установить │
│
Проверить
│
│
│
│
Python
│
│
PyTorch
│
│
что всё
│
│
│
│
(3 минуты) │
│
(3 минуты) │
│
работает
│
│
│
└─────────────┘
└─────────────┘
│
(1 минута) │
│
ШАГ 2
│ →
│
ШАГ 3
└─────────────┘
│
│
│
│
Итого: 7 минут. И вы готовы писать код.
│
│
│
└─────────────────────────────────────────────────────────────────┘
2.2. Шаг 1: Установка Python (3 минуты)
Python — это язык, на котором мы будем говорить с компьютером. Он бесплатный
и простой.
Инструкция для Windows:
1. Зайдите на сайт: python.org
2. Наведите на "Downloads" → нажмите на большую жёлтую кнопку "Download
Python"
3. Запустите скачанный файл
4. ВАЖНО! Поставьте галочку "Add Python to PATH" (это очень важно!)
5. Нажмите "Install Now"
text
┌─────────────────────────────────────────────────────────────────┐
│
УСТАНОВКА PYTHON (WINDOWS)
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
Python 3.12 Setup
│
│
│
│
┌─────────────────────────────────────────────────┐
│
│
│
│
│ ☑ Install launcher for all users
│
│
│
│
│ ☑ **ADD PYTHON TO PATH**
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────┘
│
└─────────────────────────────────────────────────────────┘
[Install Now]
│
│
← ПОСТАВЬТЕ ЭТУ ГАЛКУ │
│
│
│
│
│
[Customize]
│
│
│
│
│
│
│
│
│
Если вы поставили эту галку, у вас всё работает.
│
│
│
└─────────────────────────────────────────────────────────────────┘
Инструкция для Mac:
1. Зайдите на сайт: python.org
2. Наведите на "Downloads" → нажмите на "Download for macOS"
3. Запустите скачанный .pkg файл
4. Пройдите установку (нажимайте "Продолжить" → "Установить")
Проверка (Windows):
Откройте Командную строку (нажмите Win+R, введите cmd и нажмите Enter) и
выполните:
text
python --version
Если вы видите что-то вроде Python 3.12.x — всё работает!
Проверка (Mac):
Откройте Терминал и выполните:
text
python3 --version
Если вы видите версию Python — отлично!
text
┌─────────────────────────────────────────────────────────────────┐
│
ПРОВЕРКА УСТАНОВКИ PYTHON
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
WINDOWS: cmd → python --version
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
C:\Users\Вася> python --version
│
│
│
│
Python 3.12.0
│
│
│
│
C:\Users\Вася> █
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
MAC: Терминал → python3 --version
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
~% python3 --version
│
│
│
│
Python 3.12.0
│
│
│
│
~% █
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
Если вы увидели версию — ПОЗДРАВЛЯЮ! Первый шаг сделан!
│
│
│
└─────────────────────────────────────────────────────────────────┘
2.3. Шаг 2: Установка PyTorch (3 минуты)
PyTorch — это библиотека, которая умеет делать всю сложную математику за вас.
Инструкция (для всех):
1. Зайдите на сайт: pytorch.org
2. Нажмите "Install" (в верхнем меню)
3. Выберите настройки:
text
┌─────────────────────────────────────────────────────────────────┐
│
ВЫБОР ПАРАМЕТРОВ НА PYTORCH.ORG
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
PyTorch Build: Stable (1.0)
← ВЫБЕРИТЕ ЭТО
│
│
│
│
│
Your OS: Windows / Mac / Linux ← ВАША ОС
│
│
│
│
Package: Pip
│
│
│
│
Language: Python
│
│
│
│
Compute Platform: CPU (если нет видеокарты NVIDIA)
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
│
CUDA (если есть NVIDIA)
│
│
│
ВНИМАНИЕ! Если вы не знаете, что у вас за видеокарта,
│
выберите CPU. Потом всегда можно переустановить.
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
4. Скопируйте команду, которая появится внизу. Например:
text
pip3 install torch torchvision torchaudio
5. Вставьте эту команду в Командную строку (Windows) или Терминал (Mac) и
нажмите Enter.
6. Подождите 2-3 минуты, пока скачивается и устанавливается.
text
┌─────────────────────────────────────────────────────────────────┐
│
ПРОЦЕСС УСТАНОВКИ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
C:\Users\Вася> pip3 install torch torchvision torchaudio
│
│
│
│
Downloading torch-2.0.0-cp312-cp312-win_amd64.whl
│
│
████████████████████████████████████████ 100%
│
│
Downloading torchvision-0.15.0...
│
████████████████████████████████████████ 100%
│
Downloading torchaudio-2.0.0...
│
████████████████████████████████████████ 100%
│
│
│
│
│
│
│
Successfully installed torch-2.0.0 torchvision-0.15.0...
│
│
│
│
C:\Users\Вася> █
│
│
│
└─────────────────────────────────────────────────────────────────┘
Готово! PyTorch установлен.
2.4. Шаг 3: Проверка (1 минута)
Теперь давайте убедимся, что всё работает.
Запустите Python
В командной строке (Windows) или терминале (Mac) напишите:
text
python
(или python3 на Mac)
Импортируйте PyTorch
В открывшейся консоли Python введите:
python
import torch
print(torch.__version__)
Если вы видите номер версии (например, 2.0.0) — всё работает!
text
┌─────────────────────────────────────────────────────────────────┐
│
ПРОВЕРКА УСТАНОВКИ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
C:\Users\Вася> python
│
│
Python 3.12.0 (default, ...)
│
│
Type "help", "copyright", "credits" or "license" for more
│
information.
│
>>> import torch
│
│
>>> print(torch.__version__)
│
│
2.0.0
│
│
>>> █
│
│
│
│
│
│
Если вы увидели версию — ВЫ МОЛОДЕЦ!
│
│
│
└─────────────────────────────────────────────────────────────────┘
Можете даже проверить, есть ли у вас видеокарта:
python
print(torch.cuda.is_available())
Если вы увидели True — у вас есть видеокарта NVIDIA, и PyTorch её видит.
Если False — ничего страшного, будем работать на процессоре.
2.5. Если что-то пошло не так
Проблема: "python не найден"
Решение: Вы забыли поставить галочку "Add Python to PATH". Переустановите
Python и поставьте эту галочку.
Проблема: "pip" не найден
Решение: Python установлен, но pip (инструмент для установки библиотек)
недоступен. Попробуйте:
text
python -m pip install torch torchvision torchaudio
Проблема: "загрузка идёт слишком долго"
Решение: Это нормально. PyTorch весит около 1 ГБ. Просто подождите.
Проблема: "ошибка доступа"
Решение: Запустите командную строку от имени администратора. Нажмите правой
кнопкой мыши на "Командная строка" и выберите "Запуск от имени
администратора".
2.6. Jupyter Notebook — ваш новый лучший друг
Мы будем писать код в Jupyter Notebook. Это удобная среда, где вы можете
видеть результат сразу после ввода кода.
Установка Jupyter:
text
pip install jupyter
Запуск:
text
jupyter notebook
После запуска откроется окно в браузере. Нажмите "New" → "Python 3" — и вы в
среде разработки!
text
┌─────────────────────────────────────────────────────────────────┐
│
JUPYTER NOTEBOOK В ДЕЙСТВИИ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
Untitled.ipynb
│
│
│
┌─────────────────────────────────────────────────┐
│
│
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────┘
│
│
│
│
│
│
Вы пишете код → нажимаете Shift+Enter → видите результат│
│
│
└─────────────────────────────────────────────────────────┘
│
In [1]: import torch
print("Hello, PyTorch!")
Hello, PyTorch!
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
ИДЕАЛЬНО ДЛЯ ОБУЧЕНИЯ! Видно сразу, что работает.
│
│
│
└─────────────────────────────────────────────────────────────────┘
2.7. Краткий итог
Мы сделали три простых шага:
text
┌─────────────────────────────────────────────────────────────────┐
│
ЧТО МЫ СДЕЛАЛИ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
✅ Установили Python (язык программирования)
│
│
✅ Установили PyTorch (библиотека для нейросетей)
│
│
✅ Установили Jupyter Notebook (среда разработки)
│
│
✅ Проверили, что всё работает
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
ВЫ ГОТОВЫ ПИСАТЬ НЕЙРОСЕТИ!
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Теперь у вас есть всё необходимое. В следующей главе мы напишем первую
программу на PyTorch — и это будет ваша первая нейросеть.
Задание на дом
1. Убедитесь, что Jupyter Notebook открывается. Запустите jupyter notebook и
создайте новый файл.
2. Напишите в Jupyter Notebook:
python
import torch
print("Мой первый тензор!", torch.tensor([1, 2, 3, 4, 5]))
3. Нажмите Shift+Enter. Если вы видите tensor([1, 2, 3, 4, 5]) — всё работает
идеально!
text
┌─────────────────────────────────────────────────────────────────┐
│
ВАШ ПЕРВЫЙ УСПЕХ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Если вы увидели это — вы сделали первый шаг в мире ИИ!
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
In [1]: import torch
print("Мой первый тензор!",
torch.tensor([1, 2, 3, 4, 5]))
Мой первый тензор! tensor([1, 2, 3, 4, 5])
│
│
│
│
│
│
│
│
│
│
│
│
│
В следующей главе вы узнаете, что такое тензор
│
и как с ним работать. СПОЙЛЕР: это просто список чисел!
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Готовы к следующей главе? Переворачивайте страницу!
Глава 3. Ваша первая программа на PyTorch
3.1. Что такое тензор (и почему это звучит страшнее, чем
есть на самом деле)
В прошлой главе вы уже видели слово "тензор":
python
torch.tensor([1, 2, 3, 4, 5])
Тензор — это просто список чисел. Как в школьной математике, только можно
хранить не один список, а таблицу, куб, или даже многомерный массив.
text
┌─────────────────────────────────────────────────────────────────┐
│
ЧТО ТАКОЕ ТЕНЗОР
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
0D: Скаляр (одно число)
42
│
│
│
│
1D: Вектор (список)
[1, 2, 3]
│
│
│
│
2D: Матрица (таблица)
[[1,2], [3,4]]
│
│
│
│
3D: Трёхмерный массив (куб)
[[[1,2], [3,4]], │
│
│
│
[[5,6], [7,8]]]
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────┘
4D: Батч картинок (вот это уже круто!)
│
│
│
│
│
ВСЁ! Тензор — это просто таблица с числами.
│
Не надо бояться этого слова.
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Зачем это всё? Картинка — это тензор 3D (ширина, высота, каналы RGB). Текст —
это тензор 2D (предложение, слова). Звук — это тензор 1D (волна). Всё, что мы
даём нейросети, — это тензоры.
3.2. Создаём свои первые тензоры
Откройте Jupyter Notebook и попробуйте сами:
Тензор из списка чисел
python
import torch
# Вектор (1D)
v = torch.tensor([1, 2, 3, 4, 5])
print("Вектор:", v)
print("Форма:", v.shape)
text
Вектор: tensor([1, 2, 3, 4, 5])
Форма: torch.Size([5])
Таблица чисел (матрица, 2D)
python
# Матрица (2D)
m = torch.tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print("Матрица:\n", m)
print("Форма:", m.shape)
text
Матрица:
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
Форма: torch.Size([3, 3])
Трёхмерный тензор (как маленькая картинка)
python
# Трёхмерный тензор (2 картинки, каждая 2x2 пикселя)
img = torch.tensor([[[1, 2], [3, 4]],
[[5, 6], [7, 8]]])
print("3D тензор:\n", img)
print("Форма:", img.shape)
text
3D тензор:
tensor([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
Форма: torch.Size([2, 2, 2])
3.3. Специальные тензоры — создаём быстро
Часто нам нужны не конкретные числа, а тензоры, заполненные нулями,
единицами или случайными числами.
python
# Тензор из нулей (3 строки, 4 столбца)
zeros = torch.zeros(3, 4)
print("Нули:\n", zeros)
# Тензор из единиц (2 строки, 5 столбцов)
ones = torch.ones(2, 5)
print("Единицы:\n", ones)
# Тензор со случайными числами (нормальное распределение)
random = torch.randn(3, 3)
print("Случайные:\n", random)
text
┌─────────────────────────────────────────────────────────────────┐
│
СПЕЦИАЛЬНЫЕ ТЕНЗОРЫ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
torch.zeros(3, 4) →
│
│
[[0., 0., 0., 0.],
│
│
[0., 0., 0., 0.],
│
│
[0., 0., 0., 0.]]
│
│
│
│
torch.ones(2, 5) →
│
│
[[1., 1., 1., 1., 1.],
│
│
[1., 1., 1., 1., 1.]]
│
│
│
│
torch.randn(3, 3) →
│
[[ 0.3, -0.2,
│
0.7],
│
1.2, -0.1],
│
│
[-0.5,
│
[ 0.9, -0.8,
0.4]]
│
│
│
│
Случайные числа — это "стартовый шум", с которого
│
│
нейросеть начинает учиться.
│
│
│
└─────────────────────────────────────────────────────────────────┘
3.4. Арифметика с тензорами (как в школе)
Вы можете делать с тензорами всё то же, что делали в школе с числами:
складывать, вычитать, умножать, делить.
Сложение
python
a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])
c = a + b
print(c)
# tensor([5, 7, 9])
Умножение на число
python
x = torch.tensor([2, 4, 6])
y = x * 3
print(y)
# tensor([6, 12, 18])
Умножение матриц (самое важное!)
python
# Матрица 2x3
A = torch.tensor([[1, 2, 3],
[4, 5, 6]])
# Матрица 3x2
B = torch.tensor([[7, 8],
[9, 10],
[11, 12]])
# Умножение: A (2x3) @ B (3x2) → результат (2x2)
C = A @ B
print("A @ B = \n", C)
text
┌─────────────────────────────────────────────────────────────────┐
│
УМНОЖЕНИЕ МАТРИЦ (ДЛЯ ЧАЙНИКОВ)
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Это главная операция в нейросетях!
│
│
│
│
A = [[1, 2, 3],
│
[4, 5, 6]]
│
B = [[7, 8],
[9, 10],
[11, 12]]
│
│
│
│
│
│
Берём первую строку A: [1, 2, 3]
│
│
Умножаем на первый столбец B: [7, 9, 11]
│
│
1*7 + 2*9 + 3*11 = 7 + 18 + 33 = 58 ← первый элемент
│
│
│
│
И так для каждой пары строки и столбца.
│
│
│
│
Результат:
│
C = [[58, 64],
│
│
│
[139, 154]]
│
│
│
└─────────────────────────────────────────────────────────────────┘
3.5. Изменяем форму тензора (очень полезно)
Нейросети часто требуют, чтобы данные были в определённой форме. Например,
картинка 28x28 пикселей — это 784 числа. Но иногда их нужно превратить в вектор
из 784 чисел, а иногда в матрицу 28x28.
python
# Создаём вектор из 12 чисел
x = torch.arange(12)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
print("Исходный:", x)
# Превращаем в матрицу 3x4
y = x.reshape(3, 4)
print("3x4:\n", y)
# Превращаем в матрицу 2x6
z = x.reshape(2, 6)
print("2x6:\n", z)
text
┌─────────────────────────────────────────────────────────────────┐
│
RESHAPE — МАГИЯ ИЗМЕНЕНИЯ ФОРМЫ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Исходный: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
│
│
│
│
reshape(3, 4) →
│
│
[[ 0,
1,
2,
3],
│
│
[ 4,
5,
6,
7],
│
│
[ 8,
9, 10, 11]]
│
│
│
│
reshape(2, 6) →
│
│
[[ 0,
1,
2,
3,
5],
│
│
[ 6,
7,
8,
9, 10, 11]]
│
4,
│
│
│
reshape(4, 3) →
│
│
[[ 0,
1,
2],
│
│
[ 3,
4,
5],
│
│
[ 6,
7,
8],
│
│
[ 9, 10, 11]]
│
│
│
│
Количество чисел должно совпадать! 12 = 3×4 = 2×6 = 4×3
│
│
│
└─────────────────────────────────────────────────────────────────┘
Важно: reshape не меняет сами числа, только то, как они организованы.
3.6. Ваша первая нейросеть (всего в 5 строк!)
А теперь — самое интересное. Мы создадим самую простую нейросеть. Она
называется линейный слой.
python
import torch
import torch.nn as nn
# Создаём линейный слой: 4 входа → 3 выхода
layer = nn.Linear(4, 3)
# Вход: 1 пример, 4 признака
x = torch.tensor([[1.0, 2.0, 3.0, 4.0]])
# Прямой проход
y = layer(x)
print(y)
text
┌─────────────────────────────────────────────────────────────────┐
│
ВАША ПЕРВАЯ НЕЙРОСЕТЬ (ЛИНЕЙНЫЙ СЛОЙ)
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
│
nn.Linear(4, 3) — это нейросеть:
│
│
│
4 входа (числа) → умножаем на веса → 3 выхода (числа)
│
│
│
│
ВХОД
ВЕСА
ВЫХОД
│
│
[1] ────────────────┐
│
[2] ────────────────┼──→ [умножить и сложить] ──→ [0.5]
│
[3] ────────────────┤
──→ [0.2]
│
│
[4] ────────────────┘
──→ [-0.1]
│
│
│
│
│
│
Веса изначально случайные. Поэтому числа на выходе
│
│
будут случайными. В следующей главе мы научимся
│
│
их настраивать (обучать) — тогда они станут
│
│
предсказаниями!
│
│
│
└─────────────────────────────────────────────────────────────────┘
3.7. Что вы научились делать
text
┌─────────────────────────────────────────────────────────────────┐
│
ЧТО МЫ УМЕЕМ ПОСЛЕ ЭТОЙ ГЛАВЫ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
✅ Создавать тензоры из списков чисел
│
✅ Создавать тензоры из нулей, единиц, случайных чисел
│
│
✅ Складывать, умножать тензоры
│
│
✅ Умножать матрицы
│
│
✅ Менять форму тензоров (reshape)
│
│
✅ Создавать простую нейросеть (линейный слой)
│
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
Это уже ПРОГРАММИРОВАНИЕ НЕЙРОСЕТЕЙ!
│
│
│
│
Да, это были основы, но это уже работает код.
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Задание для закрепления
1. Создайте матрицу 4×4 из случайных чисел.
python
# Решение:
m = torch.randn(4, 4)
print(m)
2. Превратите эту матрицу в вектор из 16 чисел.
python
# Решение:
v = m.reshape(16)
print(v)
3. Сложите этот вектор с вектором из единиц.
python
# Решение:
result = v + torch.ones(16)
print(result)
text
┌─────────────────────────────────────────────────────────────────┐
│
ПРОВЕРЬТЕ СЕБЯ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Если ваш код выдал числа без ошибок — ВЫ СПРАВИЛИСЬ!
│
│
│
│
В следующей главе мы узнаем, как нейросеть учится:
│
│
как она превращается из "случайного болвана"
│
│
в "умную систему", которая распознаёт цифры.
│
│
│
└─────────────────────────────────────────────────────────────────┘
Готовы узнать, как работает обучение? Вперёд!
Глава 4. Как нейросеть учится (без страшной
математики)
4.1. Главная идея: нейросеть — это ученик, который
учится на ошибках
Представьте, что вы учите маленького робота распознавать цифры. Вы
показываете ему цифру "3". Он выдаёт ответ: "Это 8". Вы говорите: "Нет, это 3!".
Робот запоминает, что ошибся, и чуть-чуть меняет свои настройки. Вы показываете
другую "3". Робот выдаёт "5". Вы опять поправляете. И так 10 000 раз.
Через 10 000 попыток робот перестаёт ошибаться. Он не знает, почему это 3. Он
просто подобрал настройки, которые работают.
Это и есть обучение нейросети. Только вместо учителя — компьютер, а
вместо робота — нейросеть.
text
┌─────────────────────────────────────────────────────────────────┐
│
КАК УЧИТСЯ НЕЙРОСЕТЬ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
1. Нейросеть видит картинку → выдаёт ответ (случайный)
│
│
2. Сравниваем с правильным ответом → считаем ошибку
│
│
3. Смотрим, как каждый вес повлиял на ошибку
│
4. Меняем веса так, чтобы ошибка уменьшилась
│
│
5. Повторяем шаги 1-4 тысячи раз → ошибка становится
│
│
│
очень маленькой → нейросеть научилась!
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
ЭТО ВСЁ! Никакой магии. Только повторение и
│
│
подгонка чисел.
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
4.2. Три шага обучения
У каждой нейросети обучение происходит по одному и тому же принципу. Три
шага повторяются тысячи раз.
Шаг 1: Прямой проход (Forward Pass)
text
┌─────────────────────────────────────────────────────────────────┐
│
ПРЯМОЙ ПРОХОД
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
ВХОД (числа) → НЕЙРОСЕТЬ → ВЫХОД (ответ)
│
│
│
│
Картинка: [0.2, 0.7, 0.1, ...] → Нейросеть → "Кот (45%)"
│
│
│
│
Мы просто пропускаем данные через сеть и смотрим, что
│
│
она выдала.
│
│
│
└─────────────────────────────────────────────────────────────────┘
Шаг 2: Ошибка (Loss)
text
┌─────────────────────────────────────────────────────────────────┐
│
ФУНКЦИЯ ОШИБКИ (LOSS)
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Если правильный ответ был "Кот", а сеть сказала "Собака":
│
│
│
│
Ошибка = (правильный_ответ - предсказание)²
│
Ошибка = (1 - 0)² = 1 (большая ошибка!)
│
│
│
│
│
Если сеть сказала "Кот" с вероятностью 95%:
│
│
Ошибка = (1 - 0.95)² = 0.0025 (маленькая ошибка!)
│
│
│
│
Чем ближе предсказание к правильному ответу, тем меньше
│
ошибка.
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Шаг 3: Обратный проход (Backward Pass)
text
┌─────────────────────────────────────────────────────────────────┐
│
ОБРАТНЫЙ ПРОХОД (BACKPROPAGATION)
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Это самый важный шаг. Нейросеть "смотрит" на ошибку и
│
│
решает, в какую сторону крутить каждую ручку-вес,
│
│
чтобы ошибка уменьшилась.
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
Вес №1: 0.3 → ошибка уменьшится, если увеличить
│
│
│
│
Вес №2: 0.8 → ошибка уменьшится, если уменьшить
│
│
│
│
Вес №3: 0.1 → ошибка почти не зависит от этого веса │
│
│
│
...
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
Затем ВСЕ веса меняются в правильном направлении.
│
│
│
└─────────────────────────────────────────────────────────────────┘
4.3. Градиентный спуск (это не страшно!)
Градиентный спуск — это просто способ узнать, в какую сторону крутить веса.
Представьте, что вы стоите на склоне горы в густом тумане и хотите спуститься к
подножию. Вы не видите, где подножие, но можете проверить землю ногой в
разных направлениях:
text
┌─────────────────────────────────────────────────────────────────┐
│
ГРАДИЕНТНЫЙ СПУСК НА ПАЛЬЦАХ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Вы стоите на горе. Под ногами — уклон.
│
│
│
│
Вперёд: земля уходит вниз → идите вперёд!
│
│
Назад: земля уходит вверх → не идите назад!
│
│
Влево: земля ровная → можете не идти
│
Вправо: земля круто вниз → бегите вправо!
│
│
│
│
│
Вы выбираете направление, в котором склон самый крутой,
│
│
и делаете шаг. Потом снова проверяете. И так, пока не
│
│
окажетесь на дне.
│
│
│
│
В нейросети это называется "градиентный спуск".
│
"Градиент" — это уклон. "Спуск" — шаги вниз.
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Вот как это выглядит в коде:
python
# PyTorch делает всё за нас!
loss.backward()
# Вычисляет градиенты (уклон)
optimizer.step()
# Делает шаг вниз (меняет веса)
optimizer.zero_grad()# Готовимся к следующему шагу
Вы не пишете сложные формулы. Вы просто вызываете три команды.
4.4. Аналогия: нейросеть — это угадыватель чисел
Давайте поиграем в игру. Я загадал число. Вы должны его угадать.
Вы: "10?"
Я: "Слишком мало!"
Вы: "20?"
Я: "Слишком много!"
Вы: "15?"
Я: "Почти! Ещё чуть-чуть."
Вы: "16?"
Я: "Правильно!"
text
┌─────────────────────────────────────────────────────────────────┐
│
НЕЙРОСЕТЬ УГАДЫВАЕТ ЧИСЛА
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Нейросеть делает то же самое, только:
│
│
• Ей дают не числа, а картинки
│
• Ей говорят: "Нет, это не кот, это собака"
│
│
• Она подгоняет миллионы весов вместо одного числа
│
│
• Она угадывает миллионы раз, пока не научится
│
│
│
│
│
Отличие: нейросеть подгоняет не одно число, а миллионы!
│
Но PyTorch делает это за нас.
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
4.5. Сколько нужно учиться?
Чем больше примеров, тем лучше.
text
┌─────────────────────────────────────────────────────────────────┐
│
СКОЛЬКО НУЖНО ПРИМЕРОВ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Для простых задач (цифры): 50 000 примеров
│
│
Для сложных задач (лица): 1 000 000 примеров
│
│
Для очень сложных (ChatGPT): 10 000 000 000 примеров
│
│
│
│
Каждый пример — это одна картинка с правильным ответом.
│
│
│
│
Нейросеть просматривает все примеры несколько раз.
│
│
Один такой "круг" называется эпоха (epoch).
│
│
│
│
Обычно нужно 5-50 эпох.
│
│
│
└─────────────────────────────────────────────────────────────────┘
4.6. Что вы теперь знаете
text
┌─────────────────────────────────────────────────────────────────┐
│
ГЛАВНЫЕ ИДЕИ ГЛАВЫ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
✅ Нейросеть учится на ошибках
│
✅ Чем больше примеров — тем лучше
│
│
✅ Обучение = повторение трёх шагов:
│
│
│
1. Прямой проход (предсказание)
│
│
2. Ошибка (сравнение с правильным ответом)
│
│
3. Обратный проход (настройка весов)
│
│
✅ Градиентный спуск = шаги вниз по склону ошибки
│
│
✅ Вся сложная математика внутри PyTorch
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
Теперь вы готовы написать свою первую НАСТОЯЩУЮ
│
│
нейросеть!
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Задание для закрепления
Вопрос 1: Что такое "эпоха" в обучении нейросети?
Ответ: Это один полный проход по ВСЕМ тренировочным примерам.
Вопрос 2: Что такое "градиентный спуск"?
Ответ: Это способ настройки весов, при котором мы идём в сторону
уменьшения ошибки.
Вопрос 3: Кто считает градиенты в PyTorch?
Ответ: Команда loss.backward(). Мы просто вызываем её, а PyTorch делает всю
работу.
В следующей главе мы напишем НАСТОЯЩУЮ нейросеть, которая
распознаёт рукописные цифры. Это будет ваше первое приложение ИИ!
Глава 5. Ваша первая нейросеть — распознаём
рукописные цифры
5.1. MNIST — "Hello, World!" нейросетей
MNIST — это набор из 70 000 рукописных цифр. Это самый известный датасет в
мире нейросетей. Если вы сделали нейросеть, которая распознаёт MNIST — вы уже
не новичок.
text
┌─────────────────────────────────────────────────────────────────┐
│
ЧТО ТАКОЕ MNIST
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Это набор чёрно-белых картинок 28×28 пикселей:
│
│
│
│
┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐
│
│
│ 0 │ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │ 5 │ │ 6 │ │ 7 │ │ 8 │ │ 9 │ │
│
│┌─┐│ │┌─┐│ │┌─┐│ │┌─┐│ │┌─┐│ │┌─┐│ │┌─┐│ │┌─┐│ │┌─┐│ │┌─┐│ │
│
││●││ ││ █││ ││█││ ││█││ ││●││ ││█││ ││●││ ││●││ ││█││ ││█││ │
│
│└─┘│ │└─┘│ │└─┘│ │└─┘│ │└─┘│ │└─┘│ │└─┘│ │└─┘│ │└─┘│ │└─┘│ │
│
└───┘ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘
│
│
│
│
70 000 картинок. 60 000 — для обучения, 10 000 — для теста. │
│
│
│
Ваша задача: научить нейросеть правильно определять
│
цифру на картинке.
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
5.2. Что мы построим
Мы создадим нейросеть с одним скрытым слоем. Простую, но рабочую.
text
┌─────────────────────────────────────────────────────────────────┐
│
АРХИТЕКТУРА НЕЙРОСЕТИ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
ВХОД
СКРЫТЫЙ СЛОЙ
ВЫХОД
│
784 числа
128 нейронов
10 чисел
│
(пиксели)
(обработка)
(цифры 0-9)
│
│
│
│
│
│
┌────┐
│
┌────┐
┌────┐
│
│ 0.2│ ─────→ │ ×
│ ───────────→ │ 0.9│ ← вероятность 0
│
│
├────┤
│
├────┤
│
│
│ 0.7│ ─────→ │ ×
│ ───────────→ │ 0.1│ ← вероятность 1
│
│
├────┤
│
├────┤
│
│
│ 0.1│ ─────→ │ ×
│ ───────────→ │ 0.0│ ← вероятность 2
│
│
├────┤
│
│
│
│ ...│ ─────→ │ ×
│
└────┘
│ ×
│ ×
│ ×
├────┤
│ ───────────→ │ ...│
└────┘
└────┘
│
│
│
│
│
Вход: 784 пикселя → скрытый слой → 10 вероятностей
│
│
Самая большая вероятность → это ответ.
│
│
│
└─────────────────────────────────────────────────────────────────┘
5.3. Весь код целиком (за 30 строк!)
Давайте напишем всё сразу, а потом разберём каждую строчку.
Откройте Jupyter Notebook и скопируйте этот код:
python
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 1. Загружаем данные MNIST
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
train_data = datasets.MNIST(root='./data', train=True, download=True, transform=trans
form)
test_data = datasets.MNIST(root='./data', train=False, download=True, transform=trans
form)
train_loader = DataLoader(train_data, batch_size=64, shuffle=True)
test_loader = DataLoader(test_data, batch_size=1000, shuffle=False)
# 2. Создаём нейросеть
class SimpleNN(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(28*28, 128)
# 784 → 128
self.fc2 = nn.Linear(128, 10)
# 128 → 10
def forward(self, x):
x = x.view(-1, 28*28)
# распрямляем картинку в вектор
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
model = SimpleNN()
# 3. Настраиваем обучение
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 4. Обучаем!
for epoch in range(5):
for images, labels in train_loader:
optimizer.zero_grad()
output = model(images)
loss = criterion(output, labels)
loss.backward()
optimizer.step()
# Проверяем точность после каждой эпохи
correct = 0
total = 0
with torch.no_grad():
for images, labels in test_loader:
output = model(images)
_, predicted = torch.max(output.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Эпоха {epoch+1}: точность {100 * correct / total:.2f}%')
Запустите этот код! Через пару минут вы увидите что-то вроде:
text
Эпоха 1: точность 93.45%
Эпоха 2: точность 96.12%
Эпоха 3: точность 97.03%
Эпоха 4: точность 97.45%
Эпоха 5: точность 97.67%
Поздравляю! Вы только что создали ИИ, который распознаёт цифры! Ваша
нейросеть работает лучше многих людей.
5.4. Разбор кода по частям (всё просто!)
Часть 1: Загрузка данных (4 строки)
python
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
Что это значит:
ToTensor()
Normalize
— превращает картинку в тензор (список чисел)
— делает числа удобными для обучения (центрирует около нуля)
text
┌─────────────────────────────────────────────────────────────────┐
│
ЗАЧЕМ НОРМАЛИЗОВАТЬ ДАННЫЕ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Обычные пиксели: от 0 до 255
│
│
Нормализованные: от -1 до 1
│
│
│
│
Почему это важно?
│
│
Нейросети легче учиться на маленьких числах.
│
│
Как если бы вы учили ребёнка считать на числах от 0 до 10,
│
│
а не от 0 до 1000.
│
│
│
└─────────────────────────────────────────────────────────────────┘
Часть 2: Создание нейросети (8 строк)
python
class SimpleNN(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(28*28, 128)
# 784 → 128
self.fc2 = nn.Linear(128, 10)
# 128 → 10
def forward(self, x):
x = x.view(-1, 28*28)
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
Что здесь происходит:
text
┌─────────────────────────────────────────────────────────────────┐
│
РАЗБОР НЕЙРОСЕТИ ПО КОСТОЧКАМ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
self.fc1 = nn.Linear(784, 128)
│
│
┌─────────────────────────────────────────────────────────┐
│
│
Это первый слой. 784 входа, 128 выходов.
│
│
784 — это 28×28 пикселей.
│
│
128 — это скрытый слой (мы можем менять это число).
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
│
│
│
self.fc2 = nn.Linear(128, 10)
│
│
┌─────────────────────────────────────────────────────────┐
│
│
Это второй слой. 128 входов, 10 выходов.
│
│
│
│
10 — это цифры от 0 до 9.
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
torch.relu(self.fc1(x))
│
│
┌─────────────────────────────────────────────────────────┐
│
│
ReLU — это функция активации. Она делает нейросеть
│
│
нелинейной, чтобы она могла распознавать сложные
│
│
│
│
узоры. Если бы её не было, сеть была бы просто
│
│
│
│
│
│
│
линейной и не смогла бы распознавать цифры.
│
│
│
│
│
│
ReLU(x) = max(0, x)
│
│
Отрицательные числа превращает в 0, положительные
│
│
оставляет как есть.
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Часть 3: Обучение (5 строк)
python
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
for epoch in range(5):
for images, labels in train_loader:
optimizer.zero_grad()
output = model(images)
loss = criterion(output, labels)
loss.backward()
optimizer.step()
text
┌─────────────────────────────────────────────────────────────────┐
│
ЦИКЛ ОБУЧЕНИЯ (ШАГ ЗА ШАГОМ)
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
1. optimizer.zero_grad()
│
│
┌─────────────────────────────────────────────────────┐
│
│
│
"Подготовься! Сейчас будем учиться."
│
│
│
│
Обнуляем старые градиенты, чтобы не смешать их.
│
│
│
└─────────────────────────────────────────────────────┘
│
│
│
│
2. output = model(images)
│
│
┌─────────────────────────────────────────────────────┐
│
│
│
"Посмотри на эту картинку, что ты видишь?"
│
│
│
│
Прямой проход — нейросеть выдаёт предсказание.
│
│
│
└─────────────────────────────────────────────────────┘
│
│
│
│
3. loss = criterion(output, labels)
│
│
┌─────────────────────────────────────────────────────┐
│
│
│
"Сравни ответ с правильным. Какая ошибка?"
│
│
│
│
Вычисляем, насколько мы ошиблись.
│
│
│
└─────────────────────────────────────────────────────┘
│
│
│
│
4. loss.backward()
│
│
┌─────────────────────────────────────────────────────┐
│
│
│
"Понял! Сейчас пойму, как исправить ошибку."
│
│
│
│
Вычисляем градиенты (куда крутить веса).
│
│
│
└─────────────────────────────────────────────────────┘
│
│
│
│
5. optimizer.step()
│
│
┌─────────────────────────────────────────────────────┐
│
│
│
"Исправляю!"
│
│
│
Крутим все веса в правильную сторону.
│
└─────────────────────────────────────────────────────┘
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
5.5. Как проверить, что работает
python
# Проверяем точность после каждой эпохи
correct = 0
total = 0
with torch.no_grad():
for images, labels in test_loader:
output = model(images)
_, predicted = torch.max(output.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Точность: {100 * correct / total:.2f}%')
text
┌─────────────────────────────────────────────────────────────────┐
│
ЧТО ТАКОЕ ТОЧНОСТЬ (ACCURACY)
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Точность = Правильных ответов / Всех ответов × 100%
│
│
│
│
Если сеть правильно распознала 9700 цифр из 10000:
│
│
Точность = 9700 / 10000 × 100% = 97%
│
│
│
│
Для MNIST хорошая точность: > 95%
│
│
Отличная: > 98%
│
│
Человек: ~99.7% (редко ошибается в рукописных цифрах)
│
│
│
└─────────────────────────────────────────────────────────────────┘
5.6. Что вы только что сделали
text
┌─────────────────────────────────────────────────────────────────┐
│
ВАШИ ДОСТИЖЕНИЯ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
✅ Написали нейросеть, которая распознаёт цифры
│
│
✅ Обучили её на 60 000 примерах
│
│
✅ Достигли точности > 95%
│
│
✅ Использовали весь цикл: загрузка → модель → обучение
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
Вы только что создали ИИ-приложение!
│
│
│
│
Это не шутка. У вас теперь есть работающая
│
│
│
│
нейросеть.
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
└─────────────────────────────────────────────────────────────────┘
Задание: улучшите свою нейросеть!
Попробуйте изменить что-то и посмотреть, как изменится точность:
1. Увеличьте скрытый слой: 128 → 256 или 512
2. Добавьте ещё один слой: self.fc3 = nn.Linear(128, 64)
3. Измените количество эпох: 5 → 10
4. Измените скорость обучения: 0.001 → 0.01 или 0.0001
python
# Пример более глубокой сети
class DeepNN(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(28*28, 256)
self.fc2 = nn.Linear(256, 128)
self.fc3 = nn.Linear(128, 10)
def forward(self, x):
x = x.view(-1, 28*28)
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
x = self.fc3(x)
return x
Готовы к следующему шагу? В следующей главе мы добавим магии —
улучшим нейросеть с помощью сверточных слоёв и добьёмся точности >
98%!
Глава 6. Немного магии — сверточные нейросети
6.1. Почему простая сеть работает, но не идеально
Наша нейросеть из предыдущей главы работала так:
text
Картинка → распрямить в вектор 784 → нейросеть → ответ
Проблема: мы потеряли информацию о том, что пиксели рядом друг с другом.
Картинка стала просто "мешком" чисел.
text
┌─────────────────────────────────────────────────────────────────┐
│
ПОЧЕМУ ПРОСТАЯ СЕТЬ НЕ ИДЕАЛЬНА
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Представьте, что вы смотрите на картинку, но видите
│
│
только все пиксели по отдельности, без понимания,
│
│
что они образуют цифру:
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
● ● ● ● ● ● ● ● ● ●
│
│
│
│
● ● ● ● ● ● ● ● ● ●
│
│
│
│
● ● ● ● ● ● ● ● ● ●
│
│
│
│
● ● ● ● ● ● ● ● ● ●
│
│
│
│
● ● ● ● ● ● ● ● ● ●
│
│
● ● ● ● ● ● ● ● ● ●
│
│
● ● ● ● ● ● ● ● ● ●
│
└─────────────────────────────────────────────────────────┘
← Просто облако точек
Непонятно, что здесь
│
│
│
│
│
│
│
│
│
│
│
Ваш мозг так не работает. Он видит целые куски:
│
│
"вот здесь прямая линия", "а здесь уголок".
│
│
│
└─────────────────────────────────────────────────────────────────┘
Решение: Сверточные нейросети (CNN). Они смотрят на картинку не целиком, а
маленькими кусочками.
6.2. Как работает свертка (на пальцах)
Представьте, что у вас есть маленькое окошко (фильтр) размером 3×3 пикселя. Вы
двигаете его по картинке и в каждом месте смотрите:
text
┌─────────────────────────────────────────────────────────────────┐
│
КАК РАБОТАЕТ СВЁРТКА
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Картинка 28×28:
Фильтр 3×3:
│
│
│
│
┌─────────────────────┐
┌───────────┐
│
│
● ● ● ● ● ● ● ●
│
│
1
0
1
│
│
│
│
● ● ● ● ● ● ● ●
│
│
0
1
0
│
│
│
│
● ● ● ● ● ● ● ●
│
│
1
0
1
│
│
│
│
● ● ● ● ● ● ● ●
│
│
│
● ● ● ● ● ● ● ●
│
│
│
│
● ● ● ● ● ● ● ●
│
│
Ищем в картинке
│
│
│
● ● ● ● ● ● ● ●
│
│
такой же узор!
│
│
└─────────────────────┘
──────────→
│
────────────
│
│
└───────────┘
│
│
│
│
Фильтр "скользит" по картинке:
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
┌───┐
│
│
│
│
│
│
│
│
│
└───┘
│
│
│
│
Шаг 1: смотрим верхний левый угол
│
│
│
│
Шаг 2: сдвигаемся на 1 пиксель вправо
│
│
│
│
Шаг 3: сдвигаемся ещё...
│
│
│
│
...
│
│
│
│
Когда фильтр находит похожий узор — он активируется! │
│
│
└─────────────────────────────────────────────────────────┘
│
│ ← Фильтр здесь
│
│
│
└─────────────────────────────────────────────────────────────────┘
Главная идея: разные фильтры ищут разные вещи:
Один фильтр ищет горизонтальные линии
Второй — вертикальные
Третий — уголки
Четвёртый — круги
Пятый — текстуры
Чем больше фильтров — тем лучше сеть видит картинку!
6.3. Архитектура сверточной нейросети
text
┌─────────────────────────────────────────────────────────────────┐
│
АРХИТЕКТУРА CNN
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
ВХОД
СЛОИ
│
28×28×1
ВЫХОД
│
(изображение)
│
│
│
│
│
▼
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
Свёртка 1: 32 фильтра 3×3 → 28×28×32
│
│
│
│
ReLU (активация)
│
│
│
│
Пулинг (MaxPool): уменьшаем размер → 14×14×32
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
▼
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
Свёртка 2: 64 фильтра 3×3 → 14×14×64
│
│
│
│
ReLU
│
│
│
│
Пулинг: уменьшаем размер → 7×7×64
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
▼
│
│
┌─────────────────────────────────────────────────────────┐
│
│
Выпрямляем (Flatten): 7×7×64 → 3136 чисел
│
│
Полносвязный слой: 3136 → 128
│
│
ReLU
│
│
│
│
Полносвязный слой: 128 → 10 (цифры 0-9)
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
│
│
│
▼
│
ВЫХОД: вероятности для каждой цифры
│
│
│
└─────────────────────────────────────────────────────────────────┘
6.4. Код сверточной нейросети
python
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 1. Загружаем данные (то же самое)
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
train_data = datasets.MNIST(root='./data', train=True, download=True, transform=trans
form)
test_data = datasets.MNIST(root='./data', train=False, download=True, transform=trans
form)
train_loader = DataLoader(train_data, batch_size=64, shuffle=True)
test_loader = DataLoader(test_data, batch_size=1000, shuffle=False)
# 2. Создаём СВЕРТОЧНУЮ нейросеть
class CNN(nn.Module):
def __init__(self):
super().__init__()
# Первый блок: свёртка + пулинг
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
# 1 канал → 32 фильт
ра
self.pool = nn.MaxPool2d(2, 2)
# уменьшаем размер в 2 раза
# Второй блок: свёртка + пулинг
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
# Полносвязная часть
self.fc1 = nn.Linear(64 * 7 * 7, 128)
self.fc2 = nn.Linear(128, 10)
# 64*7*7 = 3136
# 128 → 10
# 32 → 64 фильтра
def forward(self, x):
# Первый блок
x = torch.relu(self.conv1(x))
x = self.pool(x)
# 28×28×32
# 14×14×32
# Второй блок
x = torch.relu(self.conv2(x))
x = self.pool(x)
# 14×14×64
# 7×7×64
# Выпрямляем
x = x.view(-1, 64 * 7 * 7)
# 3136 чисел
# Полносвязная часть
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
model = CNN()
# 3. Обучение (то же самое!)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
for epoch in range(5):
for images, labels in train_loader:
optimizer.zero_grad()
output = model(images)
loss = criterion(output, labels)
loss.backward()
optimizer.step()
# Проверка
correct = 0
total = 0
with torch.no_grad():
for images, labels in test_loader:
output = model(images)
_, predicted = torch.max(output.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Эпоха {epoch+1}: точность {100 * correct / total:.2f}%')
Результат:
text
Эпоха 1: точность 97.20%
Эпоха 2: точность 98.40%
Эпоха 3: точность 98.71%
Эпоха 4: точность 98.95%
Эпоха 5: точность 99.06%
99%! Это уже почти как человек!
6.5. Что мы только что сделали
text
┌─────────────────────────────────────────────────────────────────┐
│
ЧТО МЫ ДОБАВИЛИ НОВОГО
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
✅ nn.Conv2d — сверточный слой (смотрит на кусочки)
│
│
✅ nn.MaxPool2d — пулинг (уменьшает размер, чтобы сеть
│
│
│
была быстрее)
│
✅ Результат: 99% точность вместо 97%
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
Сверточные нейросети — это стандарт в компьютерном
│
│
зрении. Все современные модели (для лиц, машин,
│
│
│
│
рентгеновских снимков) используют CNN.
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
6.6. Что такое пулинг (Pooling)
text
┌─────────────────────────────────────────────────────────────────┐
│
ЧТО ТАКОЕ MAX POOLING
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Мы берём окно 2×2 и оставляем только самое большое число.
│
Это уменьшает картинку в 2 раза.
│
│
│
│
│
Было (4×4):
Стало (2×2):
│
┌─────────────────┐
│
│ 1
2
3
4
│
│
│ 5
6
7
8
│
│
┌─────────────────┐
→
│
max(1,2,5,6) │
│
= 6
│
│
│
│
│
│ 9 10 11 12
│
│
max(3,4,7,8)
│
│
│
│13 14 15 16
│
│
= 8
│
│
│
└─────────────────┘
└─────────────────┘
│
│
│
│
Зачем?
│
• Меньше чисел → сеть работает быстрее
│
│
• Сеть становится устойчивее к мелким смещениям
│
│
│
(если цифра сдвинулась на пиксель — не страшно)
│
│
│
└─────────────────────────────────────────────────────────────────┘
6.7. А теперь — визуализация!
Давайте посмотрим, что наша сеть видит на самом деле.
python
import matplotlib.pyplot as plt
# Берём одну картинку из тестового набора
image, label = test_data[0]
# Делаем предсказание
with torch.no_grad():
output = model(image.unsqueeze(0))
probabilities = torch.softmax(output, dim=1)
predicted = torch.argmax(probabilities, dim=1).item()
# Показываем картинку и предсказание
plt.imshow(image.squeeze(), cmap='gray')
plt.title(f'Истинная цифра: {label}, Предсказание: {predicted}')
plt.show()
# Показываем вероятности
print('Вероятности:')
for i, prob in enumerate(probabilities.squeeze()):
print(f'
{i}: {prob.item():.3f}')
text
┌─────────────────────────────────────────────────────────────────┐
│
ЧТО ВИДИТ НЕЙРОСЕТЬ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
│
Картинка:
Вероятности:
│
│
│
┌───┐
0: 0.001
│
│
│ 3 │
1: 0.002
│
│
└───┘
2: 0.001
│
│
3: 0.985 ← Уверена!
│
│
4: 0.001
│
│
5: 0.003
│
│
6: 0.002
│
│
7: 0.001
│
│
8: 0.002
│
│
9: 0.002
│
│
│
│
Нейросеть говорит: "Я на 98.5% уверена, что это цифра 3"
│
│
│
└─────────────────────────────────────────────────────────────────┘
Задание: экспериментируйте!
1. Увеличьте число фильтров: 32 → 64, 64 → 128
2. Добавьте третий сверточный слой
3. Добавьте Dropout (защита от переобучения):
python
self.dropout = nn.Dropout(0.2)
# в forward:
x = self.dropout(x)
4. Измените размер батча: 64 → 128 или 32
В следующей главе мы применим всё, что узнали, к реальному проекту —
распознаванию кошек и собак!
Глава 7. Ваш первый проект — нейросеть, которая
видит
7.1. Что мы будем делать
До сих пор мы работали с цифрами. Это хорошо для обучения, но не слишком
впечатляет. Теперь мы создадим нейросеть, которая распознаёт кошек и собак.
text
┌─────────────────────────────────────────────────────────────────┐
│
НАШ ПРОЕКТ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
Нейросеть, которая отвечает на вопрос:
│
│
│
│
"Это кот или собака?"
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
┌─────────────┐
┌─────────────────┐
│
│
Картинка
│ → │
│
│
(кота)
│
│
└─────────────┘
│
Нейросеть
(обученная)
┌─────────────┐
│ → │
│
└─────────────────┘
"Кот"
│
95%
│
│
│
│
│
└─────────────┘
│
│
│
│
Это одна из самых популярных задач для начинающих!
│
│
│
└─────────────────────────────────────────────────────────────────┘
7.2. Данные: где взять кошек и собак
Датасет "Dogs vs Cats" от Kaggle:
25 000 картинок кошек
25 000 картинок собак
Всего 50 000 картинок
text
┌─────────────────────────────────────────────────────────────────┐
│
ДАННЫЕ ДЛЯ ПРОЕКТА
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Папка с данными:
│
│
│
│
train/
│
│
├── cat.0.jpg
│
│
├── cat.1.jpg
│
│
├── ...
│
│
├── dog.0.jpg
│
│
├── dog.1.jpg
│
│
├── ...
│
│
│
│
Это обычные картинки. Мы загрузим их, изменим размер,
│
│
и скормим нейросети.
│
│
│
└─────────────────────────────────────────────────────────────────┘
7.3. Скачиваем данные (быстро)
Если у вас нет датасета, не беда. В интернете есть много готовых датасетов.
Простой вариант: используем встроенный датасет из PyTorch
(torchvision.datasets.ImageFolder).
Структура папок:
text
data/
├── train/
│
├── cats/
│
│
├── cat1.jpg
│
│
├── cat2.jpg
│
│
└── ...
│
└── dogs/
│
├── dog1.jpg
│
├── dog2.jpg
│
└── ...
← все картинки кошек
← все картинки собак
└── test/
├── cats/
└── dogs/
7.4. Код: загружаем данные
python
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import os
# Преобразования для картинок
transform = transforms.Compose([
transforms.Resize((64, 64)),
# уменьшаем до 64×64
transforms.RandomHorizontalFlip(),
# случайно отражаем (для разнообразия)
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
# для RGB
])
# Загружаем данные из папок
train_data = datasets.ImageFolder(root='data/train', transform=transform)
test_data = datasets.ImageFolder(root='data/test', transform=transform)
train_loader = DataLoader(train_data, batch_size=32, shuffle=True)
test_loader = DataLoader(test_data, batch_size=32, shuffle=False)
print(f'Тренировочных: {len(train_data)} картинок')
print(f'Тестовых: {len(test_data)} картинок')
7.5. Код: нейросеть (уже знакомая!)
Мы используем ту же архитектуру CNN, что и для MNIST, но адаптируем под
цветные картинки.
python
class CatDogCNN(nn.Module):
def __init__(self):
super().__init__()
# Вход: 3 канала (RGB), 64×64 пикселя
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
self.pool = nn.MaxPool2d(2, 2)
self.dropout = nn.Dropout(0.25)
# После трёх пулингов размер уменьшится: 64 → 32 → 16 → 8
self.fc1 = nn.Linear(128 * 8 * 8, 256)
self.fc2 = nn.Linear(256, 2)
# 2 класса: кот или собака
def forward(self, x):
x = self.pool(torch.relu(self.conv1(x)))
# 64→32
x = self.pool(torch.relu(self.conv2(x)))
# 32→16
x = self.pool(torch.relu(self.conv3(x)))
# 16→8
x = x.view(-1, 128 * 8 * 8)
x = torch.relu(self.fc1(x))
x = self.dropout(x)
x = self.fc2(x)
return x
model = CatDogCNN()
7.6. Код: обучение (вы уже знаете!)
python
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
for epoch in range(10):
running_loss = 0.0
for images, labels in train_loader:
optimizer.zero_grad()
output = model(images)
loss = criterion(output, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
# Проверяем точность
correct = 0
total = 0
with torch.no_grad():
for images, labels in test_loader:
output = model(images)
_, predicted = torch.max(output.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Эпоха {epoch+1}: loss = {running_loss/len(train_loader):.4f}, '
f'точность = {100 * correct / total:.2f}%')
Результат (примерный):
text
Эпоха 1: loss = 0.693, точность = 56.20%
Эпоха 2: loss = 0.610, точность = 64.80%
Эпоха 3: loss = 0.552, точность = 71.30%
Эпоха 4: loss = 0.498, точность = 76.50%
Эпоха 5: loss = 0.451, точность = 80.20%
Эпоха 6: loss = 0.410, точность = 83.10%
Эпоха 7: loss = 0.378, точность = 85.40%
Эпоха 8: loss = 0.352, точность = 87.20%
Эпоха 9: loss = 0.330, точность = 88.70%
Эпоха 10: loss = 0.310, точность = 89.90%
~90% точности! Вы создали нейросеть, которая отличает кошек от собак!
7.7. Тестируем на новой картинке
python
from PIL import Image
import matplotlib.pyplot as plt
def predict_image(image_path):
# Загружаем картинку
image = Image.open(image_path)
# Применяем те же преобразования
transform = transforms.Compose([
transforms.Resize((64, 64)),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
img_tensor = transform(image).unsqueeze(0)
# Предсказываем
model.eval()
with torch.no_grad():
output = model(img_tensor)
probabilities = torch.softmax(output, dim=1)
predicted = torch.argmax(probabilities, dim=1).item()
# Показываем
classes = ['Кот', 'Собака']
plt.imshow(image)
plt.title(f'Это {classes[predicted]}! Уверенность: {probabilities[0][predicted]:.
2%}')
plt.show()
# Тестируем на своей картинке
predict_image('my_cat.jpg')
text
┌─────────────────────────────────────────────────────────────────┐
│
ВАША НЕЙРОСЕТЬ В ДЕЙСТВИИ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
[Ваша картинка кота]
[Ваша картинка собаки]
│
│
│
│
▼
▼
│
│
┌─────────────────┐
┌─────────────────┐
│
│
│
ЭТО КОТ!
│
│
ЭТО СОБАКА!
│
│
│
│
Уверенность
│
│
Уверенность
│
│
│
│
94%
│
│
91%
│
│
│
└─────────────────┘
└─────────────────┘
│
│
│
└─────────────────────────────────────────────────────────────────┘
7.8. Что дальше? Как улучшить результат
text
┌─────────────────────────────────────────────────────────────────┐
│
КАК УЛУЧШИТЬ НЕЙРОСЕТЬ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
🔹 Использовать предобученные модели (Transfer Learning)
│
│
Вместо обучения с нуля, берём модель, уже обученную
│
│
на миллионах картинок (ResNet, VGG, EfficientNet).
│
│
Это даёт 95%+ точности с минимальным обучением.
│
│
│
│
🔹 Увеличить размер картинок (128×128 или 224×224)
│
Сеть видит больше деталей
│
│
│
│
│
🔹 Добавить аугментацию (повороты, обрезки, изменение
│
│
яркости)
│
│
Сеть становится устойчивее к изменениям
│
│
│
│
🔹 Использовать больше эпох (20-30)
│
Но следить, чтобы не было переобучения
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
7.9. Краткий итог книги
text
┌─────────────────────────────────────────────────────────────────┐
│
ЧТО ВЫ НАУЧИЛИСЬ ЗА 7 ГЛАВ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
✅ Устанавливать Python, PyTorch, Jupyter Notebook
│
│
✅ Создавать тензоры и работать с ними
│
│
✅ Понимать, как нейросети учатся
│
│
✅ Писать полносвязные нейросети (MLP)
│
│
✅ Писать сверточные нейросети (CNN)
│
│
✅ Обучать нейросети на реальных данных
│
│
✅ Распознавать цифры (MNIST 99%)
│
│
✅ Распознавать кошек и собак (~90%)
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
Вы теперь знаете 80% того, что нужно знать
│
│
начинающему специалисту по нейросетям.
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Что почитать дальше
1. PyTorch Documentation — официальная документация
2. Kaggle — соревнования и датасеты
3. Fast.ai — бесплатные курсы по глубокому обучению
4. YouTube — каналы: Sentdex, Andrej Karpathy, Two Minute Papers
Финальное слово
Вы сделали это!
Вы прошли путь от человека, который боялся слова "нейросеть", до создателя
приложения на основе ИИ. Это огромное достижение.
Помните:
Нейросети — это просто числа, которые мы подгоняем
Вся сложная математика спрятана внутри библиотек
Вы можете создать нейросеть для любой задачи
Главное — не бояться и экспериментировать
Сделайте шаг. Напишите код. Создайте что-то новое.
Мир ждёт ваших идей.
text
┌─────────────────────────────────────────────────────────────────┐
│
│
★
│
★
★
★
★
★
★
★
★
★
│
│
│
│
ВЫ --- ТВОРЕЦ ИСКУССТВЕННОГО ИНТЕЛЛЕКТА!
│
│
│
★
│
★
★
★
★
★
★
★
★
★
│
│
│
│
│
│
Спасибо, что прочитали эту книгу.
│
│
│
│
Теперь — создавайте!
│
│
│
└─────────────────────────────────────────────────────────────────┘
Глава 8. Что дальше: ваш путь в мир нейросетей
8.1. Поздравляю! Вы сделали первый и самый важный
шаг
Вы только что прошли путь от полного нуля до создания нейросети, которая
распознаёт кошек и собак. Это не шутка и не "игрушечный" пример. Это реальная
задача, которую решают в индустрии каждый день.
text
┌─────────────────────────────────────────────────────────────────┐
│
ВАШ ПРОГРЕСС ЗА 7 ГЛАВ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
День 1: "Что такое нейросеть?"
│
│
День 2: Установка Python и PyTorch
│
│
День 3: Первые тензоры и операции
│
│
День 4: Понимание обучения
│
│
День 5: Первая нейросеть (MNIST)
│
│
День 6: Сверточные нейросети
│
│
День 7: КОШКИ И СОБАКИ!
│
│
│
│
┌─────────────────────────────────────────────────────────┐
│
│
Это больше, чем делают 90% людей, которые
│
│
│
│
│
интересуются нейросетями.
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
└─────────────────────────────────────────────────────────────────┘
8.2. Ваша дорожная карта: от новичка до эксперта
text
┌─────────────────────────────────────────────────────────────────┐
│
ДОРОЖНАЯ КАРТА РАЗВИТИЯ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
УРОВЕНЬ 1: НОВИЧОК (ВЫ ЗДЕСЬ!)
│
│
┌─────────────────────────────────────────────────────────┐
│
│
✅ Понимаю, что такое нейросеть
│
│
✅ Могу написать простую CNN
│
│
│
│
✅ Могу обучить модель на своих данных
│
│
│
│
✅ Знаю PyTorch на базовом уровне
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
▼
│
│
УРОВЕНЬ 2: ПРАКТИК
│
│
┌─────────────────────────────────────────────────────────┐
│
│
□ Использую предобученные модели (Transfer Learning)
│
│
□ Работаю с большими датасетами (ImageNet)
│
│
│
│
□ Знаю, как бороться с переобучением
│
│
│
│
□ Использую TensorBoard для визуализации
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
▼
│
│
УРОВЕНЬ 3: ПРОДВИНУТЫЙ
│
│
┌─────────────────────────────────────────────────────────┐
│
│
□ Понимаю архитектуры: ResNet, EfficientNet, ViT
│
│
│
│
□ Могу дообучать модели на своих задачах
│
│
│
│
□ Знаю, как оптимизировать гиперпараметры
│
│
│
│
□ Могу деплоить модели в продакшен
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
▼
│
│
УРОВЕНЬ 4: ЭКСПЕРТ
│
│
┌─────────────────────────────────────────────────────────┐
│
│
□ Читаю и понимаю научные статьи
│
│
□ Могу реализовать модели из статей
│
│
│
│
│
│
│
□ Пишу свои архитектуры
│
│
│
│
□ Участвую в соревнованиях на Kaggle
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
└─────────────────────────────────────────────────────────────────┘
8.3. Три направления для развития
Направление 1: Компьютерное зрение
text
┌─────────────────────────────────────────────────────────────────┐
│
КОМПЬЮТЕРНОЕ ЗРЕНИЕ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Что вы уже умеете:
│
✅ Классификация (кот/собака, цифры)
│
│
│
│
│
Что можно изучить:
│
🔹 Обнаружение объектов (Object Detection)
│
│
│
→ YOLO, Faster R-CNN
│
│
→ Найти все лица на фото
│
│
│
│
🔹 Сегментация (Segmentation)
│
→ U-Net, Mask R-CNN
│
→ Выделить контур объекта
│
│
│
│
│
│
🔹 Генерация изображений
│
│
→ GAN, Diffusion Models (Stable Diffusion)
│
│
→ Создавать новые лица, рисунки
│
│
│
│
🔹 Распознавание лиц
│
│
→ FaceNet, ArcFace
│
│
→ Разблокировка телефона по лицу
│
│
│
└─────────────────────────────────────────────────────────────────┘
Направление 2: Обработка текста (NLP)
text
┌─────────────────────────────────────────────────────────────────┐
│
ОБРАБОТКА ТЕКСТА (NLP)
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Основы, которые нужно изучить:
│
🔹 Word Embeddings (Word2Vec, GloVe)
│
│
│
→ Превращаем слова в векторы
│
│
│
│
🔹 Рекуррентные сети (RNN, LSTM)
│
│
→ Анализ последовательностей
│
│
│
│
🔹 Трансформеры (BERT, GPT)
│
│
→ Современный стандарт
│
│
→ ChatGPT, Claude, Gemini
│
│
│
│
Задачи, которые можно решать:
│
│
• Классификация текстов (спам/не спам)
│
• Генерация текста
│
│
• Машинный перевод
│
│
• Ответы на вопросы
│
│
• Суммаризация
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Направление 3: Графовые нейросети
text
┌─────────────────────────────────────────────────────────────────┐
│
ГРАФОВЫЕ НЕЙРОСЕТИ (GNN)
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Когда это нужно:
│
│
• Социальные сети (друзья, подписки)
│
│
• Молекулы (атомы и связи)
│
│
• Дорожные сети
│
│
• Рекомендательные системы
│
│
│
│
Основы:
│
🔹 Что такое граф (вершины, рёбра)
│
🔹 Матрица смежности
│
│
🔹 Лапласиан графа
│
│
🔹 GCN, GAT, GraphSAGE
│
│
│
│
│
│
Где применяется:
│
│
• Поиск новых лекарств (молекулы)
│
│
• Анализ социальных сетей
│
│
• Рекомендации товаров
│
│
│
└─────────────────────────────────────────────────────────────────┘
8.4. Практические советы: как учиться дальше
Совет 1: Делайте проекты, а не читайте теорию
text
┌─────────────────────────────────────────────────────────────────┐
│
ПРОЕКТЫ > ТЕОРИЯ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Плохо: "Я прочитаю ещё одну книгу по теории"
│
Хорошо: "Я сделаю проект, который распознаёт мои фото"
│
│
│
│
│
Лучший способ научиться — сделать что-то своими руками.
│
│
Идеи для проектов:
│
• Распознавание рукописных букв
│
│
• Классификация музыкальных жанров
│
│
• Определение породы собаки по фото
│
│
• Предсказание цены квартиры
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Совет 2: Используйте готовые модели (Transfer Learning)
text
┌─────────────────────────────────────────────────────────────────┐
│
TRANSFER LEARNING
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
Зачем учить нейросеть с нуля, если уже есть обученные?
│
│
│
│
Шаг 1: Берём предобученную модель (ResNet, VGG, EfficientNet)│
│
Шаг 2: Меняем последний слой под свою задачу
│
│
Шаг 3: Дообучаем на своих данных (10 минут)
│
│
│
│
Результат: 95%+ точности вместо 90%!
│
│
│
└─────────────────────────────────────────────────────────────────┘
Пример Transfer Learning на 3 строчки кода:
python
import torchvision.models as models
# Берём ResNet-18, обученный на миллионах картинок
model = models.resnet18(weights=models.ResNet18_Weights.IMAGENET1K_V1)
# Меняем последний слой: было 1000 классов → 2 (кот/собака)
model.fc = nn.Linear(512, 2)
# Дообучаем на своих данных (как в Главе 7)
8.5. Ресурсы для продолжения обучения
text
┌─────────────────────────────────────────────────────────────────┐
│
КУДА ИДТИ ДАЛЬШЕ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
📚 КНИГИ:
│
• "Глубокое обучение" (Гудфеллоу, Бенджио, Курвилль)
│
│
• "Python и машинное обучение" (Мюллер, Гвидо)
│
│
• "PyTorch для глубокого обучения" (Стивенс)
│
│
│
│
│
🎓 КУРСЫ (БЕСПЛАТНЫЕ):
│
│
• Fast.ai — практический курс
│
│
• CS231n (Stanford) — компьютерное зрение
│
• CS224n (Stanford) — NLP
│
• PyTorch Tutorials — официальные туториалы
│
│
│
│
│
│
💻 ПЛАТФОРМЫ:
│
• Kaggle — соревнования и датасеты
│
• Hugging Face — готовые модели
│
• Google Colab — бесплатный GPU
│
│
│
│
│
│
│
📺 YOUTUBE-КАНАЛЫ:
│
• Andrej Karpathy — нейросети с нуля
│
• Sentdex — практический PyTorch
│
│
│
│
• Two Minute Papers — новости из мира ИИ
│
│
│
└─────────────────────────────────────────────────────────────────┘
8.6. Часто задаваемые вопросы
text
┌─────────────────────────────────────────────────────────────────┐
│
FAQ НАЧИНАЮЩЕГО
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
❓ "Нужна ли мне математика?"
│
→ Для начала — нет. Но когда вы захотите понять,
│
почему модель работает, математика пригодится.
│
Однако 80% работы можно делать без глубокой математики.
│
│
│
│
│
│
│
❓ "Нужен ли мне мощный компьютер?"
│
→ Нет! Google Colab даёт бесплатный GPU.
│
Ваш обычный ноутбук тоже подойдёт для небольших моделей.
│
│
│
│
│
│
❓ "Сколько времени нужно, чтобы стать экспертом?"
│
→ 6-12 месяцев регулярной практики.
│
Но первые результаты вы увидите через неделю!
│
│
│
│
│
│
❓ "Где брать данные?"
│
│
→ Kaggle, Hugging Face, Google Dataset Search
│
│
Или собирайте свои данные (фото, тексты)
│
│
│
│
❓ "Что если моя модель не работает?"
│
→ Это нормально! 80% времени уходит на отладку.
│
Начните с простого: проверьте данные, уменьшите
│
learning rate, упростите модель.
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
8.7. Ваш план на ближайший месяц
text
┌─────────────────────────────────────────────────────────────────┐
│
ПЛАН НА 30 ДНЕЙ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
НЕДЕЛЯ 1: ЗАКРЕПЛЯЕМ ОСНОВЫ
│
│
┌─────────────────────────────────────────────────────────┐
│
│
│
□ Повторить все главы книги
│
│
□ Переписать все примеры кода заново
│
│
□ Сделать свой проект на MNIST
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
НЕДЕЛЯ 2: TRANSFER LEARNING
│
│
┌─────────────────────────────────────────────────────────┐
│
│
□ Изучить ResNet, VGG, EfficientNet
│
│
□ Применить к задаче (например, породы собак)
│
│
□ Попробовать разные предобученные модели
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
│
│
│
НЕДЕЛЯ 3: НОВАЯ ЗАДАЧА
│
│
┌─────────────────────────────────────────────────────────┐
│
│
□ Выбрать новый датасет (с Kaggle)
│
│
│
│
□ Применить CNN + Transfer Learning
│
│
│
│
□ Добиться точности >90%
│
│
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
НЕДЕЛЯ 4: УГЛУБЛЕНИЕ
│
│
┌─────────────────────────────────────────────────────────┐
│
│
□ Начать курс Fast.ai
│
│
□ Изучить одну современную архитектуру
│
│
□ Сделать проект, который вам интересен
│
└─────────────────────────────────────────────────────────┘
│
│
│
│
│
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
8.8. Финальное напутствие
text
┌─────────────────────────────────────────────────────────────────┐
│
│
│
│
│
★
★
★
★
★
★
★
★
│
│
│
ВЫ СДЕЛАЛИ НЕВОЗМОЖНОЕ!
│
│
│
│
│
★
★
★
★
★
★
★
★
│
│
│
│
│
│
Всего неделю назад вы не знали, как установить Python.
│
│
Сегодня у вас есть работающая нейросеть.
│
│
│
│
Запомните это чувство — когда код заработал, и вы
│
│
увидели, как модель распознаёт цифры. Это чувство
│
│
будет с вами всегда.
│
│
│
│
Дальше будет только интереснее. Вы научитесь генерировать
│
│
изображения, создавать чат-ботов, предсказывать будущее.
│
│
│
│
Главное — не останавливайтесь. Каждый день пишите код.
│
│
Каждый день делайте что-то новое.
│
│
│
│
Мир ИИ ждёт вас.
│
Удачи, создатель!
│
│
│
│
│
│
✦
│
✦
✦
│
│
│
│
"Код — это поэзия,
│
│
а нейросети — это магия, которую
│
│
вы теперь можете создавать."
│
│
│
│
│
└─────────────────────────────────────────────────────────────────┘
Приложение А: Шпаргалка по PyTorch
text
┌─────────────────────────────────────────────────────────────────┐
│
ШПАРГАЛКА ПО PYTORCH
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
🔹 СОЗДАНИЕ ТЕНЗОРОВ
│
├─────────────────────────────────────────────────────────────┤ │
│
│ torch.tensor([1, 2, 3])
→ из списка
│
│ torch.zeros(3, 4)
→ нули
│
│ torch.ones(2, 5)
→ единицы
│
│ torch.randn(3, 3)
→ случайные числа
│ │
│
│ torch.arange(10)
→ [0,1,2,...,9]
│ │
│
└─────────────────────────────────────────────────────────────┤ │
│
│ │
│ │
│ │
│
│
│
🔹 ОПЕРАЦИИ С ТЕНЗОРАМИ
│
│
├─────────────────────────────────────────────────────────────┤ │
│
│ a + b, a - b, a * b, a / b
│
│ a @ b
→ матричное умножение
│
│ a.reshape(3, 4)
→ изменение формы
│ │
│
│ a.view(-1, 784)
→ изменение формы
│ │
│
│ a.sum(), a.mean(), a.max()
→ агрегации
│ │
│
└─────────────────────────────────────────────────────────────┤ │
→ поэлементные операции
│ │
│ │
│
│
│
🔹 НЕЙРОСЕТИ
│
├─────────────────────────────────────────────────────────────┤ │
│
│ nn.Linear(in, out)
│
│ nn.Conv2d(in, out, kernel)
→ сверточный слой
│
│ nn.MaxPool2d(kernel)
→ пулинг
│
│ nn.ReLU()
→ функция активации
│
│ nn.Dropout(p)
→ регуляризация
│
│ nn.CrossEntropyLoss()
→ loss для классификации│ │
│
└─────────────────────────────────────────────────────────────┤ │
│
→ полносвязный слой
│ │
│ │
│ │
│ │
│ │
│
│
│
🔹 ОБУЧЕНИЕ
│
├─────────────────────────────────────────────────────────────┤ │
│
│ optimizer.zero_grad()
→ обнуляем градиенты
│ │
│
│ output = model(input)
→ прямой проход
│ │
│
│ loss = criterion(output, target) → ошибка
│
│ loss.backward()
→ обратный проход
│ │
│
│ optimizer.step()
→ шаг оптимизатора
│ │
│
└─────────────────────────────────────────────────────────────┤ │
│
│ │
│
│
│
🔹 ПРОВЕРКА МОДЕЛИ
│
├─────────────────────────────────────────────────────────────┤ │
│
│ model.eval()
→ режим инференса
│
│ with torch.no_grad():
→ не считать градиенты │ │
│
│ torch.max(output, 1)
→ найти максимум
│ │
│
│ torch.softmax(output, dim=1)
→ вероятности
│ │
│
└─────────────────────────────────────────────────────────────┤ │
│
│
│ │
│
└─────────────────────────────────────────────────────────────────┘
Приложение Б: Глоссарий
text
┌─────────────────────────────────────────────────────────────────┐
│
ГЛОССАРИЙ ТЕРМИНОВ
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
🔹 Тензор — просто таблица с числами
│
🔹 Вес — число, которое настраивается во время обучения
│
│
🔹 Эпоха — один полный проход по всем данным
│
│
🔹 Батч — группа примеров, обрабатываемых вместе
│
│
🔹 Функция активации — нелинейность (ReLU, Sigmoid)
│
│
🔹 Функция потерь (Loss) — показывает, насколько модель
│
│
│
ошибается
│
│
🔹 Оптимизатор — алгоритм, который настраивает веса
│
│
🔹 Градиент — направление, в котором нужно крутить веса
│
│
🔹 Переобучение — модель запомнила данные, но не умеет
│
│
обобщать
│
│
🔹 Свертка — скольжение маленького фильтра по картинке
│
🔹 Пулинг — уменьшение размера картинки
│
🔹 Dropout — случайное выключение нейронов для борьбы
│
│
│
│
с переобучением
│
│
🔹 Transfer Learning — использование готовой модели
│
│
🔹 Предобученная модель — модель, уже обученная на
│
│
больших данных
│
│
│
└─────────────────────────────────────────────────────────────────┘
Приложение В: Установка Google Colab
Если у вас нет мощного компьютера или вы не хотите ничего устанавливать:
text
┌─────────────────────────────────────────────────────────────────┐
│
GOOGLE COLAB — БЕСПЛАТНЫЙ GPU
│
├─────────────────────────────────────────────────────────────────┤
│
│
│
1. Зайдите на colab.research.google.com
│
│
2. Нажмите "Новый блокнот"
│
│
3. Выберите "Среда выполнения" → "Сменить тип" → "GPU"
│
4. Пишите код как в Jupyter!
│
│
│
│
│
Преимущества:
│
✅ Бесплатный GPU (ускоряет обучение в 10 раз!)
│
│
✅ Ничего не нужно устанавливать
│
│
✅ Работает в браузере
│
│
✅ Можно сохранять в Google Drive
│
│
│
│
│
Недостатки:
│
│
❌ Ограничение по времени (12 часов)
│
│
❌ Ограничение по памяти
│
│
❌ Нужен интернет
│
│
│
└─────────────────────────────────────────────────────────────────┘
Финальные слова автора
Дорогой читатель!
Если вы дочитали до этого места — вы не просто прочитали книгу. Вы сделали чтото гораздо более важное. Вы взяли и написали код. Вы увидели, как нейросеть
учится. Вы создали что-то, что работает.
Это и есть главный секрет. Не читать — а делать. Не смотреть — а создавать.
Теперь вы знаете, что нейросети — это не магия. Это инженерия. Это математика.
Это код. И всё это доступно каждому, кто готов потратить время и силы.
Я верю, что вы сможете пойти дальше. Сделаете свои проекты. Решите свои
задачи. Может быть, даже измените мир.
Помните:
text
┌─────────────────────────────────────────────────────────────────┐
│
│
│
│
"Единственный способ узнать, сможете ли вы
│
сделать что-то — это сделать это."
│
│
│
│
— Элеонора Рузвельт
│
│
│
│
│
│
│
"Код — это то, что я могу написать.
Всё остальное — это просто разговоры."
│
│
│
│
│
— Линус Торвальдс
│
│
│
│
│
│
✦
✦
✦
│
│
│
│
Спасибо, что прочитали.
│
│
Теперь — создавайте!
│
│
│
│
Ваш автор
│
│
│
└─────────────────────────────────────────────────────────────────┘
КОНЕЦ