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

今天 4阅读

人工神经网络(Artificial Neural Networks, ANNs)是深度学习的核心技术之一,它模拟人脑神经元的工作方式,通过大量数据进行训练,从而完成图像识别、自然语言处理、语音识别等任务。在本文中,我们将使用 Python 从头开始实现一个简单的神经网络,并用它来解决一个基本的分类问题。

我们将使用 numpy 库来进行数值计算,并构建一个具有输入层、隐藏层和输出层的前馈神经网络(Feedforward Neural Network)。最后,我们将使用该网络对一个合成的二分类数据集进行训练和预测。


环境准备

首先,请确保你已经安装了以下库:

pip install numpy matplotlib scikit-learn

神经网络结构概述

我们将构建一个三层神经网络:

输入层:接收特征向量隐藏层:使用 Sigmoid 激活函数输出层:使用 Sigmoid 激活函数,用于二分类任务

损失函数我们使用均方误差(MSE),优化算法使用梯度下降法。


数据准备

为了演示目的,我们将使用 scikit-learnmake_blobs 函数生成一个二维的二分类数据集。

import numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets import make_blobs# 生成数据X, y = make_blobs(n_samples=300, centers=2, cluster_std=1.5, random_state=42)y = y.reshape((-1, 1))  # 转换为列向量# 可视化数据plt.scatter(X[:, 0], X[:, 1], c=y, cmap='coolwarm')plt.title('Generated Binary Classification Dataset')plt.show()

这段代码会生成两个类别的点,并将其可视化。


构建神经网络模型

定义激活函数及其导数

我们使用 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)

初始化参数

接下来定义我们的神经网络类 SimpleNeuralNetwork,并初始化权重和偏置:

class SimpleNeuralNetwork:    def __init__(self, input_dim, hidden_dim, output_dim):        # 初始化权重和偏置        self.W1 = np.random.randn(input_dim, hidden_dim)        self.b1 = np.zeros((1, hidden_dim))        self.W2 = np.random.randn(hidden_dim, output_dim)        self.b2 = np.zeros((1, output_dim))    def forward(self, X):        # 前向传播        self.z1 = X @ self.W1 + self.b1        self.a1 = sigmoid(self.z1)        self.z2 = self.a1 @ self.W2 + self.b2        self.a2 = sigmoid(self.z2)        return self.a2    def compute_loss(self, y_true, y_pred):        # 均方误差损失        return np.mean((y_true - y_pred)**2)    def backward(self, X, y_true, learning_rate=0.01):        # 反向传播        m = X.shape[0]        # 输出层误差        delta2 = (y_pred - y_true) * sigmoid_derivative(y_pred)        dW2 = self.a1.T @ delta2 / m        db2 = np.sum(delta2, axis=0, keepdims=True) / m        # 隐藏层误差        delta1 = delta2 @ self.W2.T * sigmoid_derivative(self.a1)        dW1 = X.T @ delta1 / m        db1 = np.sum(delta1, axis=0, keepdims=True) / m        # 更新参数        self.W2 -= learning_rate * dW2        self.b2 -= learning_rate * db2        self.W1 -= learning_rate * dW1        self.b1 -= learning_rate * db1

训练模型

现在我们可以实例化模型并进行训练:

# 初始化模型nn = SimpleNeuralNetwork(input_dim=2, hidden_dim=4, output_dim=1)# 训练参数epochs = 10000learning_rate = 0.1# 训练过程losses = []for epoch in range(epochs):    y_pred = nn.forward(X)    loss = nn.compute_loss(y, y_pred)    losses.append(loss)    nn.backward(X, y, learning_rate)    if epoch % 1000 == 0:        print(f"Epoch {epoch}, Loss: {loss:.6f}")# 绘制损失曲线plt.plot(losses)plt.title("Training Loss")plt.xlabel("Epoch")plt.ylabel("Loss")plt.show()

随着训练的进行,损失值应该逐渐减小,表示模型正在学习如何更好地拟合数据。


