神经网络的学习之旅:探索“梯度下降”
想象一下,你正在爬山。你的目标是从山顶到达山脚,但你的眼睛被蒙住了,你只能感觉到脚下的坡度。每一步,你都会选择坡度最陡的方向前进,直到你觉得自己已经到达了山脚。这个过程就像神经网络中的一个关键算法——梯度下降。
1. 神经网络: 一个数字的大脑
首先,让我们理解什么是神经网络。想象一个机器的大脑,它由成千上万个小单元组成,就 像我们大脑中的神经元。这些单元互相连接,传递和处理信息,帮助机器做出决策。
为了让机器学会做某件事情(比如识别手写数字),我们需要调整这些连接的强度,让它更 好地理解我们给它的数据。这就像是调整音响的各种旋钮,让音乐听起来更和谐。
2. 为什么要下山?
回到我们的爬山比喻,为什么我们要从山顶走到山脚呢? 在神经网络的世界里,山顶代表的是一个很差的网络,而山脚代表的是一个很好的网络。我们的目标是找到一种方法,让网络 从“差”变为“好”。
但是,我们如何衡量“差”和“好”呢? 这就是成本函数的作用。它像一个指南针,告诉我们网络 现在的位置,以及我们应该朝哪个方向前进。数学上,我们可以描述这个差异为:
其中, 是网络的预测输出,而 是真实的标签。
3. 找到下山的最佳路径
我们知道要走到山脚,但具体怎么走呢? 这就需要了解坡度或斜率。在每一步,我们都会选 择坡度最陡的方向前进。
在神经网络中,我们使用数学工具 (称为“稊度”) 来帮助我们找到这个方向。梯度就像一个指示器,告诉我们应该如何调整网络的连接,使其更好。数学上,梯度是这样计算的:
其中, 是成本函数的梯度,而 是网络的权重。
4.走一步,再走一步
每一次调整都是一个小步䅇。我们不想走得太快,否则可能会错过最佳路径。这就像是调整 音响的旋钮,我们不想转得太快,否则可能会错过最佳音效。
在神经网络中,这个步骤的大小称为“学习率”。学习率决定了我们每次调整的幅度。数学上, 我们的更新规则是:
其中, 是学习率,决定了每一步的大小。
5. 重复直到完美
我们会反复调整,直到网络变得足够好。这个过程可能需要很长时间,因为我们正在处理大 量的数据和复杂的模型。
但是,最终的结果是值得的。通过梯度下降,我们可以训练出强大的神经网络,帮助机器做出准确的决策。
6. 总结
神经网络的梯度下降就像是一个盲人爬山的故事。通过感觉脚下的坡度,我们可以找到下山 的最佳路径。同样,通过调整网络的连接,我们可以让机器更好地理解数据,做出更准确的 决策。
这个过程可能听起来很复杂,但其实它只是一个简单的迭代过程,目标是找到最佳的网络。通过梯度下降,我们可以训练出强大的机器学习模型,为人工智能的未来铺路。
附录-从头设计梯度下降算法
import numpy as np
def sigmoid(x):
"""Sigmoid activation function."""
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
"""Derivative of the sigmoid function."""
return x * (1 - x)
class NeuralNetwork:
def __init__(self, input_size, hidden_size, output_size):
# Initialize weights and biases
self.weights_input_to_hidden = np.random.rand(input_size, hidden_size)
self.weights_hidden_to_output = np.random.rand(hidden_size, output_size)
self.bias_hidden = np.random.rand(1, hidden_size)
self.bias_output = np.random.rand(1, output_size)
self.learning_rate = 0.01
def forward(self, x):
"""Forward pass through the network."""
self.input = np.array([x])
self.hidden_activation = sigmoid(np.dot(self.input, self.weights_input_to_hidden) + self.bias_hidden)
self.output = sigmoid(np.dot(self.hidden_activation, self.weights_hidden_to_output) + self.bias_output)
return self.output
def backward(self, y):
"""Backward pass to update weights and biases."""
output_error = y - self.output
output_delta = output_error * sigmoid_derivative(self.output)
hidden_error = output_delta.dot(self.weights_hidden_to_output.T)
hidden_delta = hidden_error * sigmoid_derivative(self.hidden_activation)
# Update weights
self.weights_input_to_hidden += self.input.T.dot(hidden_delta) * self.learning_rate
self.weights_hidden_to_output += self.hidden_activation.T.dot(output_delta) * self.learning_rate
# Update biases
self.bias_hidden += np.sum(hidden_delta, axis=0) * self.learning_rate
self.bias_output += np.sum(output_delta, axis=0) * self.learning_rate
def train(self, X, y, epochs):
"""Training the neural network using gradient descent."""
for epoch in range(epochs):
for xi, yi in zip(X, y):
self.forward(xi)
self.backward(yi)
def predict(self, x):
"""Predicting using the trained neural network."""
return self.forward(x)
# Sample usage with dummy data
X = np.array([[0, 0],
[0, 1],
[1, 0],
[1, 1]])
y = np.array([[0], [1], [1], [0]])
nn = NeuralNetwork(input_size=2, hidden_size=4, output_size=1)
nn.train(X, y, epochs=10000)
predictions = nn.predict(X)
predictions
结果为
array([[[0.48384395],
[0.50758334],
[0.50515687],
[0.51856939]]])
下面让我们解释代码的设计及其功能。
激活函数与其导数
我们首先定义了 sigmoid 函数和它的导数 sigmoid_derivative。sigmoid 函数是神经网络中常用的激活函数,它将任何输入转换为0到1之间的值。其导数用于反向传播过程中。
神经网络类定义
这个类表示了一个简单的三层神经网络:输入层、一个隐藏层和输出层。
初始化方法 init
初始化权重和偏置:我们使用随机值初始化权重和偏置。这确保了网络开始时是随机的,随后的训练会调整这些值。
设置学习率:学习率决定了在梯度下降过程中权重更新的步长。
前向传播方法 forward
输入数据通过网络进行传播,生成输出。
输入数据乘以输入层到隐藏层的权重,然后加上偏置,并应用 sigmoid 激活函数。
隐藏层的激活值乘以隐藏层到输出层的权重,然后加上偏置,并应用 sigmoid 激活函数,产生最终输出。
反向传播方法 backward:这是训练神经网络的核心部分。首先,计算输出层的误差(实际输出与预期输出之间的差异)。然后,计算隐藏层的误差。使用这些误差值和 sigmoid_derivative 函数,计算权重和偏置的更新量。最后,根据学习率和更新量调整权重和偏置。
训练方法 train 这个方法使用给定的数据和标签训练网络。对于每个纪元,它都会执行前向和反向传播。
预测方法 predict 一旦网络被训练,这个方法可以用来根据给定的输入数据进行预测。
示例使用 我们使用了一个简单的数据集,包括四个输入和对应的输出。这实际上是一个逻辑异或(XOR)问题,经常用来作为神经网络的一个简单示例。
我们创建了一个神经网络实例,然后使用数据进行了10000个纪元的训练,并最终预测了输入数据的输出。
最后说一下封面的那幅图,我是采用AI生成的,关键词是“gradient decent” 结果就是这样了😂看上去蛮有意思的就留下了哈哈。
参考资料:
Sanderson, G. (2017, October 16). Gradient descent, how neural networks learn. Adapted by J. Pullen. 3Blue1Brown. Updated 2023, August 30. https://www.3blue1brown.com/lessons/gradient-descent