问题背景
误差反向传播算法(Error Backpropagation Algorithm)是一种用于训练神经网络的常用算法。然而,是否只能用于训练神经网络是一个比较有争议的问题。在本文中,我们将详细讨论误差反向传播算法的原理、公式推导、计算步骤以及给出一个复杂的Python代码示例。
算法原理
误差反向传播算法是一种基于梯度下降的优化算法,用于训练神经网络。在神经网络中,参数(权重和偏置)的调整是通过最小化损失函数来实现的。算法的基本思想是通过计算损失函数对每个参数的导数来确定参数调整的方向和幅度。
公式推导
在推导误差反向传播算法之前,我们先引入一些符号:
- 输入向量:$$x = (x_1, x_2, …, x_m)$$
- 第$l$层的输入:$$a^{(l)} = (a_1^{(l)}, a_2^{(l)}, …, a_{n_l}^{(l)})$$
- 第$l$层的输出:$$z^{(l)} = (z_1^{(l)}, z_2^{(l)}, …, z_{n_l}^{(l)})$$
- 第$l$层的参数:权重矩阵 $$W^{(l)}$$ 和偏置向量 $$b^{(l)}$$,其中 $$W^{(l)} = [w_{ij}^{(l)}]{n_l \times n{l-1}}$$ 且 $$b^{(l)} = (b_1^{(l)}, b_2^{(l)}, …, b_{n_l}^{(l)})$$
- 第$l$层的激活函数:$$\sigma^{(l)}(\cdot)$$
对于一个有$L$层的神经网络,其输出可以表示为:
$$a^{(L)} = f(z^{(L)})$$
其中 $f(\cdot)$ 是输出层的激活函数。我们的目标是最小化损失函数 $J(a^{(L)}, y)$,其中 $y$ 是训练样本的真实标签。
我们使用梯度下降法来更新参数。下面推导每一层中的参数调整量。
首先,计算输出层第$L$层的误差项 $delta^{(L)}$:
$$\delta^{(L)} = \nabla_{a^{(L)}} J \odot f'(z^{(L)})$$
其中 $\nabla_{a^{(L)}} J$ 表示损失函数对 $a^{(L)}$ 的导数,$\odot$ 表示逐元素乘法,$f'(\cdot)$ 表示激活函数的导数。
然后,对于第$l$层 $(L-1 \geq l \geq 1)$,我们计算误差项 $\delta^{(l)}$:
$$\delta^{(l)} = ((W^{(l+1)})^T \delta^{(l+1)}) \odot f'(z^{(l)})$$
最后,我们使用误差项来计算参数调整量:
$$\Delta W^{(l)} = \delta^{(l)} (a^{(l-1)})^T$$
$$\Delta b^{(l)} = \delta^{(l)}$$
其中,$(a^{(l-1)})^T$ 表示 $(l-1)$ 层的输入的转置。
计算步骤
根据推导的公式,我们可以总结出误差反向传播算法的一般步骤:
- 初始化神经网络的参数 $W^{(l)}$ 和 $b^{(l)}$。
- 对于每个训练样本,进行前向传播计算,得到每一层的输入和输出。
- 计算输出层的误差项 $\delta^{(L)}$。
- 根据误差项,计算每一层的误差项 $\delta^{(l)}$。
- 使用误差项计算参数调整量 $\Delta W^{(l)}$ 和 $\Delta b^{(l)}$。
- 更新参数 $W^{(l)}$ 和 $b^{(l)}$,应用梯度下降法进行优化。
- 重复步骤 2-6 直到达到收敛条件或达到训练迭代次数。
复杂Python代码示例
下面是一个使用Python实现的复杂神经网络误差反向传播算法的示例代码。我们假设网络有两个隐藏层和一个输出层,使用 sigmoid 激活函数。
import numpy as np
# 定义神经网络的参数
W1 = np.random.randn(2, 4) # 第一层权重矩阵大小为 (2, 4)
b1 = np.random.randn(4) # 第一层偏置向量大小为 (4,)
W2 = np.random.randn(4, 4) # 第二层权重矩阵大小为 (4, 4)
b2 = np.random.randn(4) # 第二层偏置向量大小为 (4,)
W3 = np.random.randn(4, 1) # 输出层权重矩阵大小为 (4, 1)
b3 = np.random.randn(1) # 输出层偏置向量大小为 (1,)
# 定义激活函数和其导数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return sigmoid(x) artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls (1 - sigmoid(x))
# 定义正向传播函数
def forward_propagation(X):
# 第一层
z1 = np.dot(X, W1) + b1
a1 = sigmoid(z1)
# 第二层
z2 = np.dot(a1, W2) + b2
a2 = sigmoid(z2)
# 输出层
z3 = np.dot(a2, W3) + b3
a3 = sigmoid(z3)
return a3
# 定义误差反向传播函数
def backward_propagation(X, y, learning_rate):
m = X.shape[0] # 样本数量
# 正向传播
a3 = forward_propagation(X)
# 输出层误差项
delta3 = (a3 - y) artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls sigmoid_derivative(z3)
# 第二层误差项
delta2 = np.dot(delta3, W3.T) artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls sigmoid_derivative(z2)
# 第一层误差项
delta1 = np.dot(delta2, W2.T) artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls sigmoid_derivative(z1)
# 参数调整量
dW3 = np.dot(a2.T, delta3) / m
db3 = np.sum(delta3, axis=0) / m
dW2 = np.dot(a1.T, delta2) / m
db2 = np.sum(delta2, axis=0) / m
dW1 = np.dot(X.T, delta1) / m
db1 = np.sum(delta1, axis=0) / m
# 参数更新
W3 -= learning_rate artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls dW3
b3 -= learning_rate artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls db3
W2 -= learning_rate artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls dW2
b2 -= learning_rate artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls db2
W1 -= learning_rate artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls dW1
b1 -= learning_rate artical cgpt2md_gpt.sh cgpt2md_johngo.log cgpt2md_johngo.sh cgpt2md.sh _content1.txt _content.txt current_url.txt history_url history_urls log nohup.out online pic.txt seo test.py topic_gpt.txt topic_johngo.txt topic.txt upload-markdown-to-wordpress.py urls db1
# 训练网络
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) # 输入样本
y = np.array([[0], [1], [1], [0]]) # 标签
learning_rate = 0.1 # 学习率
num_epochs = 10000 # 迭代次数
for epoch in range(num_epochs):
# 误差反向传播更新参数
backward_propagation(X, y, learning_rate)
# 输出结果
print(forward_propagation(X))
代码细节解释
- 第 3 行到第 7 行定义了不同层的权重矩阵和偏置向量。
- 第 10 行到第 14 行定义了 sigmoid 函数和其导数。
- 第 17 行到第 25 行定义了正向传播的函数。
- 第 28 行到第 54 行定义了误差反向传播的函数。其中,求导数的公式在正向传播中已经给出,这里直接应用。
- 第 58 行到第 67 行设置了训练的输入样本和目标标签,学习率和迭代次数。
- 第 69 行到第 73 行进行了训练迭代,调用了误差反向传播函数进行参数调整。
- 第 76 行打印了最终的输出结果。
这是一个简单的深度神经网络的误差反向传播算法的示例代码。通过这个例子,我们可以更好地理解该算法的实现和工作原理。
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/823877/
转载文章受原作者版权保护。转载请注明原作者出处!