共计 2541 个字符,预计需要花费 7 分钟才能阅读完成。
人工神经元:神经网络的基础构建块
人工神经元是神经网络的基本单元,其数学模型模仿了生物神经元的工作原理。一个典型的人工神经元包含三个主要部分:

- 输入:接收来自其他神经元或外部环境的信号(x₁, x₂, …, xn)
- 权重:每个输入都有一个对应的权重(w₁, w₂, …, wn),表示该输入的重要性
- 激活函数:对加权和进行非线性变换的函数(如 Sigmoid、ReLU 等)
数学表达式为:
z = w₁x₁ + w₂x₂ + ... + wnxn + b
a = f(z)
其中 b 是偏置项,f 是激活函数。
前向传播:信息流动的方向
前向传播是神经网络进行预测的核心过程,其步骤可以概括为:
- 输入数据通过输入层进入网络
- 每一层的神经元计算加权和并应用激活函数
- 结果传递到下一层,直到输出层产生最终预测
以一个简单的 3 层网络(输入层、隐藏层、输出层)为例:
- 输入层到隐藏层:
z^[1] = W^[1]X + b^[1] a^[1] = f^[1](z^[1]) - 隐藏层到输出层:
z^[2] = W^[2]a^[1] + b^[2] a^[2] = f^[2](z^[2])
反向传播算法:神经网络的学习引擎
反向传播(Backpropagation,简称 BP)是神经网络训练的核心算法,其目的是通过调整权重来最小化损失函数。BP 算法可以分为四个主要步骤:
- 前向传播 计算预测值和损失
- 计算输出层误差:
δ^[L] = ∂L/∂a^[L] ⊙ f'^[L](z^[L]) - 反向传播误差 到各层:
δ^[l] = (W^[l+1]T δ^[l+1]) ⊙ f'^[l](z^[l]) - 计算梯度并更新参数:
∂L/∂W^[l] = δ^[l] a^[l-1]T ∂L/∂b^[l] = δ^[l] W^[l] = W^[l] - α ∂L/∂W^[l] b^[l] = b^[l] - α ∂L/∂b^[l]
Python 实现:从零搭建神经网络
下面是一个简单的全连接神经网络的 Python 实现:
import numpy as np
class NeuralNetwork:
def __init__(self, layer_sizes):
self.weights = [np.random.randn(y, x) * 0.1
for x, y in zip(layer_sizes[:-1], layer_sizes[1:])]
self.biases = [np.zeros((y, 1)) for y in layer_sizes[1:]]
def forward(self, x):
a = x
for w, b in zip(self.weights, self.biases):
z = np.dot(w, a) + b
a = self.sigmoid(z)
return a
def backward(self, x, y):
# 前向传播
activations = [x]
zs = []
for w, b in zip(self.weights, self.biases):
z = np.dot(w, activations[-1]) + b
zs.append(z)
activations.append(self.sigmoid(z))
# 反向传播
delta = (activations[-1] - y) * self.sigmoid_prime(zs[-1])
nabla_w = [np.zeros(w.shape) for w in self.weights]
nabla_b = [np.zeros(b.shape) for b in self.biases]
nabla_w[-1] = np.dot(delta, activations[-2].T)
nabla_b[-1] = delta
for l in range(2, len(self.weights)+1):
z = zs[-l]
sp = self.sigmoid_prime(z)
delta = np.dot(self.weights[-l+1].T, delta) * sp
nabla_w[-l] = np.dot(delta, activations[-l-1].T)
nabla_b[-l] = delta
return nabla_w, nabla_b
def sigmoid(self, z):
return 1.0/(1.0 + np.exp(-z))
def sigmoid_prime(self, z):
return self.sigmoid(z) * (1 - self.sigmoid(z))
激活函数对比与选择
常见的激活函数包括:
- Sigmoid:
- 优点:输出在 (0,1) 之间,适合二分类问题
- 缺点:容易出现梯度消失,计算成本高
-
公式:σ(z) = 1/(1 + e^-z)
-
ReLU(Rectified Linear Unit):
- 优点:计算简单,缓解梯度消失
- 缺点:可能出现神经元 ” 死亡 ” 问题
-
公式:ReLU(z) = max(0, z)
-
Tanh:
- 优点:输出在 (-1,1) 之间,中心对称
- 缺点:同样存在梯度消失问题
-
公式:tanh(z) = (e^z – e^-z)/(e^z + e^-z)
-
Leaky ReLU:
- 优点:解决了 ReLU 的神经元死亡问题
- 缺点:需要调参
- 公式:LReLU(z) = max(αz, z),通常 α =0.01
优化算法选择策略
- 随机梯度下降(SGD):
- 最简单的优化方法
- 容易陷入局部最优
-
学习率需要仔细调整
-
动量法(Momentum):
- 引入速度概念,加速收敛
- 减少震荡
-
公式:v = γv + η∇J(θ)
θ = θ – v -
Adam:
- 结合了动量法和 RMSProp
- 自适应学习率
- 实践中表现优异
生产环境注意事项
- 梯度消失 / 爆炸:
- 使用 ReLU 等激活函数
- 实施梯度裁剪(gradient clipping)
-
使用批归一化(Batch Normalization)
-
过拟合:
- 使用 L1/L2 正则化
- 实施 Dropout
-
增加训练数据
-
学习率调优:
- 使用学习率衰减
- 实施学习率预热
- 考虑使用周期性学习率
思考题
- 如何修改我们的神经网络实现来支持多种不同的激活函数?
- 除了均方误差和交叉熵,还有哪些损失函数适合神经网络?它们各有什么特点?
- 批处理(batch processing)对神经网络训练有什么影响?如何选择合适的 batch size?
总结
本文从人工神经元的基本原理出发,详细讲解了神经网络的前向传播和反向传播算法,并提供了完整的 Python 实现。我们还比较了不同激活函数和优化算法的特点,并讨论了生产环境中需要注意的问题。神经网络虽然强大,但也需要仔细调参和优化才能发挥最佳性能。希望这篇文章能帮助你更好地理解和应用神经网络技术。
正文完
发表至: 未分类
近两天内