模型评估与预测

我们可以将输出大于等于 0.5 的样本预测为类别 1,小于 0.5 的预测为类别 0:

# 预测y_pred_class = (y_pred >= 0.5).astype(int)# 计算准确率accuracy = np.mean(y_pred_class == y)print(f"Accuracy: {accuracy * 100:.2f}%")

完整代码汇总

以下是完整的代码,你可以直接复制运行:

import numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets import make_blobs# 生成数据X, y = make_blobs(n_samples=300, centers=2, cluster_std=1.5, random_state=42)y = y.reshape((-1, 1))  # 转换为列向量# 可视化数据plt.scatter(X[:, 0], X[:, 1], c=y, cmap='coolwarm')plt.title('Generated Binary Classification Dataset')plt.show()# 激活函数def sigmoid(x):    return 1 / (1 + np.exp(-x))def sigmoid_derivative(x):    return x * (1 - x)# 神经网络类class SimpleNeuralNetwork:    def __init__(self, input_dim, hidden_dim, output_dim):        # 初始化权重和偏置        self.W1 = np.random.randn(input_dim, hidden_dim)        self.b1 = np.zeros((1, hidden_dim))        self.W2 = np.random.randn(hidden_dim, output_dim)        self.b2 = np.zeros((1, output_dim))    def forward(self, X):        # 前向传播        self.z1 = X @ self.W1 + self.b1        self.a1 = sigmoid(self.z1)        self.z2 = self.a1 @ self.W2 + self.b2        self.a2 = sigmoid(self.z2)        return self.a2    def compute_loss(self, y_true, y_pred):        # 均方误差损失        return np.mean((y_true - y_pred)**2)    def backward(self, X, y_true, learning_rate=0.01):        # 反向传播        m = X.shape[0]        # 输出层误差        delta2 = (self.a2 - y_true) * sigmoid_derivative(self.a2)        dW2 = self.a1.T @ delta2 / m        db2 = np.sum(delta2, axis=0, keepdims=True) / m        # 隐藏层误差        delta1 = delta2 @ self.W2.T * sigmoid_derivative(self.a1)        dW1 = X.T @ delta1 / m        db1 = np.sum(delta1, axis=0, keepdims=True) / m        # 更新参数        self.W2 -= learning_rate * dW2        self.b2 -= learning_rate * db2        self.W1 -= learning_rate * dW1        self.b1 -= learning_rate * db1# 初始化模型nn = SimpleNeuralNetwork(input_dim=2, hidden_dim=4, output_dim=1)# 训练参数epochs = 10000learning_rate = 0.1# 训练过程losses = []for epoch in range(epochs):    y_pred = nn.forward(X)    loss = nn.compute_loss(y, y_pred)    losses.append(loss)    nn.backward(X, y, learning_rate)    if epoch % 1000 == 0:        print(f"Epoch {epoch}, Loss: {loss:.6f}")# 绘制损失曲线plt.plot(losses)plt.title("Training Loss")plt.xlabel("Epoch")plt.ylabel("Loss")plt.show()# 预测y_pred = nn.forward(X)y_pred_class = (y_pred >= 0.5).astype(int)# 计算准确率accuracy = np.mean(y_pred_class == y)print(f"Accuracy: {accuracy * 100:.2f}%")

总结

在本文中,我们使用 Python 和 NumPy 实现了一个简单的三层前馈神经网络,并成功地对其进行了训练和测试。虽然这个模型相对简单,但它展示了神经网络的基本原理,包括:

前向传播损失计算反向传播参数更新

如果你有兴趣进一步扩展这个项目,可以尝试:

添加更多的隐藏层使用不同的激活函数(如 ReLU)改用交叉熵损失函数加入正则化防止过拟合将模型封装成可复用的模块

希望这篇文章能帮助你更好地理解神经网络的内部工作原理,并激发你深入探索深度学习的兴趣!

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

目录[+]

您是本站第29160名访客 今日有20篇新文章

微信号复制成功

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