我们接着讲解神经网络-反向传播算法
反向传播(Backward Propagation)详细讲解
反向传播的基本概念
反向传播是一种通过计算误差梯度来调整神经网络权重和偏置的算法,旨在最小化损失函数。反向传播算法使神经网络能够根据输出误差信息来调整其内部参数,从而逐步优化模型性能。
反向传播的目的:误差最小化
反向传播的主要目标是通过不断调整网络参数,使预测结果与真实值之间的误差逐步减小。这个过程通过计算梯度并更新权重和偏置来实现。
误差函数
常见的误差函数包括:
- 均方误差(Mean Squared Error, MSE):
KaTeX parse error: Undefined control sequence: \ at position 53: …- \hat{y}_i)^2 \̲ ̲ - 交叉熵损失(Cross-Entropy Loss):
KaTeX parse error: Undefined control sequence: \ at position 101: …{y}_i) \right) \̲ ̲
梯度下降算法简介
梯度下降是一种优化算法,用于通过最小化损失函数来更新神经网络的参数。常见的梯度下降算法包括:
- 随机梯度下降(SGD):每次使用一个样本进行梯度更新。
- 批量梯度下降(Batch Gradient Descent):每次使用整个训练集进行梯度更新。
- 小批量梯度下降(Mini-Batch Gradient Descent):每次使用一部分训练集进行梯度更新。
- Adam优化算法:结合了动量和自适应学习率的方法。
反向传播的步骤详细说明
反向传播算法的主要步骤如下:
- 计算输出层误差:根据误差函数计算预测输出与真实值之间的误差。
- 计算隐藏层误差:利用链式法则将误差反向传递到各隐藏层。
- 更新权重和偏置:根据计算出的梯度调整每个神经元的权重和偏置。
数学原理
正向传播的数学公式推导
在正向传播过程中,我们计算每层神经元的输出。以一个简单的单隐藏层神经网络为例,正向传播公式如下:
- 隐藏层的线性组合:
KaTeX parse error: Undefined control sequence: \ at position 50: …cdot x_2 + b_1 \̲ ̲ - 激活函数应用:
KaTeX parse error: Undefined control sequence: \ at position 15: a_1 = f(z_1) \̲ ̲ - 输出层的线性组合:
KaTeX parse error: Undefined control sequence: \ at position 50: …cdot a_2 + b_2 \̲ ̲ - 激活函数应用:
KaTeX parse error: Undefined control sequence: \ at position 13: y = f(z_2) \̲ ̲
当然可以,以下是权重更新的数学公式重新整理和详细解释:
反向传播的数学公式推导
反向传播通过计算误差的梯度来更新网络参数。以下是具体步骤:
-
计算输出层误差:
δ ( L ) = ∂ L ∂ z ( L ) = y ^ − y \delta^{(L)} = \frac{\partial L}{\partial z^{(L)}} = \hat{y} - y δ(L)=∂z(L)∂L=y^−y
其中, y ^ \hat{y} y^ 是预测值, y y y 是真实值。 -
计算隐藏层误差:
δ ( l ) = ( δ ( l + 1 ) ⋅ W ( l + 1 ) ) ⊙ f ′ ( z ( l ) ) \delta^{(l)} = (\delta^{(l+1)} \cdot W^{(l+1)}) \odot f'(z^{(l)}) δ(l)=(δ(l+1)⋅W(l+1))⊙f′(z(l))
其中, ⊙ \odot ⊙ 表示元素乘积, δ ( l ) \delta^{(l)} δ(l)是第 l l l 层的误差, W ( l + 1 ) W^{(l+1)} W(l+1)是第 l + 1 l+1 l+1层的权重, f ′ ( z ( l ) ) f'(z^{(l)}) f′(z(l)) 是第 l l l 层激活函数的导数。 -
更新权重和偏置:
- 权重更新:
W ( l ) = W ( l ) − η ∂ L ∂ W ( l ) = W ( l ) − η ⋅ ( δ ( l ) ⋅ ( a ( l − 1 ) ) T ) W^{(l)} = W^{(l)} - \eta \frac{\partial L}{\partial W^{(l)}} = W^{(l)} - \eta \cdot (\delta^{(l)} \cdot (a^{(l-1)})^T) W(l)=W(l)−η∂W(l)∂L=W(l)−η⋅(δ(l)⋅(a(l−1))T)
其中, η \eta η是学习率, δ ( l ) \delta^{(l)} δ(l) 是第 l l l 层的误差, a ( l − 1 ) a^{(l-1)} a(l−1)是第 l − 1 l-1 l−1层的输出。 - 偏置更新:
b ( l ) = b ( l ) − η ⋅ δ ( l ) b^{(l)} = b^{(l)} - \eta \cdot \delta^{(l)} b(l)=b(l)−η⋅δ(l)
- 权重更新:
具体示例代码
以下是使用Python和NumPy实现的简单单隐藏层神经网络的反向传播过程:
import numpy as np
# 激活函数及其导数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return x * (1 - x)
# 输入数据
inputs = np.array([[0.5, 0.2]])
expected_output = np.array([[1]])
# 初始化权重和偏置
weights_input_hidden = np.random.rand(2, 2)
bias_hidden = np.random.rand(2)
weights_hidden_output = np.random.rand(2, 1)
bias_output = np.random.rand(1)
learning_rate = 0.1
# 正向传播
hidden_layer_input = np.dot(inputs, weights_input_hidden) + bias_hidden
hidden_layer_output = sigmoid(hidden_layer_input)
output_layer_input = np.dot(hidden_layer_output, weights_hidden_output) + bias_output
output = sigmoid(output_layer_input)
# 计算输出层误差
error = expected_output - output
d_output = error * sigmoid_derivative(output)
# 计算隐藏层误差
error_hidden_layer = d_output.dot(weights_hidden_output.T)
d_hidden_layer = error_hidden_layer * sigmoid_derivative(hidden_layer_output)
# 更新权重和偏置
weights_hidden_output += hidden_layer_output.T.dot(d_output) * learning_rate
bias_output += np.sum(d_output, axis=0, keepdims=True) * learning_rate
weights_input_hidden += inputs.T.dot(d_hidden_layer) * learning_rate
bias_hidden += np.sum(d_hidden_layer, axis=0, keepdims=True) * learning_rate
print("更新后的权重(输入到隐藏层):", weights_input_hidden)
print("更新后的偏置(隐藏层):", bias_hidden)
print("更新后的权重(隐藏层到输出层):", weights_hidden_output)
print("更新后的偏置(输出层):", bias_output)
反向传播过程详细说明
-
计算输出层误差:
- 误差计算: e r r o r = e x p e c t e d _ o u t p u t − o u t p u t error = expected\_output - output error=expected_output−output
- 梯度计算: d _ o u t p u t = e r r o r × s i g m o i d _ d e r i v a t i v e ( o u t p u t ) d\_output = error \times sigmoid\_derivative(output) d_output=error×sigmoid_derivative(output)
-
计算隐藏层误差:
- 误差传递: e r r o r _ h i d d e n _ l a y e r = d _ o u t p u t ⋅ w e i g h t s _ h i d d e n _ o u t p u t T error\_hidden\_layer = d\_output \cdot weights\_hidden\_output^T error_hidden_layer=d_output⋅weights_hidden_outputT
- 梯度计算: d _ h i d d e n _ l a y e r = e r r o r _ h i d d e n _ l a y e r × s i g m o i d _ d e r i v a t i v e ( h i d d e n _ l a y e r _ o u t p u t ) d\_hidden\_layer = error\_hidden\_layer \times sigmoid\_derivative(hidden\_layer\_output) d_hidden_layer=error_hidden_layer×sigmoid_derivative(hidden_layer_output)
-
更新权重和偏置:
- 更新隐藏层到输出层的权重和偏置:
w e i g h t s _ h i d d e n _ o u t p u t + = h i d d e n _ l a y e r _ o u t p u t T ⋅ d _ o u t p u t × l e a r n i n g _ r a t e weights\_hidden\_output += hidden\_layer\_output^T \cdot d\_output \times learning\_rate weights_hidden_output+=hidden_layer_outputT⋅d_output×learning_rate
b i a s _ o u t p u t + = ∑ ( d _ o u t p u t , a x i s = 0 , k e e p d i m s = T r u e ) × l e a r n i n g _ r a t e bias\_output += \sum(d\_output, axis=0, keepdims=True) \times learning\_rate bias_output+=∑(d_output,axis=0,keepdims=True)×learning_rate - 更新输入层到隐藏层的权重和偏置:
w e i g h t s _ i n p u t _ h i d d e n + = i n p u t s T ⋅ d _ h i d d e n _ l a y e r × l e a r n i n g _ r a t e weights\_input\_hidden += inputs^T \cdot d\_hidden\_layer \times learning\_rate weights_input_hidden+=inputsT⋅d_hidden_layer×learning_rate
b i a s _ h i d d e n + = ∑ ( d _ h i d d e n _ l a y e r , a x i s = 0 , k e e p d i m s = T r u e ) × l e a r n i n g _ r a t e bias\_hidden += \sum(d\_hidden\_layer, axis=0, keepdims=True) \times learning\_rate bias_hidden+=∑(d_hidden_layer,axis=0,keepdims=True)×learning_rate
- 更新隐藏层到输出层的权重和偏置:
总结
反向传播是神经网络训练中的核心算法,它通过计算误差梯度来调整神经网络的权重和偏置,从而逐步优化模型性能。理解反向传播的原理和实现过程,对于掌握神经网络和深度学习至关重要。通过实际的代码示例,初学者可以更直观地理解反向传播的每一步计算过程。