感知机与线性变换
从生物神经元到数学模型
神经网络的最基本计算单元是人工神经元,其灵感来源于生物神经元。一个神经元接收多个输入信号,对这些信号加权求和后加上偏置,产生输出。
单个神经元的数学定义
设输入为
向量化表示
将所有权重写为行向量
多个神经元并行:矩阵形式
在实际网络中,一层通常包含多个神经元。设输入维度为
对于单个样本
其中
批量处理
对于
形状分析:
偏置
代码实现:LinearLayer.forward()
以上数学公式在 src/nn/layers/linearLayer.py 中的直接对应:
python
def forward(self, inputData: np.ndarray) -> np.ndarray:
# inputData: (batchSize, inputDim)
self.inputCache = inputData
# Y = X @ W 矩阵乘法,形状: (batchSize, outputDim)
outputData = inputData @ self.weights
# Y = X @ W + b 加上偏置(广播)
if self.useBias and self.bias is not None:
outputData = outputData + self.bias
self.outputCache = outputData
return outputData关键点:
@是 NumPy 的矩阵乘法运算符,对应公式中的矩阵乘积+ self.bias利用了 NumPy 广播——self.bias形状自动复制到每一行 self.inputCache保存输入,供反向传播计算权重梯度使用
权重初始化:Xavier (Glorot) 均匀分布
权重初始值对训练至关重要。本项目使用 Xavier 均匀初始化:
其中
python
rng = np.random.default_rng(randomSeed)
limit = np.sqrt(6.0 / (inputDim + outputDim))
self.weights = rng.uniform(
low=-limit, high=limit, size=(inputDim, outputDim),
).astype(np.float64)详细的 Xavier 初始化数学推导见 Xavier 初始化 章节。
为什么线性变换不够
如果神经网络只由线性变换组成,无论堆叠多少层,最终效果等价于单个线性变换:
这意味着没有隐藏层的表达能力提升。因此需要在每个线性层之后引入非线性激活函数,见下一章 激活函数。