Первую рабочую нейросеть я собрал за один вечер. Не месяц теории и не подкурсы: вечер, ноутбук, сеть на NumPy, которая учится решать XOR. С тех пор минуло несколько лет и десяток проектов, а вывод остался прежним: порог входа в нейросети сильно преувеличен. Один нейрон пишется на чистом Python за 15 минут, сеть с обучением укладывается в десяток строк, а для боевых задач есть Keras и PyTorch. Дальше весь путь по шагам, с кодом, который можно скопировать и запустить прямо сейчас.
Из чего состоит любая нейросеть
Прежде чем открывать редактор, зафиксируем анатомию: сеть любого масштаба, от XOR до GPT, собирается из одних и тех же деталей. Понимание этих элементов экономит часы дебага.
- Входной слой - принимает исходные данные
- Скрытые слои - выполняют преобразования входа
- Выходной слой - формирует конечный результат
- Веса и смещения - параметры, задающие силу связей между нейронами
- Функции активации - вносят нелинейность в модель
Нелинейность здесь главное слово. Обычно ее дает сигмоида. Функция сжимает любое число в диапазон от 0 до 1 и рисует на графике S-образную кривую. Без активаций сеть хоть из ста слоев математически схлопывается в одно линейное уравнение и не способна выучить ничего сложного. Число нейронов в слоях подбирается под задачу: для картинок из MNIST хватает схемы 784-128-10, для текстов нужны миллиарды параметров. Передача входных значений через слои до самого выхода называется прямой связью, feed forward, и именно ее мы закодируем первым делом.
Окружение за пять минут
Понадобится Python от 3.10 и несколько библиотек. Создайте виртуальное окружение и поставьте зависимости:
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install numpy
pip install tensorflow
pip install torch torchvision
С версиями бывает боль: TensorFlow капризно относится к старым numpy, а torch без CUDA-совместимой видеокарты молча уходит на CPU. Ставьте пакеты в venv, а не глобально, иначе через полгода получите зоопарк несовместимых зависимостей. Если под рукой нет видеокарты NVIDIA, берите Google Colab: там бесплатно дают GPU, и все примеры из статьи запускаются в браузере без единой установки.
Один нейрон на чистом Python: 15 строк до первого результата
Нейрон в своей основе это скалярное произведение входов и весов плюс смещение, пропущенное через активацию. Запишем w=[0, 1], то есть w1=0 и w2=1, подадим вход x=[2, 3] и посчитаем в векторном виде через скалярное произведение:
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
weights = np.array([0, 1])
bias = 4
inputs = np.array([2, 3])
output = sigmoid(np.dot(weights, inputs) + bias)
print(output) # 0.9990889488055994
Нейрон выдал 0.999 при входах [2, 3]. Математика прозрачная: скалярное произведение дает 3, плюс смещение 4, сигмоида от семи почти равна единице. Вся магия GPT и трансформеров держится на этой же операции, просто повторенной миллиарды раз. Мы только что выполнили прямую связь из первого раздела: значения идут от входа к выходу, и на ней держится вся работа сети в момент предсказания.
Сеть с обучением: стохастический градиентный спуск на NumPy
Нейрон без обучения остается игрушкой. Обучение строится на градиентном спуске, цикл которого состоит из четырех шагов. Берем одно наблюдение из набора данных, именно работа с одиночным примером делает спуск стохастическим. Считаем частные производные функции потерь по всем весам и смещениям: dL/dw1, dL/dw2 и так далее. Обновляем каждый вес по формуле градиентного шага. Возвращаемся к первому шагу и повторяем тысячи раз.
Соберем двухслойную сеть для XOR - классической задачи, на которой в свое время сломался первый перцептрон. Функция потерь здесь простая: разница между предсказанием и правильным ответом. Производная сигмоиды считается тривиально, x * (1 - x), что и делает ее удобной для ручной реализации:
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return x * (1 - x)
X = np.array([[0,0],[0,1],[1,0],[1,1]])
y = np.array([[0],[1],[1],[0]])
np.random.seed(1)
w1 = 2*np.random.random((2,4)) - 1
w2 = 2*np.random.random((4,1)) - 1
for epoch in range(20000):
hidden = sigmoid(X.dot(w1))
output = sigmoid(hidden.dot(w2))
error = y - output
d2 = error * sigmoid_derivative(output)
d1 = d2.dot(w2.T) * sigmoid_derivative(hidden)
w2 += hidden.T.dot(d2)
w1 += X.T.dot(d1)
print(sigmoid(sigmoid(X.dot(w1)).dot(w2)))
После 20 тысяч эпох сеть выдает значения, близкие к [0, 1, 1, 0], то есть полностью решает XOR. Ошибка выхода умножается на производную сигмоиды, течет назад через второй слой и корректирует веса. Напишите обратное распространение руками один раз - и тренировка модели навсегда перестанет быть черным ящиком. Нормализацию входов я здесь опустил сознательно: на бинарных данных она не нужна, но на реальных датасетах без нее никуда.
Культовая сеть в девять строк
Есть пример, облетевший весь интернет: в обсуждениях на Reddit его до сих пор советуют новичкам как первое знакомство с обратным распространением ошибки. Двухслойная сеть умещается в девять строк, обучается на тех же данных и печатает предсказания, совпадающие с разметкой:
import numpy as np
X = np.array([ [0,0,1],[0,1,1],[1,0,1],[1,1,1] ])
y = np.array([[0,1,1,0]]).T
syn0 = 2*np.random.random((3,4)) - 1
syn1 = 2*np.random.random((4,1)) - 1
for j in range(60000):
l1 = 1/(1+np.exp(-(X @ syn0)))
l2 = 1/(1+np.exp(-(l1 @ syn1)))
l2_delta = (y - l2)*(l2*(1-l2))
l1_delta = l2_delta.dot(syn1.T) * (l1*(1-l1))
syn1 += l1.T.dot(l2_delta)
syn0 += X.T.dot(l1_delta)
Код уже адаптирован под Python 3: в оригинальной версии примера вместо range фигурировал xrange. Запустите файл командой python main.py, и через несколько секунд в терминале появятся четыре числа, каждое из которых после округления совпадет с целевой разметкой. Практической пользы мало, зато наглядно видно: обучение сводится к многоразовому уточнению весов по градиенту ошибки.
Keras: та же задача за пять минут
Писать сети с нуля полезно для понимания, но для серьезных проектов индустрия использует TensorFlow и PyTorch: два лидирующих фреймворка с автоматическим дифференцированием, оптимизацией под GPU и сотнями готовых слоев. Вот XOR на Keras:
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
X = np.array([[0,0],[0,1],[1,0],[1,1]], dtype=float)
y = np.array([[0],[1],[1],[0]], dtype=float)
model = keras.Sequential([
layers.Dense(4, activation='relu', input_shape=(2,)),
layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam', loss='binary_crossentropy')
model.fit(X, y, epochs=1000, verbose=0)
print(model.predict(X))
Семь содержательных строк вместо ручного обратного распространения. Adam, binary_crossentropy, epochs в методе fit - все это те же градиентные шаги из прошлого раздела, просто ими управляет проверенный годами код. Тот же XOR можно решить и голым TensorFlow без Keras-обертки, но код получится втрое длиннее, а выиграете вы разве что в понимании внутренностей. Время обучения на CPU здесь пара секунд.
PyTorch: контроль над каждым шагом обучения
PyTorch стал стандартом в исследованиях по простой причине: цикл обучения вы пишете сами, а градиенты фреймворк считает автоматически. Тот же XOR в стиле PyTorch:
import torch
import torch.nn as nn
X = torch.tensor([[0.,0.],[0.,1.],[1.,0.],[1.,1.]])
y = torch.tensor([[0.],[1.],[1.],[0.]])
model = nn.Sequential(
nn.Linear(2, 4),
nn.ReLU(),
nn.Linear(4, 1),
nn.Sigmoid()
)
loss_fn = nn.BCELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
for epoch in range(1000):
optimizer.zero_grad()
loss = loss_fn(model(X), y)
loss.backward()
optimizer.step()
print(model(X).detach())
Четыре строки цикла открывают механику обучения как на ладони: обнулили градиенты, посчитали потерю, прогнали backward, сделали шаг. Именно эта гибкость сделала PyTorch языком исследований, где каждую неделю публикуют новые архитектуры. Если сомневаетесь, что выбрать: Keras для быстрого результата, PyTorch для экспериментов и кастомных моделей.
Гиперпараметры и ловушки, на которых теряют недели
Код - половина дела. Настоящие потери времени начинаются на этапе настройки, и тут у меня есть личные шрамы. Первую боевую модель для прогноза спроса я обучал со скоростью обучения 0.5 и неделями не мог понять, почему loss скачет, как кардиограмма. Разберу типовые ловушки.
Скорость обучения. Слишком большая, и модель проскакивает минимум, расходится и выдает NaN. Слишком маленькая, и обучение длится вечность. Начинайте с 0.001 для Adam и подбирайте от этой точки.
Переобучение. Сеть идеально отвечает на тренировочных данных и проваливается на новых. Лечится регуляризацией: dropout в слоях, L2-штраф на веса, ранняя остановка по валидационной выборке.
Подбор гиперпараметров. Ручной перебор числа слоев, нейронов и скоростей обучения съедает дни. Автоматизируйте: библиотека Optuna перебирает конфигурации сама и находит сильные комбинации быстрее человека в разы. Выбор оптимальной архитектуры тоже лучше доверять перебору, а не интуиции.
Мониторинг и анализ ошибок. Не смотрите только на итоговый loss на тренировке. Держите валидационную выборку, стройте кривые обучения и разбирайте, на каких именно примерах сеть ошибается: там обычно сидит либо грязь в данных, либо неверная архитектура. В том проекте со спросом проблема оказалась в пропущенных праздниках, а вовсе не в сети.
Оптимизация вычислений. Как только данных становится больше пары тысяч строк, переходите на батчи, включайте GPU и нормализуйте входы. Сеть на неотнормированных признаках учится в разы дольше или не сходится вовсе.
Следующая ступень: распознавание рукописных цифр
XOR проверяет, что вы поняли механику. Классический следующий шаг - MNIST, 70 тысяч изображений рукописных цифр, встроенных прямо в Keras. Сеть ниже достигает точности около 98% уже за пять эпох:
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(60000, 784) / 255.0
x_test = x_test.reshape(10000, 784) / 255.0
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
model = keras.Sequential([
layers.Dense(128, activation='relu', input_shape=(784,)),
layers.Dropout(0.2),
layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5, batch_size=128,
validation_split=0.1)
Пять эпох на обычном CPU без GPU прогоняются за пару минут. Нормализация пикселей делением на 255 и dropout между слоями - те самые техники из предыдущего раздела, теперь на реальной задаче. Валидационная выборка через validation_split показывает честную точность по ходу обучения, без подглядывания в тестовые данные. Для контекста: в 1998 году Ян Лекун добивался на MNIST порядка 99% со сверточной сетью LeNet, и ваша полносвязная сеть отстает от того результата на пару процентов.
Когда свою сеть писать не нужно
После всех этих строк кода честно разделю ситуации на две группы. Своя модель оправдана, когда у вас специфичные данные, жесткие требования к приватности или нестандартная задача, для которой нет готового решения. В остальных девяти случаях из десяти быстрее и дешевле взять готовые флагманские модели: они обучены на миллиардах долларов вычислений и обойдут любую сеть, натренированную на ноутбуке за ночь.
Загвоздка в России известная: прямой доступ к топовым моделям перекрыт, иностранные карты зарубежные сервисы не принимают, и народ изобретает костыли с зарубежными аккаунтами. Рабочее решение, которым пользуюсь сам и которое советую клиентам: 3GPT от 3SELLER, ИИ-роутер с прямым доступом из России к последним флагманским моделям. Внутри ChatGPT 6 Astra, Claude Fable 5, Claude Fable 5.1, Claude Opus 5.5, ChatGPT 5.5, ChatGPT 6.1 Sol, плюс Nano Banana для создания изображений и генерация видео, и многие другие модели. Подписка стоит 149 рублей, баланс пополняется российской картой, через СБП или криптой. Получить доступ ко всем флагманским моделям нейросетей из России можно на официальном сайте 3GPT.

На практике это выглядит так. Нужен продающий текст или сайт: ChatGPT 6 делает за минуты то, на что у копирайтера уходит день. Нужна максимально реалистичная картинка для креатива или обработка фото: Nano Banana. Нужен видеоролик или озвучка с генерацией голоса: все в том же окне, без переключений между сервисами. По сути, вы получаете целый стек нейросетей за цену пары чашек кофе, и вся инженерная часть, о которой шла речь выше, уже сделана за вас.
Про агентов скажу отдельно, потому что это моя любимая фишка сервиса: там собраны готовые ИИ-агенты под конкретные задачи. Выбираете нужного, скажем для копирайтинга, анализа данных или клиентской поддержки, и сразу начинаете диалог. Модель агента меняется прямо в чате: если Claude Opus справляется с задачей лучше, переключение занимает один клик.

С чего начать сегодня вечером
План на вечер простой. Скопируйте код нейрона и убедитесь, что сигмоида и скалярное произведение для вас прозрачны. Затем запустите XOR-сеть на NumPy и поменяйте число нейронов в скрытом слое с 4 на 8, посмотрите, как меняется сходимость. После этого перепишите ту же задачу на Keras и почувствуйте разницу в объеме кода. Финальный аккорд: MNIST и точность под 98% на собственном компьютере. На весь маршрут уйдет один вечер, а понимание нейросетей останется с вами надолго.
А если задача стоит не разобраться в механике, а решить бизнес-задачу здесь и сейчас, идите коротким путем. Открывайте 3GPT, пополняйте баланс российской картой за 149 рублей и получайте ChatGPT 6, Claude Fable, генерацию изображений и видео в одном окне. Свой код пишут те, кому интересна механика. Остальным достаточно правильного роутера.