使用Python实现一个简单的神经网络
神经网络是深度学习的核心组成部分,广泛应用于图像识别、自然语言处理、语音识别等领域。本文将通过使用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