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

06-25 15阅读

神经网络是深度学习的核心组成部分,广泛应用于图像识别、自然语言处理、语音识别等领域。本文将通过使用Python手动实现一个简单的全连接前馈神经网络(Feedforward Neural Network),帮助读者理解神经网络的基本原理和工作流程。

我们将从头开始构建神经网络,包括数据准备、模型定义、损失函数计算、反向传播优化等步骤,并最终在简单的分类任务上进行测试。


1. 环境准备

我们使用以下库:

numpy:用于数值计算matplotlib:用于绘图sklearn.datasets:用于生成样本数据

安装命令如下:

pip install numpy matplotlib scikit-learn

2. 导入必要的库

import numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets import make_blobs

3. 生成数据集

我们使用make_blobs生成一个二维的多类别分类问题数据集,方便可视化。

X, y = make_blobs(n_samples=300, centers=3, n_features=2, random_state=42)plt.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis')plt.title("Generated Data")plt.show()

输出结果应为一个二维散点图,展示三个类别的分布。


4. 数据预处理

我们需要将标签进行 One-Hot 编码,并对输入特征进行归一化处理。

def one_hot_encode(y, num_classes):    return np.eye(num_classes)[y]def normalize(X):    mean = np.mean(X, axis=0)    std = np.std(X, axis=0)    return (X - mean) / (std + 1e-8)# 预处理X = normalize(X)y_one_hot = one_hot_encode(y, num_classes=3)

5. 定义神经网络结构

我们构建一个具有单个隐藏层的神经网络:

输入层:2个节点隐藏层:4个节点输出层:3个节点(对应三分类)

激活函数采用ReLU和Softmax。

class SimpleNeuralNetwork:    def __init__(self, input_size, hidden_size, output_size):        self.params = {            'W1': np.random.randn(input_size, hidden_size),            'b1': np.zeros(hidden_size),            'W2': np.random.randn(hidden_size, output_size),            'b2': np.zeros(output_size)        }    def forward(self, X):        W1, b1, W2, b2 = self.params['W1'], self.params['b1'], self.params['W2'], self.params['b2']        Z1 = X @ W1 + b1        A1 = self.relu(Z1)        Z2 = A1 @ W2 + b2        A2 = self.softmax(Z2)        cache = (Z1, A1, Z2, A2)        return A2, cache    def relu(self, x):        return np.maximum(0, x)    def softmax(self, x):        exps = np.exp(x - np.max(x, axis=1, keepdims=True))        return exps / np.sum(exps, axis=1, keepdims=True)    def cross_entropy_loss(self, y_pred, y_true):        m = y_true.shape[0]        log_likelihood = -np.log(y_pred[range(m), y_true.argmax(axis=1)] + 1e-15)        loss = np.sum(log_likelihood) / m        return loss    def backward(self, X, y_true, cache, learning_rate=0.01):        W1, b1, W2, b2 = self.params['W1'], self.params['b1'], self.params['W2'], self.params['b2']        Z1, A1, Z2, A2 = cache        m = X.shape[0]        # 计算梯度        dZ2 = A2 - y_true        dW2 = A1.T @ dZ2 / m        db2 = np.sum(dZ2, axis=0) / m        dA1 = dZ2 @ W2.T        dZ1 = dA1 * (Z1 > 0)        dW1 = X.T @ dZ1 / m        db1 = np.sum(dZ1, axis=0) / m        # 更新参数        self.params['W2'] -= learning_rate * dW2        self.params['b2'] -= learning_rate * db2        self.params['W1'] -= learning_rate * dW1        self.params['b1'] -= learning_rate * db1

6. 模型训练

我们训练该模型500轮,每100轮打印一次损失值。

nn = SimpleNeuralNetwork(input_size=2, hidden_size=4, output_size=3)losses = []for epoch in range(500):    y_pred, cache = nn.forward(X)    loss = nn.cross_entropy_loss(y_pred, y_one_hot)    losses.append(loss)    if epoch % 100 == 0:        print(f"Epoch {epoch}, Loss: {loss:.4f}")    nn.backward(X, y_one_hot, cache, learning_rate=0.1)# 绘制损失曲线plt.plot(losses)plt.title("Training Loss Curve")plt.xlabel("Epoch")plt.ylabel("Loss")plt.show()

7. 模型评估

我们可以将预测结果与真实标签对比,查看准确率。

y_pred, _ = nn.forward(X)predicted_classes = np.argmax(y_pred, axis=1)accuracy = np.mean(predicted_classes == y)print(f"Accuracy: {accuracy * 100:.2f}%")

8. 可视化决策边界

为了更直观地观察模型效果,我们可以绘制决策边界。

def plot_decision_boundary(model, X, y):    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1    xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),                         np.arange(y_min, y_max, 0.01))    grid = np.c_[xx.ravel(), yy.ravel()]    probs, _ = model.forward(grid)    preds = np.argmax(probs, axis=1)    preds = preds.reshape(xx.shape)    plt.contourf(xx, yy, preds, alpha=0.4, cmap='viridis')    plt.scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor='k', cmap='viridis')    plt.title("Decision Boundary")    plt.show()plot_decision_boundary(nn, X, y)

9. 总结

在本文中,我们使用纯Python实现了一个人工神经网络模型,涵盖了:

数据生成与预处理前向传播与反向传播激活函数(ReLU、Softmax)损失函数(交叉熵)参数更新(梯度下降)模型评估与可视化

虽然这个模型比较简单,但它是理解深度学习模型工作原理的良好起点。未来可以扩展的方向包括添加更多的隐藏层、使用不同的优化器(如Adam)、正则化技术(如Dropout)等。


10. 参考资料

Deep Learning Specialization by Andrew NgCS231n Convolutional Neural Networks for Visual RecognitionScikit-learn Documentation

如果你觉得这篇文章对你有帮助,欢迎点赞或分享给更多人阅读!

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

目录[+]

您是本站第336名访客 今日有39篇新文章

微信号复制成功

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