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

59分钟前 3阅读

在现代人工智能和机器学习领域,神经网络(Neural Networks)是一种非常强大的工具。它模仿人脑的工作方式,通过多个层级的节点(神经元)来处理信息,并完成诸如图像识别、自然语言处理、语音识别等任务。

本文将从零开始,使用 Python 和 NumPy 实现一个简单的三层前馈神经网络(Feedforward Neural Network),并用于解决一个基本的二分类问题。我们将介绍神经网络的基本结构、损失函数、反向传播算法以及如何用代码实现这些步骤。


神经网络概述

一个基本的三层神经网络包括:

输入层(Input Layer)隐藏层(Hidden Layer)输出层(Output Layer)

每一层都由若干个“神经元”组成,每个神经元与下一层的所有神经元相连。连接的强度由权重(weights)决定,同时每个神经元还有一个偏置项(bias)。

我们使用的激活函数是 Sigmoid 函数,其公式如下:

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

它的导数为:

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


数据准备

为了演示目的,我们使用一个简单的二维二分类数据集。我们可以使用 sklearn.datasets.make_blobs 来生成一些样本点。

import numpy as npfrom sklearn.datasets import make_blobsimport matplotlib.pyplot as plt# 生成2维数据,两个类别X, y = make_blobs(n_samples=300, centers=2, cluster_std=1.5, random_state=42)y = y.reshape(-1, 1)print("输入数据形状:", X.shape)print("标签数据形状:", y.shape)

输出:

输入数据形状: (300, 2)标签数据形状: (300, 1)

构建神经网络模型

我们定义一个包含以下部分的类:

初始化函数(构造权重和偏置)前向传播函数损失函数(交叉熵)反向传播函数训练函数

3.1 定义神经网络类

class SimpleNeuralNetwork:    def __init__(self, input_size, hidden_size, output_size):        # 初始化参数        self.W1 = np.random.randn(input_size, hidden_size)        self.b1 = np.zeros((1, hidden_size))        self.W2 = np.random.randn(hidden_size, output_size)        self.b2 = np.zeros((1, output_size))    def sigmoid(self, x):        return 1 / (1 + np.exp(-x))    def sigmoid_derivative(self, x):        return x * (1 - x)    def forward(self, X):        # 前向传播        self.z1 = np.dot(X, self.W1) + self.b1        self.a1 = self.sigmoid(self.z1)        self.z2 = np.dot(self.a1, self.W2) + self.b2        self.a2 = self.sigmoid(self.z2)        return self.a2    def compute_loss(self, y_true, y_pred):        # 交叉熵损失函数        m = y_true.shape[0]        loss = -np.sum(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred)) / m        return loss    def backward(self, X, y, learning_rate=0.01):        # 反向传播        m = X.shape[0]        # 输出层误差        dz2 = self.a2 - y        dW2 = np.dot(self.a1.T, dz2) / m        db2 = np.sum(dz2, axis=0, keepdims=True) / m        # 隐藏层误差        da1 = np.dot(dz2, self.W2.T)        dz1 = da1 * self.sigmoid_derivative(self.a1)        dW1 = np.dot(X.T, dz1) / m        db1 = np.sum(dz1, axis=0, keepdims=True) / m        # 更新参数        self.W1 -= learning_rate * dW1        self.b1 -= learning_rate * db1        self.W2 -= learning_rate * dW2        self.b2 -= learning_rate * db2    def train(self, X, y, epochs=1000, learning_rate=0.01, print_loss=True):        losses = []        for epoch in range(epochs):            y_pred = self.forward(X)            loss = self.compute_loss(y, y_pred)            losses.append(loss)            self.backward(X, y, learning_rate)            if print_loss and (epoch % 100 == 0 or epoch == epochs - 1):                print(f"Epoch {epoch}: Loss = {loss:.6f}")        return losses

训练模型

接下来我们实例化模型并进行训练。

# 创建模型input_size = 2hidden_size = 4output_size = 1model = SimpleNeuralNetwork(input_size, hidden_size, output_size)# 开始训练losses = model.train(X, y, epochs=1000, learning_rate=0.1)# 绘制损失曲线plt.plot(losses)plt.xlabel("Epoch")plt.ylabel("Loss")plt.title("Training Loss Curve")plt.show()

评估模型性能

我们可以计算预测准确率来评估模型的表现。

def accuracy(y_true, y_pred):    predictions = (y_pred > 0.5).astype(int)    correct = np.sum(predictions == y_true)    return correct / len(y_true)# 预测y_pred = model.forward(X)acc = accuracy(y, y_pred)print(f"模型准确率:{acc * 100:.2f}%")

