
1. 神经网络基础概念回顾在正式进入浅层神经网络的具体内容之前我们需要先明确几个核心概念。神经网络本质上是一种模仿生物神经网络结构和功能的数学模型由大量相互连接的节点或称神经元组成。每个神经元接收输入信号经过加权求和后通过激活函数产生输出。第三周课程中提到的浅层神经网络通常指的是仅包含一个隐藏层的网络结构。这种网络虽然结构简单但已经能够解决许多非线性分类问题。与后续要学习的深层网络相比浅层网络的计算复杂度更低训练速度更快是初学者理解神经网络工作原理的理想切入点。提示虽然称为浅层但单隐藏层网络理论上已经能够以任意精度逼近任何连续函数通用逼近定理关键在于隐藏层神经元的数量。2. 浅层神经网络的结构解析2.1 网络层级组成一个典型的浅层神经网络包含三层输入层Input layer接收原始数据特征隐藏层Hidden layer进行特征变换和非线性映射输出层Output layer产生最终预测结果以二分类问题为例假设我们有nx个输入特征隐藏层有n[1]个神经元那么各层的维度为输入层nx隐藏层n[1]输出层1二分类输出一个0-1之间的概率值2.2 参数矩阵的维度分析理解参数矩阵的维度对于正确实现神经网络至关重要。对于上述网络结构W[1]隐藏层权重矩阵维度为(n[1], nx)b[1]隐藏层偏置向量维度为(n[1], 1)W[2]输出层权重矩阵维度为(1, n[1])b[2]输出层偏置标量维度为(1, 1)在实际编程实现时务必检查这些矩阵的维度是否正确这是避免许多错误的第一个检查点。3. 前向传播的数学原理与实现3.1 单样本前向传播公式对于单个样本x维度nx×1前向传播的计算步骤如下隐藏层计算 z[1] W[1]x b[1] a[1] g 1输出层计算 z[2] W[2]a[1] b[2] a[2] g 2其中g[1]和g[2]分别是隐藏层和输出层的激活函数。常见的组合是隐藏层使用ReLU或tanh输出层使用sigmoid二分类问题。3.2 多样本向量化实现在实际应用中我们通常同时处理多个样本m个以提高计算效率。这时需要将上述计算向量化将m个样本按列堆叠成矩阵X维度nx×m隐藏层计算 Z[1] W[1]X b[1] A[1] g 1输出层计算 Z[2] W[2]A[1] b[2] A[2] g 2注意这里的b[1]和b[2]会通过python的广播机制自动扩展到所有样本这是NumPy的一个便利特性。4. 激活函数的选择与比较4.1 常用激活函数及其导数Sigmoid函数 σ(z) 1/(1e^-z) σ(z) σ(z)(1-σ(z))适用于输出层二分类问题但隐藏层中容易导致梯度消失。tanh函数 tanh(z) (e^z - e^-z)/(e^z e^-z) tanh(z) 1 - tanh²(z)通常比sigmoid表现更好因为输出以0为中心。ReLU函数 ReLU(z) max(0,z) ReLU(z) 1 if z0 else 0目前最常用的隐藏层激活函数计算简单且能缓解梯度消失问题。4.2 激活函数选择建议输出层二分类sigmoid回归问题线性无激活或ReLU输出非负时隐藏层首选ReLU计算高效且梯度保持良好次选tanh某些特定场景可能表现更好避免使用sigmoid梯度消失问题严重5. 反向传播算法详解5.1 损失函数计算对于二分类问题常用交叉熵损失函数 L(ŷ,y) -[ylog(ŷ) (1-y)log(1-ŷ)]对于m个样本成本函数为 J (1/m)ΣL(ŷ(i),y(i))5.2 梯度计算步骤反向传播的核心是计算成本函数对各参数的偏导数输出层梯度 dZ[2] A[2] - Y dW[2] (1/m)dZ[2]A[1]ᵀ db[2] (1/m)ΣdZ[2]隐藏层梯度 dZ[1] W[2]ᵀdZ[2] * g[1](Z[1]) dW[1] (1/m)dZ[1]Xᵀ db[1] (1/m)ΣdZ[1]5.3 参数更新规则使用梯度下降法更新参数 W[1] W[1] - αdW[1] b[1] b[1] - αdb[1] W[2] W[2] - αdW[2] b[2] b[2] - αdb[2]其中α是学习率控制每次更新的步长。6. 参数初始化技巧6.1 随机初始化的必要性如果将所有权重初始化为0会导致所有神经元学习相同的特征失去多层网络的意义。因此必须进行随机初始化。6.2 推荐的初始化方法小随机数初始化 W np.random.randn(n[l],n[l-1]) * 0.01适用于浅层网络但深层网络可能需要更复杂的初始化。Xavier初始化tanh激活 W np.random.randn(n[l],n[l-1]) * sqrt(1/n[l-1])He初始化ReLU激活 W np.random.randn(n[l],n[l-1]) * sqrt(2/n[l-1])提示偏置项b通常初始化为0因为不对称性主要由权重随机初始化提供。7. 超参数调优实践7.1 学习率选择学习率α是最关键的超参数之一太大可能无法收敛成本函数震荡甚至发散太小收敛速度过慢建议尝试对数尺度上的值0.001, 0.003, 0.01, 0.03, 0.1等7.2 隐藏单元数量隐藏层神经元数量n[1]决定模型的容量太少欠拟合无法捕捉复杂模式太多过拟合计算成本增加可以从较小值如32、64开始根据验证集表现逐步增加。7.3 迭代次数训练迭代次数需要平衡不足欠拟合过多浪费时间且可能导致过拟合使用早停法early stopping可以在验证集误差不再下降时终止训练。8. 常见问题与调试技巧8.1 梯度检查在实现反向传播时建议先进行梯度检查gradient checking来验证梯度计算的正确性计算数值梯度 grad_approx (J(θε) - J(θ-ε))/(2ε)与解析梯度比较 diff ||grad - grad_approx||₂ / (||grad||₂ ||grad_approx||₂)如果diff 1e-7通常认为实现正确。注意梯度检查仅用于调试正式训练时应关闭因为它计算代价很高。8.2 成本函数不下降的可能原因学习率太小初始化不当导致梯度消失实现中存在bug如梯度计算错误正则化过强8.3 过拟合应对策略增加训练数据应用L2正则化使用dropout虽然浅层网络通常不需要减少隐藏单元数量9. 完整实现示例Python以下是一个浅层神经网络的简化实现框架import numpy as np def initialize_parameters(n_x, n_h, n_y): W1 np.random.randn(n_h, n_x) * 0.01 b1 np.zeros((n_h, 1)) W2 np.random.randn(n_y, n_h) * 0.01 b2 np.zeros((n_y, 1)) return {W1: W1, b1: b1, W2: W2, b2: b2} def forward_propagation(X, parameters): W1, b1, W2, b2 parameters[W1], parameters[b1], parameters[W2], parameters[b2] Z1 np.dot(W1, X) b1 A1 np.tanh(Z1) Z2 np.dot(W2, A1) b2 A2 sigmoid(Z2) cache {Z1: Z1, A1: A1, Z2: Z2, A2: A2} return A2, cache def compute_cost(A2, Y): m Y.shape[1] logprobs np.multiply(np.log(A2), Y) np.multiply(np.log(1 - A2), (1 - Y)) cost -np.sum(logprobs) / m return np.squeeze(cost) def backward_propagation(parameters, cache, X, Y): m X.shape[1] W1, W2 parameters[W1], parameters[W2] A1, A2 cache[A1], cache[A2] dZ2 A2 - Y dW2 np.dot(dZ2, A1.T) / m db2 np.sum(dZ2, axis1, keepdimsTrue) / m dZ1 np.dot(W2.T, dZ2) * (1 - np.power(A1, 2)) dW1 np.dot(dZ1, X.T) / m db1 np.sum(dZ1, axis1, keepdimsTrue) / m grads {dW1: dW1, db1: db1, dW2: dW2, db2: db2} return grads def update_parameters(parameters, grads, learning_rate): W1 parameters[W1] - learning_rate * grads[dW1] b1 parameters[b1] - learning_rate * grads[db1] W2 parameters[W2] - learning_rate * grads[dW2] b2 parameters[b2] - learning_rate * grads[db2] return {W1: W1, b1: b1, W2: W2, b2: b2} def sigmoid(z): return 1/(1np.exp(-z))10. 实际应用中的注意事项数据预处理确保输入特征尺度相近标准化或归一化分类标签y应为0或1二分类问题训练监控记录训练集和验证集的成本函数值绘制学习曲线判断是否欠拟合或过拟合随机性控制固定随机种子如np.random.seed(1)以便复现结果多次随机初始化避免局部最优性能优化使用向量化操作避免显式循环对于大数据集考虑mini-batch梯度下降在实际项目中实现浅层神经网络时我发现最常遇到的问题往往不是算法本身而是数据预处理和参数初始化的细节。例如当输入特征尺度差异很大时如果不进行标准化某些权重可能需要非常小的学习率才能稳定更新这会显著拖慢训练速度。另一个常见陷阱是在计算梯度时忘记除以m样本数量导致更新步长过大。