反向传播算法的概述
反向传播算法是深度学习中一种重要的训练算法,用于计算神经网络中的权重和偏差的梯度,从而实现网络的优化和学习。该算法以一种迭代的方式通过计算损失函数对权重和偏差的梯度来更新网络参数。
在深度学习中,神经网络通常由多个层组成,包括输入层、隐藏层和输出层。反向传播算法通过计算输入与目标输出之间的误差,并将误差通过网络反向传播回每一层,从而推导出梯度以更新权重和偏差。
算法原理
反向传播算法的原理是基于链式法则和梯度下降算法的组合。首先,算法计算网络的输出与目标输出之间的误差。然后,误差通过链式法则从输出层反向传播回隐藏层和输入层,计算每个参数的梯度。最后,梯度下降算法使用这些梯度来更新网络参数,以减小误差。
公式推导
下面是反向传播算法的公式推导:
首先,定义网络的损失函数为平方损失函数:
$$loss = \frac{1}{2} \sum_{i=1}^{n}(y_i – \hat{y_i})^2$$
其中 $y_i$ 表示目标输出,$\hat{y_i}$ 表示网络的预测输出。
然后,对于最后一层的权重和偏差,可以推导出以下梯度公式:
$$\frac{\partial loss}{\partial w_{jk}^L} = (y_k – \hat{y_k}) 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 \sigma'(z_k^L) 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 a_j^{L-1}$$
$$\frac{\partial loss}{\partial b_k^L} = (y_k – \hat{y_k}) 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 \sigma'(z_k^L)$$
其中 $w_{jk}^L$ 表示最后一层的权重,$b_k^L$ 表示最后一层的偏差,$z_k^L$ 表示最后一层的加权输入,$\sigma'(z_k^L)$ 表示最后一层激活函数的导数,$a_j^{L-1}$ 表示前一层的激活值。
对于隐藏层的权重和偏差,可以推导出以下梯度公式:
$$\frac{\partial loss}{\partial w_{ij}^l} = \sum_{k=1}^{m}(\frac{\partial loss}{\partial z_k^l}\cdot w_{jk}^{l+1}) \cdot \sigma'(z_j^l) \cdot a_i^{l-1}$$
$$\frac{\partial loss}{\partial b_i^l} = \sum_{k=1}^{m}(\frac{\partial loss}{\partial z_k^l}\cdot w_{jk}^{l+1}) \cdot \sigma'(z_j^l)$$
其中 $w_{ij}^l$ 表示隐藏层的权重,$b_i^l$ 表示隐藏层的偏差,$z_j^l$ 表示隐藏层的加权输入,$\sigma'(z_j^l)$ 表示隐藏层激活函数的导数,$a_i^{l-1}$ 表示前一层的激活值。
计算步骤
反向传播算法的计算步骤如下:
- 初始化网络的权重和偏差。
- 对于每个输入样本,进行前向传播,计算每一层的加权输入和激活值,并记录预测输出。
- 计算输出层的梯度,利用公式推导计算最后一层的权重和偏差的梯度。
- 计算隐藏层的梯度,根据公式推导,从输出层反向传播到每一层,计算每一层的权重和偏差的梯度。
- 利用梯度下降算法,根据计算得到的梯度更新网络的权重和偏差。
- 重复步骤2到5,直到达到预定的迭代次数或损失函数收敛。
复杂Python代码示例
下面是一个使用Python实现反向传播算法的示例代码。我们使用一个三层神经网络,并使用手动生成的虚拟数据集进行训练和预测。
首先,我们导入所需的库:
import numpy as np
接下来,定义一个神经网络类:
class NeuralNetwork:
def __init__(self, hidden_size):
self.hidden_size = hidden_size
def _sigmoid(self, x):
return 1 / (1 + np.exp(-x))
def _sigmoid_derivative(self, x):
return 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 - x)
def train(self, X, y, num_iterations):
self.input_size = X.shape[1]
self.output_size = y.shape[1]
# 初始化权重和偏差
self.weights1 = np.random.randn(self.input_size, self.hidden_size)
self.bias1 = np.zeros((1, self.hidden_size))
self.weights2 = np.random.randn(self.hidden_size, self.output_size)
self.bias2 = np.zeros((1, self.output_size))
for i in range(num_iterations):
# 前向传播
hidden_layer_input = np.dot(X, self.weights1) + self.bias1
hidden_layer_output = self._sigmoid(hidden_layer_input)
output_layer_input = np.dot(hidden_layer_output, self.weights2) + self.bias2
output_layer_output = self._sigmoid(output_layer_input)
# 计算损失函数
loss = np.mean(np.square(y - output_layer_output))
# 输出当前迭代次数和损失函数值
print(f"Iteration: {i}, Loss: {loss}")
# 反向传播
output_error = (y - output_layer_output) 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 self._sigmoid_derivative(output_layer_output)
hidden_error = np.dot(output_error, self.weights2.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 self._sigmoid_derivative(hidden_layer_output)
# 更新权重和偏差
self.weights2 += np.dot(hidden_layer_output.T, output_error)
self.bias2 += np.sum(output_error, axis=0, keepdims=True)
self.weights1 += np.dot(X.T, hidden_error)
self.bias1 += np.sum(hidden_error, axis=0, keepdims=True)
def predict(self, X):
hidden_layer_input = np.dot(X, self.weights1) + self.bias1
hidden_layer_output = self._sigmoid(hidden_layer_input)
output_layer_input = np.dot(hidden_layer_output, self.weights2) + self.bias2
output_layer_output = self._sigmoid(output_layer_input)
return output_layer_output
使用生成的数据集进行训练和预测:
# 生成数据集
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])
# 创建神经网络对象并进行训练
nn = NeuralNetwork(4)
nn.train(X, y, num_iterations=10000)
# 预测新的样本
new_data = np.array([[0, 0]])
prediction = nn.predict(new_data)
print(f"Prediction: {prediction}")
以上是一个简单的反向传播算法的示例,我们使用了一个具有一个隐藏层的神经网络进行实现,并使用虚拟数据集进行训练和预测。
代码细节解释
在上述示例代码中,我们首先初始化了神经网络的权重和偏差。然后,在训练方法中,我们使用循环迭代的方式进行多次前向和反向传播。
在前向传播阶段,我们首先计算隐藏层的加权输入和激活值,然后计算输出层的加权输入和激活值。在反向传播阶段,我们首先计算输出层的误差,然后计算隐藏层的误差。最后,我们根据梯度下降算法使用这些梯度来更新权重和偏差。
在预测方法中,我们根据训练好的网络参数进行前向传播,得到预测的输出值。
这个例子中使用了一个简单的平方损失函数和 sigmoid 激活函数,你可以根据需要扩展和修改这个示例代码来适应不同的损失函数和激活函数。
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/823884/
转载文章受原作者版权保护。转载请注明原作者出处!