# Pseudocode for forward propagationdefforward_propagation(X, parameters):"""
X: Input data (batch_size, n_features)
parameters: Dictionary containing weights and biases for each layer
Returns: The final output and all intermediate activations
"""# Store all activations for later use (e.g., in backpropagation)
activations ={'A0': X}# A0 is the input# Loop through L-1 layers (excluding the output layer)for l inrange(1, L):# Get previous activation
A_prev = activations[f'A{l-1}']# Get weights and biases for current layer
W = parameters[f'W{l}']
b = parameters[f'b{l}']# Compute pre-activation
Z = np.dot(A_prev, W.T)+ b
# Apply activation function (e.g., ReLU for hidden layers)
A = relu(Z)# Store values for later use
activations[f'Z{l}']= Z
activations[f'A{l}']= A
# Compute output layer (layer L)
A_prev = activations[f'A{L-1}']
W = parameters[f'W{L}']
b = parameters[f'b{L}']# Compute pre-activation for output layer
Z = np.dot(A_prev, W.T)+ b
# Apply output activation function (depends on the task)if task =='binary_classification':
A = sigmoid(Z)elif task =='multiclass_classification':
A = softmax(Z)elif task =='regression':
A = Z # Linear activation# Store output layer values
activations[f'Z{L}']= Z
activations[f'A{L}']= A
return A, activations技术支持
import numpy as np
import matplotlib.pyplot as plt
# For reproducibility
np.random.seed(42)技术支持
接着定义我们将用到的激活函数:
defrelu(Z):"""ReLU activation function: max(0, Z)"""return np.maximum(0, Z)defsigmoid(Z):"""Sigmoid activation function: 1/(1 + e^(-Z))"""return1/(1+ np.exp(-Z))defsoftmax(Z):"""Softmax activation function for multi-class classification"""# Subtract max for numerical stability (prevents overflow)
exp_Z = np.exp(Z - np.max(Z, axis=1, keepdims=True))return exp_Z / np.sum(exp_Z, axis=1, keepdims=True)技术支持
然后创建神经网络类:
classNeuralNetwork:def__init__(self, layer_dims, activations):"""
Initialize a neural network with specified layer dimensions and activations
Parameters:
- layer_dims: List of integers representing the number of neurons in each layer
(including input and output layers)
- activations: List of activation functions for each layer (excluding input layer)
"""
self.L =len(layer_dims)-1# Number of layers (excluding input layer)
self.layer_dims = layer_dims
self.activations = activations
self.parameters ={}# Initialize parameters (weights and biases)
self.initialize_parameters()definitialize_parameters(self):"""Initialize weights and biases with small random values"""for l inrange(1, self.L +1):# He initialization for weights - helps with training deep networks
self.parameters[f'W{l}']= np.random.randn(self.layer_dims[l], self.layer_dims[l-1])* np.sqrt(2/ self.layer_dims[l-1])
self.parameters[f'b{l}']= np.zeros((self.layer_dims[l],1))defforward_propagation(self, X):"""
Perform forward propagation through the network
Parameters:
- X: Input data (n_features, batch_size)
Returns:
- AL: Output of the network
- caches: Dictionary containing all activations and pre-activations
"""
caches ={}
A = X # Input layer activation
caches['A0']= X
# Process through L-1 layers (excluding output layer)for l inrange(1, self.L):
A_prev = A
# Get weights and biases for current layer
W = self.parameters[f'W{l}']
b = self.parameters[f'b{l}']# Forward propagation for current layer
Z = np.dot(W, A_prev)+ b
# Apply activation function
activation_function = self.activations[l-1]if activation_function =="relu":
A = relu(Z)elif activation_function =="sigmoid":
A = sigmoid(Z)# Store values for backpropagation
caches[f'Z{l}']= Z
caches[f'A{l}']= A
# Output layer
W = self.parameters[f'W{self.L}']
b = self.parameters[f'b{self.L}']
Z = np.dot(W, A)+ b
# Apply output activation function
activation_function = self.activations[self.L-1]if activation_function =="sigmoid":
AL = sigmoid(Z)elif activation_function =="softmax":
AL = softmax(Z)elif activation_function =="linear":
AL = Z # No activation for regression# Store output layer values
caches[f'Z{self.L}']= Z
caches[f'A{self.L}']= AL
return AL, caches技术支持
上面的 NeuralNetwork 类提供了一个可自定义架构的完整神经网络框架。其关键组件包括:
初始化:根据指定的层规模与激活函数配置网络。使用 He 初始化自动初始化权重与偏置,有助于提升训练表现。
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Input
# For reproducibility
tf.random.set_seed(42)# Create the same network architecture
tf_model = Sequential([
Input(shape=(3,)),# Input layer with 3 features
Dense(4, activation='relu'),# Hidden layer with 4 neurons
Dense(2, activation='sigmoid')# Output layer with 2 neurons])
tf_model.summary()技术支持
# Sample input data with the shape expected by Keras
X_tf = np.random.randn(5,3)# 5 examples, 3 features# Forward propagation in TensorFlow
tf_output = tf_model.predict(X_tf)print(f"TensorFlow output shape: {tf_output.shape}")print(f"TensorFlow output values:\n{tf_output}")技术支持
import torch
import torch.nn as nn
# For reproducibility
torch.manual_seed(42)# Create a network in PyTorchclassPyTorchNN(nn.Module):def__init__(self):super(PyTorchNN, self).__init__()
self.hidden = nn.Linear(3,4)# 3 inputs, 4 hidden neurons
self.relu = nn.ReLU()
self.output = nn.Linear(4,2)# 4 inputs from hidden, 2 outputs
self.sigmoid = nn.Sigmoid()defforward(self, x):
x = self.relu(self.hidden(x))
x = self.sigmoid(self.output(x))return x
# Instantiate the model
torch_model = PyTorchNN()# Print model structureprint(torch_model)技术支持
# TensorFlow example of GPU accelerationimport tensorflow as tf
# Check for available GPUsprint("GPUs Available:", tf.config.list_physical_devices('GPU'))# TensorFlow automatically uses available GPUswith tf.device('/GPU:0'):# Explicitly specify GPU if multiple are available# Computation runs on GPU if available
result = tf_model.predict(X_tf)技术支持
神经网络已经重塑了人工智能,从图像识别到自然语言处理无所不包。而支撑这些强大模型的核心,正是一项基础过程——前向传播。本文将带您从基本原理到实际实现,系统讲解这一核心概念。
如果您希望对本文涉及的诸多概念进行动手实践,欢迎查看我们的Deep Learning in Python 技能路径。
什么是前向传播?
前向传播是神经网络将输入数据转换为预测或输出的过程。可以把它看作神经网络的“思考”阶段——当给定输入(如图像或文本)时,前向传播就是网络如何将信息在层间传递并处理,最终产生结果。
从技术上讲,它是按顺序进行的计算:数据从输入层出发,依次经过隐藏层,最终到达输出层。在此过程中,数据会通过带权连接和激活函数被不断变换,从而使网络能够捕捉复杂模式。
为什么要理解前向传播
理解前向传播至关重要,原因包括:
您将在本指南中学到什么
在读完本指南后,您将能够:
先决条件
为充分受益于本指南,您应具备:
如果您希望夯实基础,可以参考以下资源:
即便没有深厚背景,我们也循序渐进设计了本指南,帮助有决心的学习者迈入神经网络的世界。让我们开始吧!
前向传播的基础
要理解前向传播,我们先从其基本构件说起。从神经网络中最小的计算单元开始,逐步构建到更复杂的结构。
单个神经元:一切的起点
神经网络的故事从一个与生物学的有趣类比开始。正如人脑由数十亿个相互连接的神经元构成,人工神经网络由受这些生物细胞启发的数学模型搭建而成。
来源:Deep Learning - Visual Approach
在生物学中,神经元通过树突接收来自其他神经元的信号,在胞体中处理这些信号,然后通过轴突将结果传递给其他神经元。在计算模型中,我们用以下元素来对应这一过程:
我们用一个单个神经元来直观说明:
来源:Deep Learning - Visual Approach
这个简单的计算单元构成了即便是最复杂神经网络的基础。但神经元究竟如何把输入变成输出?这就要用到数学了。
单个神经元的数学基础
神经元的运作可以用一个简洁的方程来描述:
逐项解释:
我们用一个具体数值例子来说明。假设一个神经元有三个输入:
首先,计算加权和加偏置:
接着,应用一个激活函数。我们使用流行的 ReLU(修正线性单元) 函数,定义如下:
预激活值为负数时,ReLU 神经元输出 0,表示对该输入不“触发”。
激活函数至关重要,因为它为网络引入非线性。没有它,即使网络层数再多,也只能学习线性关系。常见的激活函数包括:
不同激活函数各有优势和适用场景,我们在实现网络时会进一步探讨。
从神经元到层
单个神经元功能强大,但神经网络真正的能力源自神经元被组织为层。层就是一组并行处理输入的神经元。通常神经网络包含三类层:
当一层中有多个神经元时,每个神经元都接收相同输入,但具有不同权重和偏置。我们可以用矩阵运算高效表示这种情况。下面看看如何实现。
设想我们有一层,包含 3 个输入值和 4 个神经元。每个神经元都有自己的一组权重和偏置:
我们可将这些权重组织为权重矩阵 W:
然后,我们可以用一次矩阵乘法同时计算所有神经元的预激活值:
其中:
接着对每个元素应用激活函数,得到最终输出:
这种矩阵表示不仅优雅,而且计算高效。现代硬件(尤其是 GPU)对矩阵运算高度优化,使这种方法远快于逐个神经元单独计算输出。
将这些层堆叠起来——上一层的输出作为下一层的输入——赋予了神经网络学习复杂模式的非凡能力。随着我们把这些积木连接起来,就可以研究前向传播在整个神经网络中如何运作。
完整网络中的前向传播
理解了单个神经元与层之后,我们再来看前向传播如何贯穿整个神经网络。这正是深度学习威力所在。
多层网络:全景图
完整的神经网络由输入层、一个或多个隐藏层,以及输出层组成。“深度”一词指拥有多个隐藏层的网络。每一层都会以更抽象的方式变换数据,从而让网络学到复杂表征。
考虑一个简单的神经网络,包含:
其结构示意如下:
当数据在该网络中流动时,我们会在每一层执行一系列计算。若记为:
则整个网络的前向传播可表示为:
1. 计算隐藏层预激活:
2. 应用激活函数得到隐藏层输出:
3. 计算输出层预激活:
4. 应用激活函数得到最终输出:
最终的 A^[2] 表示网络的预测结果。对于分类任务,它可能是各类别的概率;对于回归任务,则可能是预测值。
不同层常用不同激活函数。例如,隐藏层常用 ReLU,而输出层可能使用:
这种多层结构的妙处在于每一层都可以学习数据的不同方面。早期层通常检测简单特征,更深层将其组合为更复杂的模式。这种分层学习能力使神经网络在图像与语音识别等复杂任务上大放异彩。
前向传播算法
我们将前向传播过程形式化为一个算法。对于拥有 L 层的神经网络,前向传播遵循以下步骤:
该算法突出了前向传播的若干关键点:
前向传播算法非常简单,却使神经网络能够逼近极其复杂的函数。与反向传播的恰当训练相结合,这一简单过程让网络能够从数据中学习并做出越来越准确的预测。
我们再通过一个具体示例加深理解。考虑输入 X = [0.5, -0.2, 0.1] 经过如下示例网络:
为简化,设所有权重均为 0.1,所有偏置为 0:
按算法进行:
这就得到最终预测。在二分类背景下,接近 0.5 的值表明对两个类别的判断存在不确定性。
下一节,我们将用 Python 实现前向传播,直观展示这些计算过程。
在 Python 中实现前向传播
理解了前向传播的理论后,我们通过在 Python 中实现将其付诸实践。我们先用纯 NumPy “从零开始”实现,然后看看现代深度学习框架如何简化这一过程。
用 NumPy 从零构建
NumPy 提供高效的数组运算,使我们能够实现上述矩阵计算。下面构建一个执行多层前向传播的简单神经网络类。
首先导入必要的库:
接着定义我们将用到的激活函数:
然后创建神经网络类:
上面的
NeuralNetwork类提供了一个可自定义架构的完整神经网络框架。其关键组件包括:forward_propagation方法是网络进行预测的核心。它:3. 激活函数:网络支持多种激活函数,包括 ReLU、sigmoid 和 softmax,因而既可用于回归也可用于分类。
4. 灵活的架构:该实现允许任意深度与宽度的网络,适用于多种机器学习任务。
该实现遵循标准的神经网络设计范式:数据在网络中前向流动,每一层在传递给下一层之前对数据进行变换。
现在用一个小示例网络测试实现:
输出:
我们也来可视化数据在网络中的变换过程:
该可视化显示数据在网络中传播时的变化:
“从零开始”的实现展示了前向传播的核心原理,但现代深度学习框架为构建神经网络提供了更高效、更灵活的工具。
使用深度学习框架
接下来,我们用流行的深度学习框架 TensorFlow 和 PyTorch 实现同样的神经网络。这些框架优化了性能,并提供更高层抽象,使构建复杂模型更容易。
首先看看 TensorFlow/Keras 的实现:
我们刚用 TensorFlow/Keras 实现了神经网络,并在一些样本数据上完成了前向传播。模型概要显示了架构:输入层接收 3 个特征,隐藏层含 4 个神经元并使用 ReLU,输出层含 2 个神经元并使用 sigmoid。模型共有 26 个可训练参数。
前向传播结果显示输出形状为 (5, 2),对应 5 个输入样本,每个产生 2 个输出值。由于输出层使用 sigmoid,这些值被约束在 0 与 1 之间。
接着,我们用另一流行框架 PyTorch 实现相同的网络架构,以便比较不同方法。
输出:
输出:
我们来比较这些实现:
输出:
这些实现的主要差异:
对于简单网络,NumPy 实现足够使用;但随着复杂度提升,深度学习框架变得不可或缺。它们处理底层优化,并为从开发到部署的完整工作流提供工具。想进一步了解这些框架,请参阅我们的独立指南:
下一节,我们将构建一个完整的工作示例,将前向传播应用于真实问题。
前向传播示例
在我们用从零与框架两种方式实现前向传播之后,来看一个真实问题中的实践。我们将构建一个完整示例,并探讨如何优化流程以提升性能。
完整可运行示例
让我们把所学应用到经典任务:用 MNIST 数据集识别手写数字。该数据集包含 70,000 张 28×28 像素的手写数字(0–9)图像。
首先加载并准备数据:
现在用我们的 NumPy 实现为此任务构建网络。我们将使用:
我们得到 7% 的准确率,甚至低于随机猜测。但这是意料之中的,因为我们只执行了前向传播——并未进行任何学习。
现在可视化网络如何在各层处理一张图像:
该可视化展示了信息如何在网络中流动:
最活跃的输出神经元对应网络的预测。即便权重随机(因为尚未训练),我们也能看到前向传播如何将输入数据转化为预测。
若要更完整的示例,我们会使用反向传播训练网络,调整权重与偏置,使预测不断改进。不过,即使不训练,该示例也展示了前向传播在真实数据上的工作方式。
优化前向传播
随着神经网络规模与数据集体量增大,优化前向传播愈发重要。以下是提升前向传播效率的关键策略:
1. 批处理
与逐样本处理相比,同时对批量样本进行前向传播可以利用现代硬件的并行能力。
2. 向量化
使用矩阵运算代替循环可显著加速计算。这就是我们使用 NumPy 数组运算的原因。
3. 内存管理
在大网络中需要注意内存使用。技巧包括:
4. GPU 加速
图形处理器擅长矩阵运算。现代框架可将计算无缝迁移至 GPU,从而显著提速:
5. 专用硬件
除了 GPU,还有诸如 Google 的 TPU(张量处理单元)等专为神经网络运算设计的硬件。
6. 算法级优化
某些激活函数与网络架构在计算上更高效:
7. 框架级优化
深度学习框架实现了大量底层优化:
随着网络更深更宽,前向传播优化愈发重要。诸如 ResNet、Transformer、EfficientNet 等现代架构在设计上就兼顾了前向传播效率与模型精度。
下一节,我们将探讨前向传播如何与反向传播(Backpropagation)相互关联,从而完整呈现神经网络如何学习。
与反向传播的关系
我们已经深入探讨了前向传播,但这只是神经网络的“半边天”。下面简要说明前向传播如何与实现学习的反向传播相衔接。
连接前向与后向传播
在神经网络中,前向传播与反向传播彼此配合:
在学习过程中两者缺一不可。反向传播离不开前向传播,因为它需要:
可以将前向传播看作网络基于当前理解给出的“最佳猜测”,而反向传播则是根据错误来修正这种理解的过程。
学习循环
完整的学习过程遵循一个循环模式:
这一过程之所以强大,是因为前向传播为反向传播提供了上下文。在前向过程中,网络不仅生成预测,还记录所有中间值与决策;反向传播据此进行针对性调整。
其妙处在于,复杂的学习能力源于这两种相对简单的过程协同工作。前向传播很直观——依次进行矩阵乘法和激活函数;反向传播更复杂,但直接基于微积分原理。
两者结合,使神经网络在有足够数据与算力时几乎能学习任何模式。这一学习能力推动了计算机视觉、自然语言处理、博弈等领域的突破。
如本文所示,深入理解前向传播可为把握神经网络完整学习过程奠定基础。若您想深入学习过程,请参阅我们的 反向传播详解,了解网络如何从错误中学习。
总结与后续
前向传播是神经网络将输入转化为预测的基础过程。正如我们所见,它由一系列顺序的矩阵乘法与激活函数组成,使数据在网络层间逐步变换。无论您是从零实现、使用现代框架,还是排查模型问题,理解这一过程都至关重要。
掌握前向传播,意味着您向构建与理解能够解决复杂问题的深度学习模型迈出了重要一步。
继续您的深度学习之旅,探索 DataCamp 的系统资源:
若您偏好结构化学习路径, Deep Learning in Python 路径将帮助您掌握构建与部署神经网络以应对真实应用所需的一切。