使用 Python 实现一个简单的神经网络

前天 12阅读

在当今的人工智能和机器学习领域,神经网络是一种非常重要的工具。它模仿人脑的工作方式,通过多个“神经元”层对数据进行处理和学习。本文将介绍如何使用 Python 编写一个简单的全连接前馈神经网络,并用它来解决一个基本的分类问题。

我们将使用 NumPy 来处理矩阵运算,并实现一个两层(输入层 + 隐藏层 + 输出层)的神经网络。最后我们会用这个网络去训练一个小规模的数据集,比如逻辑异或(XOR)问题。


1. 神经网络的基本结构

一个典型的全连接前馈神经网络由输入层、隐藏层和输出层组成。每一层都包含若干个神经元,每个神经元与下一层的所有神经元相连。神经元之间的连接都有权重,这些权重是通过训练过程不断调整的。

我们将在本例中实现一个具有以下结构的神经网络:

输入层:2个节点隐藏层:3个节点(使用 Sigmoid 激活函数)输出层:1个节点(Sigmoid 激活函数)

2. 所需库

我们需要导入 numpy 来进行数值计算:

import numpy as np

3. 定义激活函数及其导数

常用的激活函数之一是 Sigmoid 函数,定义如下:

$$\sigma(x) = \frac{1}{1 + e^{-x}}$$

它的导数形式为:

$$\sigma'(x) = \sigma(x)(1 - \sigma(x))$$

我们将其封装成函数:

def sigmoid(x):    return 1 / (1 + np.exp(-x))def sigmoid_derivative(x):    return x * (1 - x)

4. 初始化网络参数

接下来我们初始化权重和偏置。通常我们会随机初始化权重以打破对称性。

# 输入数据(XOR 问题)X = np.array([[0, 0],              [0, 1],              [1, 0],              [1, 1]])# 标签y = np.array([[0], [1], [1], [0]])# 设置种子以保证结果可重复np.random.seed(42)# 初始化权重input_neurons = 2hidden_neurons = 3output_neurons = 1# 权重矩阵weights_input_hidden = np.random.uniform(size=(input_neurons, hidden_neurons))weights_hidden_output = np.random.uniform(size=(hidden_neurons, output_neurons))# 偏置向量bias_hidden = np.random.uniform(size=(1, hidden_neurons))bias_output = np.random.uniform(size=(1, output_neurons))print("初始权重(输入 -> 隐藏):\n", weights_input_hidden)print("初始权重(隐藏 -> 输出):\n", weights_hidden_output)

5. 前向传播

前向传播是指从输入到输出的一次完整计算过程。

def forward_propagation(X):    # 输入层到隐藏层    hidden_layer_input = np.dot(X, 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)    return hidden_layer_output, output

6. 反向传播与梯度下降

反向传播是根据预测误差调整网络权重的过程。我们使用均方误差作为损失函数:

$$E = \frac{1}{2} \sum (y{true} - y{pred})^2$$

我们通过链式法则计算梯度并更新权重。

def backpropagation(X, y, hidden_layer_output, output):    global weights_input_hidden, weights_hidden_output, bias_hidden, bias_output    learning_rate = 0.1    # 输出层误差    output_error = y - output    output_delta = output_error * sigmoid_derivative(output)    # 隐藏层误差    hidden_error = output_delta.dot(weights_hidden_output.T)    hidden_delta = hidden_error * sigmoid_derivative(hidden_layer_output)    # 更新权重和偏置    weights_hidden_output += hidden_layer_output.T.dot(output_delta) * learning_rate    weights_input_hidden += X.T.dot(hidden_delta) * learning_rate    bias_output += np.sum(output_delta, axis=0, keepdims=True) * learning_rate    bias_hidden += np.sum(hidden_delta, axis=0, keepdims=True) * learning_rate

7. 训练神经网络

我们将整个流程整合起来,进行多次迭代训练:

epochs = 10000for epoch in range(epochs):    hidden_layer_output, output = forward_propagation(X)    backpropagation(X, y, hidden_layer_output, output)    if epoch % 1000 == 0:        loss = np.mean(np.square(y - output))        print(f"Epoch {epoch}, Loss: {loss:.6f}")

8. 测试模型

训练完成后,我们可以用训练好的模型进行预测:

_, predictions = forward_propagation(X)print("\n预测结果:")print(predictions)

预期输出应接近 [0, 1, 1, 0]


9. 完整代码汇总

以下是完整的 Python 神经网络实现代码:

import numpy as np# 激活函数def sigmoid(x):    return 1 / (1 + np.exp(-x))def sigmoid_derivative(x):    return x * (1 - x)# 数据集X = np.array([[0, 0],              [0, 1],              [1, 0],              [1, 1]])y = np.array([[0], [1], [1], [0]])np.random.seed(42)# 初始化参数input_neurons = 2hidden_neurons = 3output_neurons = 1weights_input_hidden = np.random.uniform(size=(input_neurons, hidden_neurons))weights_hidden_output = np.random.uniform(size=(hidden_neurons, output_neurons))bias_hidden = np.random.uniform(size=(1, hidden_neurons))bias_output = np.random.uniform(size=(1, output_neurons))# 前向传播def forward_propagation(X):    hidden_layer_input = np.dot(X, 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)    return hidden_layer_output, output# 反向传播def backpropagation(X, y, hidden_layer_output, output):    global weights_input_hidden, weights_hidden_output, bias_hidden, bias_output    learning_rate = 0.1    output_error = y - output    output_delta = output_error * sigmoid_derivative(output)    hidden_error = output_delta.dot(weights_hidden_output.T)    hidden_delta = hidden_error * sigmoid_derivative(hidden_layer_output)    weights_hidden_output += hidden_layer_output.T.dot(output_delta) * learning_rate    weights_input_hidden += X.T.dot(hidden_delta) * learning_rate    bias_output += np.sum(output_delta, axis=0, keepdims=True) * learning_rate    bias_hidden += np.sum(hidden_delta, axis=0, keepdims=True) * learning_rate# 训练epochs = 10000for epoch in range(epochs):    hidden_layer_output, output = forward_propagation(X)    backpropagation(X, y, hidden_layer_output, output)    if epoch % 1000 == 0:        loss = np.mean(np.square(y - output))        print(f"Epoch {epoch}, Loss: {loss:.6f}")# 预测_, predictions = forward_propagation(X)print("\n预测结果:")print(predictions.round())

10. 总结与扩展

本文通过纯 Python 和 NumPy 实现了一个基础的前馈神经网络,并成功解决了 XOR 分类问题。虽然该网络结构简单,但它展示了神经网络的核心原理:前向传播 + 损失计算 + 反向传播 + 参数更新

未来可以尝试:

使用更复杂的网络结构(如卷积神经网络、循环神经网络)引入更多优化算法(如 Adam、RMSProp)使用 PyTorch 或 TensorFlow 进行深度学习开发应用于图像识别、自然语言处理等领域

如果你对 AI 和机器学习感兴趣,建议继续深入研究相关理论和实践项目,不断提升自己的技术水平。

免责声明:本文来自网站作者,不代表CIUIC的观点和立场,本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。客服邮箱:ciuic@ciuic.com

目录[+]

您是本站第39405名访客 今日有31篇新文章

微信号复制成功

打开微信,点击右上角"+"号,添加朋友,粘贴微信号,搜索即可!