跳到主要内容

神经网络基础

从感知机到多层神经网络,理解深度学习的基础组件。

感知机

神经网络的基本单元。接收多个输入,加权求和后通过激活函数输出:

y=f(i=1nwixi+b)y = f\left(\sum_{i=1}^{n} w_i x_i + b\right)
import numpy as np

def perceptron(x, w, b):
"""单个感知机"""
z = np.dot(w, x) + b
return 1 if z >= 0 else 0 # 阶跃激活函数

单个感知机只能解决线性可分问题(如 AND、OR),无法处理 XOR。多层感知机解决了这个问题。

多层感知机(MLP)

输入层 → 隐藏层 → 输出层,层间全连接:

class SimpleMLP:
def __init__(self, layer_sizes):
"""
layer_sizes: [输入维度, 隐藏层1维度, ..., 输出维度]
例: [784, 128, 64, 10] — MNIST 的三层网络
"""
self.weights = []
self.biases = []
for i in range(len(layer_sizes) - 1):
# He 初始化(ReLU 的最佳伙伴)
self.weights.append(
np.random.randn(layer_sizes[i], layer_sizes[i+1]) *
np.sqrt(2.0 / layer_sizes[i])
)
self.biases.append(np.zeros((1, layer_sizes[i+1])))

def forward(self, X):
"""前向传播"""
self.z = [] # 激活前的值(反向传播需要)
self.a = [X] # 各层激活后的值
for W, b in zip(self.weights[:-1], self.biases[:-1]):
self.z.append(self.a[-1] @ W + b)
self.a.append(self.relu(self.z[-1])) # 隐藏层用 ReLU
# 输出层
self.z.append(self.a[-1] @ self.weights[-1] + self.biases[-1])
self.a.append(self.softmax(self.z[-1]))
return self.a[-1]

def relu(self, x):
return np.maximum(0, x)

def softmax(self, x):
exp_x = np.exp(x - x.max(axis=1, keepdims=True)) # 数值稳定
return exp_x / exp_x.sum(axis=1, keepdims=True)

激活函数

没有激活函数,多层网络等价于单层线性模型。

函数公式特点
Sigmoid11+ex\frac{1}{1+e^{-x}}输出 (0,1),两端梯度消失
Tanhexexex+ex\frac{e^x - e^{-x}}{e^x + e^{-x}}输出 (-1,1),零中心
ReLUmax(0,x)\max(0, x)计算快,缓解梯度消失,首选
Leaky ReLUmax(0.01x,x)\max(0.01x, x)解决 ReLU 的「神经元死亡」问题
GELUxΦ(x)x \cdot \Phi(x)Transformer 标配
def relu(x):
return np.maximum(0, x)

def leaky_relu(x, alpha=0.01):
return np.where(x > 0, x, alpha * x)

def sigmoid(x):
return 1 / (1 + np.exp(-np.clip(x, -500, 500)))

损失函数

任务损失函数公式
二分类二元交叉熵1n[ylogy^+(1y)log(1y^)]-\frac{1}{n}\sum[y\log\hat{y} + (1-y)\log(1-\hat{y})]
多分类交叉熵1nyclogy^c-\frac{1}{n}\sum\sum y_c \log \hat{y}_c
回归MSE1n(yy^)2\frac{1}{n}\sum(y - \hat{y})^2

反向传播

反向传播的本质是用链式法则从输出层往输入层逐层计算梯度:

def relu_derivative(x):
return (x > 0).astype(float)

def backward(self, X, y, y_pred):
n = len(X)
grads_w = []
grads_b = []

# 输出层梯度: dL/dz = y_pred - y (交叉熵 + softmax 的简洁结果)
delta = y_pred - y

for i in reversed(range(len(self.weights))):
# dL/dW = a.T @ delta / n
grads_w.insert(0, self.a[i].T @ delta / n)
grads_b.insert(0, delta.sum(axis=0, keepdims=True) / n)

if i > 0:
# 链式法则:delta = (delta @ W.T) * relu'(z)
delta = (delta @ self.weights[i].T) * relu_derivative(self.z[i-1])

return grads_w, grads_b

优化器

SGD

# 最基础的优化器
w = w - lr * grad

SGD + Momentum

# 动量累积历史梯度方向,加速收敛
v = momentum * v - lr * grad
w = w + v

Adam(推荐默认使用)

# 结合动量 + 自适应学习率
# PyTorch 中:
# optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

PyTorch 完整示例

import torch
import torch.nn as nn

class SimpleNN(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super().__init__()
self.net = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, output_dim),
)

def forward(self, x):
return self.net(x)

# 训练循环
model = SimpleNN(784, 128, 10)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

for epoch in range(10):
for X_batch, y_batch in train_loader:
optimizer.zero_grad()
y_pred = model(X_batch)
loss = criterion(y_pred, y_batch)
loss.backward()
optimizer.step()

归一化层

类型作用维度使用场景
BatchNorm一个 batch 内归一化CNN 标配
LayerNorm一个样本内归一化Transformer 标配
Dropout随机丢弃神经元正则化、防止过拟合

正则化

防止过拟合的常用技巧:

# Dropout
nn.Dropout(p=0.5) # 训练时随机丢失 50% 神经元

# 权重衰减(L2 正则化)
torch.optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)

# Early Stopping — 验证损失不再下降时停止训练
# BatchNorm 自带轻微正则化效果

总结

特性说明
要点激活函数、损失函数、梯度下降、反向传播是四大核心
实践ReLU + Adam + BatchNorm + Dropout 是标准组合
进阶理解梯度流(Gradient Flow)是调试深度学习的关键