Первое обучение — перцептрон на NumPy
Первое обучение — перцептрон на NumPy
Эта статья — короткий практический мост между теорией из Нейрон и полноценным машинным обучением. Здесь один выходной нейрон с сигмоидой учится отличать два класса по четырём бинарным признакам (как упрощённые «черты» цифры 0 и 1).
Интерактивная схема прохождения сигнала — в статье про нейрон (NeuralNetworkDemo). Здесь — полный цикл обучения в ~40 строках кода.
Задача
Есть восемь обучающих примеров. У каждого четыре входа (0 или 1) и целевой ответ:
- 0 — «похоже на ноль» (четыре шаблона);
- 1 — «похоже на единицу» (четыре шаблона).
Сеть должна выдать число близко к 0 или близко к 1, а не жёсткий порог с первого раза.
Сигмоида
Сигмоида сжимает любую сумму входов в диапазон от 0 до 1 — удобно для вероятности класса «1»:
import numpy as np
def nonlin(x, deriv=False):
"""Сигмоида; deriv=True — производная для обратного прохода."""
if deriv:
return x * (1 - x)
return 1 / (1 + np.exp(-x))
Данные и матрица весов syn0
Входы складываем в матрицу X (8 строк × 4 столбца). Ответы — столбец y. Матрица syn0 размером 4×1 хранит веса связей «признак → нейрон»; в начале — случайные маленькие значения:
# Признаки (4 бита) и целевой класс — 0 или 1
X = np.array(
[
[0, 0, 1, 0],
[0, 1, 0, 1],
[1, 0, 0, 1],
[0, 1, 1, 0],
[1, 1, 1, 0],
[1, 0, 1, 1],
[1, 1, 0, 1],
[1, 1, 1, 1],
],
dtype=float,
)
y = np.array([[0, 0, 0, 0, 1, 1, 1, 1]], dtype=float).T
np.random.seed(1)
syn0 = 2 * np.random.random((4, 1)) - 1
Цикл обучения
На каждой итерации:
- Прямой проход — считаем выход
l1 = σ(X · syn0). - Ошибка —
y - l1. - Поправка весов — пропорциональна ошибке и производной сигмоиды (упрощённый обратный проход для одного слоя).
for _ in range(10_000):
l0 = X
l1 = nonlin(np.dot(l0, syn0))
l1_error = y - l1
l1_delta = l1_error * nonlin(l1, deriv=True)
syn0 += np.dot(l0.T, l1_delta)
После обучения ответы на тех же примерах выглядят примерно так (не ровно 0 и 1 — это нормально для сигмоиды):
[0.02, 0.01, 0.99, 0.01, 0.99, 0.99, 0.99, 0.98]
Больше итераций — выше точность
При 100 000 итерациях значения ещё ближе к 0 и 1 (например, 0.005 вместо 0.02 для класса «ноль»). Закономерность: чем дольше учим на одних и тех же данных, тем меньше ошибка — пока не начнётся переобучение на сложных задачах.
Проверка на новых данных
Подставляем векторы, которых не было в обучении:
def predict(features, weights):
return nonlin(np.dot(np.array(features, dtype=float), weights)).item()
# Похож на обучающий «ноль»
print(predict([0, 1, 0, 1], syn0)) # ~0.01
# Похож на обучающую «единицу»
print(predict([1, 1, 1, 1], syn0)) # ~0.98
# Чужой шаблон — сеть «не уверена»
print(predict([0, 0, 0, 0], syn0)) # ~0.50
Знакомый шаблон даёт уверенный ответ около 0 или 1. Абстрактный [0, 0, 0, 0] попадает между классами — выход около 0.5: модель не видела таких примеров и не должна выдавать жёсткую классификацию. В продакшене такие случаи отправляют на проверку человеку или помечают как «низкая уверенность».
Полный скрипт
Скопируйте в файл perceptron_demo.py и запустите (pip install numpy):
import numpy as np
def nonlin(x, deriv=False):
if deriv:
return x * (1 - x)
return 1 / (1 + np.exp(-x))
X = np.array(
[
[0, 0, 1, 0],
[0, 1, 0, 1],
[1, 0, 0, 1],
[0, 1, 1, 0],
[1, 1, 1, 0],
[1, 0, 1, 1],
[1, 1, 0, 1],
[1, 1, 1, 1],
],
dtype=float,
)
y = np.array([[0, 0, 0, 0, 1, 1, 1, 1]], dtype=float).T
ITERATIONS = 10_000
np.random.seed(1)
syn0 = 2 * np.random.random((4, 1)) - 1
for _ in range(ITERATIONS):
l1 = nonlin(X.dot(syn0))
syn0 += X.T.dot((y - l1) * nonlin(l1, deriv=True))
print("После обучения на X:")
print(np.round(nonlin(X.dot(syn0)).flatten(), 4))
for label, vec in [
("похож на 0", [0, 1, 0, 1]),
("похож на 1", [1, 1, 1, 1]),
("чужой", [0, 0, 0, 0]),
]:
print(label, np.round(nonlin(np.dot(vec, syn0)).item(), 4))
Что дальше
| Шаг | Куда идти |
|---|---|
| Несколько слоёв, ReLU, свёртки | Нейрон, Основные концепции ИИ |
| Датасеты, метрики, sklearn | Машинное обучение |
| Откуда взялся термин ИИ и маркетинг | Что такое ИИ на самом деле |
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). Нейрон — это основная функциональная единица биологической нервной системы, включая человеческий мозг. Что есть искусственный интеллект, вайб-кодинг, нейросеть. Деревья решений, линейная регрессия, нейронные сети, генеративные модели — это всё примеры ИИ-моделей. Рекуррентность — это свойство моделей сохранять информацию о предыдущих шагах обработки данных. Итоги раздела Нейросети — вопросы для самопроверки в энциклопедии Вселенная IT.Нейрон
Нейросети и их связь с ИИ
Принцип работы современных ИИ-систем
Архитектуры нейронных сетей
Чек-лист самопроверки