Полный forward pass на маленькой сети
Урок соединяет слои в полный проход: от входа до итогового выхода сети.
Forward pass — это запуск сети «как есть»: с текущими (пусть даже случайными) весами посчитать, что она выдаёт на данном входе.
Что мы собираем
Возьмём сеть 2 → 3 → 1: два входа, скрытый слой из трёх нейронов с sigmoid, один выходной нейрон с sigmoid. Веса зададим вручную фиксированными числами, чтобы вывод был воспроизводимым. Наша задача — аккуратно прогнать вход через оба слоя и посмотреть на результат.
Считаем проход целиком
import math
def sigmoid(x):
return 1.0 / (1.0 + math.exp(-x))
# Скрытый слой: 3 нейрона, у каждого 2 веса
W1 = [[0.5, -0.3],
[0.8, 0.2],
[-0.4, 0.7]]
b1 = [0.1, -0.2, 0.05]
# Выходной слой: 1 нейрон с 3 входами
W2 = [0.6, -0.9, 0.4]
b2 = -0.1
def forward(x):
# скрытый слой
h = []
for j in range(3):
s = W1[j][0]*x[0] + W1[j][1]*x[1] + b1[j]
h.append(sigmoid(s))
# выходной слой
s_out = W2[0]*h[0] + W2[1]*h[1] + W2[2]*h[2] + b2
out = sigmoid(s_out)
return h, out
x = [1.0, 2.0]
h, out = forward(x)
print("Вход:", x)
print("Скрытый слой:", [round(v, 3) for v in h])
print("Выход сети:", round(out, 4))
Вывод:
Вход: [1.0, 2.0] Скрытый слой: [0.5, 0.731, 0.741] Выход сети: 0.4597
Что произошло по шагам
- Каждый из трёх скрытых нейронов взял оба входа, посчитал свою взвешенную сумму и пропустил её через sigmoid. Получили три числа — активации скрытого слоя.
- Выходной нейрон взял эти три числа как свой вход, посчитал взвешенную сумму и снова применил sigmoid.
- Итог — одно число 0.4597. Поскольку веса случайные (мы их не обучали), это пока бессмысленное предсказание.
Важная мысль: forward pass всегда работает одинаково, обучена сеть или нет. Обучение лишь подбирает удачные веса, но сама процедура прогона неизменна. Когда обученная нейросеть отвечает на ваш запрос — внутри происходит ровно такой forward pass, только из миллионов чисел.
Полезно отделять два режима. Обучение (training): forward pass + вычисление потери + обратный проход + шаг спуска; здесь обязательно хранить активации. Инференс (inference, предсказание): только forward pass — активации хранить не нужно, и потому он быстрее и легче по памяти. Именно инференс работает, когда модель уже обучена и просто отвечает пользователю. Многие приёмы (например, dropout) включаются на обучении и выключаются на инференсе — поэтому в реальных фреймворках сеть явно переключают между режимами train и eval.
Сохраняем промежуточные значения
Обратите внимание: функция возвращает не только выход, но и активации скрытого слоя h. Это не каприз — при обучении (обратное распространение) нам понадобятся все промежуточные значения. Поэтому forward pass перед обучением всегда «запоминает» активации каждого слоя.
Итог
- Forward pass — последовательный прогон входа через все слои.
- Выход одного слоя — вход следующего.
- Промежуточные активации сохраняют для последующего backprop.