输出示例:

模型准确率:98.67%

可视化决策边界

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

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()]    Z = model.forward(grid)    Z = (Z > 0.5).astype(int)    Z = Z.reshape(xx.shape)    plt.contourf(xx, yy, Z, alpha=0.4)    plt.scatter(X[:, 0], X[:, 1], c=y.ravel(), s=20, edgecolor='k')    plt.xlabel("Feature 1")    plt.ylabel("Feature 2")    plt.title("Decision Boundary")    plt.show()plot_decision_boundary(model, X, y)

总结

通过本文,我们完成了以下工作:

理解了神经网络的基本结构。使用 Python 和 NumPy 构建了一个三层前馈神经网络。实现了前向传播、损失计算、反向传播和梯度下降优化。对模型进行了训练和评估。可视化了决策边界以帮助理解模型行为。

虽然这是一个基础的神经网络实现,但它展示了深度学习模型的核心思想。对于更复杂的任务,可以考虑使用如 PyTorch 或 TensorFlow 等深度学习框架,它们提供了更高效的自动求导和GPU加速功能。


附录:完整代码清单

import numpy as npfrom sklearn.datasets import make_blobsimport matplotlib.pyplot as pltclass SimpleNeuralNetwork:    def __init__(self, input_size, hidden_size, output_size):        self.W1 = np.random.randn(input_size, hidden_size)        self.b1 = np.zeros((1, hidden_size))        self.W2 = np.random.randn(hidden_size, output_size)        self.b2 = np.zeros((1, output_size))    def sigmoid(self, x):        return 1 / (1 + np.exp(-x))    def sigmoid_derivative(self, x):        return x * (1 - x)    def forward(self, X):        self.z1 = np.dot(X, self.W1) + self.b1        self.a1 = self.sigmoid(self.z1)        self.z2 = np.dot(self.a1, self.W2) + self.b2        self.a2 = self.sigmoid(self.z2)        return self.a2    def compute_loss(self, y_true, y_pred):        m = y_true.shape[0]        loss = -np.sum(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred)) / m        return loss    def backward(self, X, y, learning_rate=0.01):        m = X.shape[0]        dz2 = self.a2 - y        dW2 = np.dot(self.a1.T, dz2) / m        db2 = np.sum(dz2, axis=0, keepdims=True) / m        da1 = np.dot(dz2, self.W2.T)        dz1 = da1 * self.sigmoid_derivative(self.a1)        dW1 = np.dot(X.T, dz1) / m        db1 = np.sum(dz1, axis=0, keepdims=True) / m        self.W1 -= learning_rate * dW1        self.b1 -= learning_rate * db1        self.W2 -= learning_rate * dW2        self.b2 -= learning_rate * db2    def train(self, X, y, epochs=1000, learning_rate=0.01, print_loss=True):        losses = []        for epoch in range(epochs):            y_pred = self.forward(X)            loss = self.compute_loss(y, y_pred)            losses.append(loss)            self.backward(X, y, learning_rate)            if print_loss and (epoch % 100 == 0 or epoch == epochs - 1):                print(f"Epoch {epoch}: Loss = {loss:.6f}")        return losses# 数据生成X, y = make_blobs(n_samples=300, centers=2, cluster_std=1.5, random_state=42)y = y.reshape(-1, 1)# 模型训练model = SimpleNeuralNetwork(2, 4, 1)losses = model.train(X, y, epochs=1000, learning_rate=0.1)# 准确率计算def accuracy(y_true, y_pred):    predictions = (y_pred > 0.5).astype(int)    correct = np.sum(predictions == y_true)    return correct / len(y_true)y_pred = model.forward(X)acc = accuracy(y, y_pred)print(f"模型准确率:{acc * 100:.2f}%")# 决策边界可视化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()]    Z = model.forward(grid)    Z = (Z > 0.5).astype(int)    Z = Z.reshape(xx.shape)    plt.contourf(xx, yy, Z, alpha=0.4)    plt.scatter(X[:, 0], X[:, 1], c=y.ravel(), s=20, edgecolor='k')    plt.xlabel("Feature 1")    plt.ylabel("Feature 2")    plt.title("Decision Boundary")    plt.show()plot_decision_boundary(model, X, y)

如需进一步扩展该模型,可以尝试添加更多隐藏层、使用不同的激活函数(如 ReLU)、正则化技术或引入批量训练机制。希望这篇文章能帮助你更好地理解和动手实践神经网络!

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

目录[+]

您是本站第65293名访客 今日有9篇新文章

微信号复制成功

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