深度学习入门【神经网络基本理论】前言经过前面的实战我们已经掌握了线性回归和逻辑回归。逻辑回归靠着 Sigmoid 函数和人为构造的高次特征比如把 (x) 手动变成 (x^2, x^3)确实能画出一条弯曲的决策边界来“勉强”对付一些非线性数据。但是这种方法有一个致命缺陷它依赖“人工特征工程”。如果我们要识别的是几千张像素极多、极其复杂的图片比如区分猫和狗我们根本没有办法靠人脑去想出“应该加什么复杂的高阶特征”才能把它分开。于是我们引入了神经网络。神经网络并不会改变“梯度下降更新权重”的底层逻辑。它的革命性在于它把“特征提取”和“画决策边界”这两件事全部交给了机器自己。通过隐藏层的“激活函数”机器能够自动把原始数据弯折、扭曲组合出极其复杂的形状。本文将不依赖任何深度学习框架从零开始推导一个包含“单隐藏层”的神经网络彻底揭示**“它是如何自动把直线变弯曲”**的数学原理。一、神经网络的结构组成1.1 神经元模型神经网络的基本单元是“神经元”。一个标准的神经元运算分为两步线性加权求和Z W * X b非线性激活A g(Z)常用的激活函数有以下几种它们的特性、优缺点及适用场景对比如下激活函数公式输出范围优点缺点适用场景Sigmoidσ(x) 1 / (1 e^{-x})(0, 1)输出可解释为概率处处可导容易梯度消失输出非零均值收敛慢二分类输出层tanhtanh(x) (e^x - e^{-x}) / (e^x e^{-x})(-1, 1)零均值输出收敛更快形状与 Sigmoid 类似仍存在梯度消失问题隐藏层浅层网络适用ReLUReLU(x) max(0, x)[0, ∞)计算极快有效缓解梯度消失稀疏激活x 0 时梯度为 0可能导致神经元“死亡”隐藏层现代深层网络首选1.2 单隐藏层网络架构本文推导的网络由输入层、隐藏层1层和输出层组成。我们定义以下符号X输入矩阵特征数 n_x样本数 m。维度(n_x, m)y真实标签二分类任务维度 1 * m。(W[1], b[1])输入层到隐藏层的权重和偏置。W[1] 维度(n_h, n_x)b[1] 维度(n_h, 1)(W[2], b[2])隐藏层到输出层的权重和偏置。W[2] 维度(1, n_h)b[2] 维度(1, 1)n_h隐藏层神经元的数量这是一个超参数。二、前向传播前向传播是指数据从输入层经过层层计算最终得出预测值的过程。2.1 隐藏层计算提取特征首先我们将输入 X 传递给隐藏层进行线性变换Z[1] W[1] * X b[1]此时得到的 Z[1] 是一条“绝对笔直的线”。为了让它能够弯曲我们必须引入激活函数Activation Function。这里我们选用 tanh 函数A[1] tanh(Z[1])为什么隐藏层必须要有激活函数如果没有激活函数即 A[1] Z[1]那么数学上经过两层推导神经网络最终会变成A[2] (W[2] * W[1]) * X (W[2] * b[1] b[2])这依然是一个单纯的线性方程。无论你叠加多少层没有激活函数神经网络就等价于一个线性回归模型绝对无法处理非线性问题。2.2 输出层计算得出概率隐藏层提取的特征 A[1] 被传递给输出层Z[2] W[2] * A[1] b[2]因为我们完成的是二分类任务输出 0 或 1所以输出层需要使用Sigmoid函数将结果压缩到 0 到 1 之间A[2] sigma(Z[2])2.3 计算损失Cost Function神经网络衡量预测误差的方法依然是对数损失函数交叉熵J - (1/m) * sum( y * log(A[2]) (1-y) * log(1-A[2]) )目标就是通过优化让这个 J 的值最小。三、反向传播如果说前向传播是“做预测”那么反向传播Backpropagation就是“找原因”。反向传播的核心逻辑是链式法则Chain Rule。它把输出层的计算误差像倒放一样一层一层回传给前面的权重告诉模型“为了降低误差你应该往哪个方向修改 W 和 b”。3.1 输出层的梯度计算我们先计算损失函数对输出层线性输出 Z[2] 的偏导dZ[2] A[2] - y这是数学推导中一个极其优雅的简化结果等于“预测值减去真实值”。由此可以推导出 W[2] 和 b[2] 的更新梯度dW[2] (1/m) * dZ[2] * (A[1])^Tdb[2] (1/m) * sum(dZ[2])3.2 隐藏层的梯度计算误差回传隐藏层的神经元无法直接接触真实标签它怎么知道自己的权重该不该改答案是它将输出层传回来的误差“分享”给自己。从输出层反向传回的误差为dA[1] (W[2])^T * dZ[2]接下来误差要穿过隐藏层的激活函数。由于激活函数是 tanh其导数为 1 - tanh(z)^2所以隐藏层最终的误差项为dZ[1] dA[1] * (1 - (A[1])^2)最后求出隐藏层参数的梯度dW[1] (1/m) * dZ[1] * X^Tdb[1] (1/m) * sum(dZ[1])四、参数更新求出了每一层的梯度后我们使用和逻辑回归完全一样的梯度下降公式来更新参数W[2] W[2] - alpha * dW[2]b[2] b[2] - alpha * db[2]W[1] W[1] - alpha * dW[1]b[1] b[1] - alpha * db[1]其中 alpha 是学习率步长。重复执行前向传播 - 反向传播 - 梯度下降的过程直到损失函数不再下降模型就训练好了。总结通过这次数学推导我们可以得出神经网络的四个核心真相1. 激活函数是“非线性的灵魂”如果没有tanh、ReLU或Sigmoid这类激活函数无论你的神经网络叠加多少层它在数学上都等价于一个简单的线性回归永远无法弯折出曲线也永远无法处理现实世界复杂的数据。2. 前向传播是做“特征变形”数据在隐藏层中经过加权求和与非线性激活被不断折叠、扭曲从原本难以区分的原始像素或特征变成能被输出层轻松切分的高维形态。3. 反向传播是做“误差调查”反向传播的数学根基是链式法则。它把输出层的误差顺着连接权重一层一层倒传回输入层精确告诉每一个神经元“为了降低总误差你的参数该往哪个方向调整”。4. 梯度下降是做“参数修复”拿着反向传播查出的梯度方向乘以学习率更新所有权重和偏置。只有完成这一步神经网络才算真正完成了一次有效学习。深度学习框架没有魔法。PyTorch 和 TensorFlow 等工具只不过是用极其高效的矩阵运算替我们自动完成了上述繁琐的求导和更新过程。只要理解了今天的四大核心真相我们就掌握了所有深度网络CNN、RNN、Transformer最底层的数学基因。附录极简核心代码如果上面的推导让你觉得有点抽象不用担心。下面这段极简的 Numpy 代码把这个神经网络的“一次训练轮回”原汁原味地还原了出来。后面我们将逐步走进实战。importnumpyasnp# 1. 随机初始化不能全为0W1np.random.randn(n_h,n_x)*0.01b1np.zeros((n_h,1))W2np.random.randn(n_y,n_h)*0.01b2np.zeros((n_y,1))# 2. 开始迭代训练foriinrange(iterations):# 前向传播 Z1np.dot(W1,X)b1 A1np.tanh(Z1)# 隐藏层激活Z2np.dot(W2,A1)b2 A21/(1np.exp(-Z2))# 输出层激活Sigmoid# 计算损失 loss-(1/m)*np.sum(y*np.log(A2)(1-y)*np.log(1-A2))# 反向传播 dZ2A2-y# 输出层误差dW2(1/m)*np.dot(dZ2,A1.T)db2(1/m)*np.sum(dZ2,axis1,keepdimsTrue)dA1np.dot(W2.T,dZ2)# 误差传回隐藏层dZ1dA1*(1-np.power(A1,2))# tanh 的导数dW1(1/m)*np.dot(dZ1,X.T)db1(1/m)*np.sum(dZ1,axis1,keepdimsTrue)# 梯度下降更新参数 W1W1-alpha*dW1 b1b1-alpha*db1 W2W2-alpha*dW2 b2b2-alpha*db2