自己动手实现一个神经网络多分类器

本文介绍了如何不依赖深度学习框架,手动实现一个简单的神经网络多分类器。首先通过生成非线性可分数据,训练Softmax线性分类器,然后探讨了softmax和交叉熵损失在多分类中的作用。接着,作者构建了一个神经网络,显著提高了分类效果,并展示了训练前后决策边界的对比。最后提供了联系方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文由**罗周杨stupidme.me.lzy@gmail.com**原创,转载请注明作者和出处。未经授权,不得用于商业用途。

不使用任何深度学习框架,实现一个简单的神经网络用来分类。
手把手带你搭建神经网络,包括损失函数的选择,已经手写反向传播代码。

生成一些数据

生成一些数据,这些数据不太容易线性分类。

import numpy as np
import matplotlib.pyplot as plt

N = 100 # 每一个类别的生成的点的数量
D = 2 # 每个点的维度,这里使用平面,所以是2维数据
K = 3 # 类别数量,我们一共生成3个类别的点

# 所有的样本数据,一共300个点,每个点用2个维度表示
# 所有训练数据就是一个300*2的二维矩阵
X = np.zeros((N*K, D))
# 标签数据,一共是300个点,每个点对应一个类别,
# 所以标签是一个300*1的矩阵
y = np.zeros(N*K, dtype='uint8')

# 生成训练数据
for j in range(K):
    ix = range(N*j, N*(j+1))
    r = np.linspace(0.0, 1, N)
    t = np.linspace(j*4, (j+1)*4, N) + np.random.randn(N)*0.2
    X[ix] = np.c_[r*np.sin(t), r*np.cos(t)]
    y[ix] = j
    
plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.Spectral)
plt.show()

训练一个Softmax线性分类器

使用softmax和cross-entropy loss,训练一个线性分类器。

实际上就是直接用softmax做多分类,使用交叉熵损失作为损失函数,训练一个线性分类模型。

import numpy as np
import matplotlib.pyplot as plt

N = 100
D = 2
K = 3
X = np.zeros((N*K, D))
y = np.zeros(N*K, dtype='uint8')

for j in range(K):
    ix = range(N*j, N*(j+1))
    r = np.linspace(0.0, 1, N)
    t = np.linspace(j*4, (j+1)*4, N) + np.random.randn(N)*0.2
    X[ix] = np.c_[r*np.sin(t), r*np.cos(t)]
    y[ix] = j
    
# plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.Spectral)
# plt.show()

# 初始化权重和偏置
W = 0.01 * np.random.randn(D, K)
b = np.zeros((1, K))

step_size = 1e-0
reg = 1e-3 # regularization strength


# 获取训练样本数量
num_examples = X
<think>嗯,用户让我帮他实现一个神经网络算法。首先,我需要确定他的需求是什么。他可能是一个刚开始学习机器学习的新手,或者有编程经验但想了解神经网络的具体实现。用户提到“帮我实现”,所以可能需要一个简单的示例代码,比如用Python和NumPy从头开始构建一个基础的前馈神经网络。 接下来,我需要考虑用户的背景知识。如果他刚入门,可能需要解释神经网络的基本概念,比如层、激活函数、损失函数和反向传播。同时,代码需要尽可能简洁,避免使用高级库如TensorFlow或PyTorch,而是用基础的NumPy来展示原理。 然后,我需要决定网络的结构。通常,一个包含输入层、隐藏层和输出层的三层网络比较适合教学。激活函数方面,ReLU在隐藏层常用,输出层用Sigmoid或Softmax,这里可能用Sigmoid做二分类示例。 数据部分,可能需要生成一些随机数据或者使用简单数据集,但为了示例,使用合成数据更方便。比如,用XOR问题或者线性可分的数据。不过XOR是非线性问题,可以展示神经网络的非线性处理能力。 接下来是初始化权重,要注意不能全为零,使用随机初始化,比如He初始化。然后实现前向传播,计算各层的输出,应用激活函数。损失函数这里用均方误差,虽然分类问题常用交叉熵,但MSE更简单,适合示例。 反向传播部分需要详细解释梯度计算,链式法则的应用,权重更新使用梯度下降。可能需要逐步推导损失对各个参数的梯度,但在代码中用向量化操作实现会更高效。 最后,训练循环部分,设置迭代次数和学习率,输出训练过程中的损失变化,让用户看到模型在学习。 检查代码是否存在错误,比如矩阵乘法的维度是否正确,激活函数的导数是否正确,梯度计算是否有误。同时,确保示例足够简单,用户能理解每一步的作用,并可以自行调整层数和参数进行实验。 可能用户还想知道如何扩展这个网络,比如增加更多层,调整超参数,或者应用到真实数据集上。因此,在解释中可以提到这些扩展方向,并建议使用更高级的库来简化实现。 总结,回答的结构应该是先介绍神经网络的基本概念,然后分步骤解释代码的每个部分,提供完整的示例,并讨论可能的改进和注意事项,确保用户能够理解并自己动手实现。</think>以下是一个基础神经网络算法的实现指南,包含关键概念和Python代码示例。我们将以三层全连接网络为例,使用NumPy实现手写数字识别功能(基于MNIST数据集简化版): 一、神经网络核心概念 1. 网络结构示意图: 输入层(784) → 隐藏层(128, ReLU) → 输出层(10, Softmax) 二、代码实现步骤 ```python import numpy as np from sklearn.datasets import load_digits from sklearn.preprocessing import OneHotEncoder # 初始化参数(He初始化) def init_params(): W1 = np.random.randn(64, 128) * np.sqrt(2/64) # 输入层到隐藏层 b1 = np.zeros((1, 128)) W2 = np.random.randn(128, 10) * np.sqrt(2/128) # 隐藏层到输出层 b2 = np.zeros((1, 10)) return W1, b1, W2, b2 # ReLU激活函数 def relu(Z): return np.maximum(0, Z) # Softmax激活函数 def softmax(Z): exp = np.exp(Z - np.max(Z)) return exp / exp.sum(axis=1, keepdims=True) # 前向传播 def forward_prop(X, W1, b1, W2, b2): Z1 = X.dot(W1) + b1 A1 = relu(Z1) Z2 = A1.dot(W2) + b2 A2 = softmax(Z2) return Z1, A1, Z2, A2 # 反向传播 def backward_prop(X, Y, Z1, A1, Z2, A2, W2): m = X.shape[0] dZ2 = A2 - Y dW2 = (A1.T.dot(dZ2)) / m db2 = np.sum(dZ2, axis=0, keepdims=True) / m dZ1 = (dZ2.dot(W2.T)) * (Z1 > 0) # ReLU导数 dW1 = (X.T.dot(dZ1)) / m db1 = np.sum(dZ1, axis=0, keepdims=True) / m return dW1, db1, dW2, db2 # 训练函数 def train(X, Y, epochs=1000, lr=0.1): W1, b1, W2, b2 = init_params() for i in range(epochs): Z1, A1, Z2, A2 = forward_prop(X, W1, b1, W2, b2) dW1, db1, dW2, db2 = backward_prop(X, Y, Z1, A1, Z2, A2, W2) # 参数更新 W1 -= lr * dW1 b1 -= lr * db1 W2 -= lr * dW2 b2 -= lr * db2 # 每100次输出损失 if i % 100 == 0: loss = -np.mean(Y * np.log(A2)) print(f"Epoch {i}, Loss: {loss:.4f}") return W1, b1, W2, b2 # 加载数据 digits = load_digits() X = digits.data / 16.0 # 归一化到0-1 Y = OneHotEncoder(sparse=False).fit_transform(digits.target.reshape(-1,1)) # 训练网络 W1, b1, W2, b2 = train(X, Y, epochs=1000, lr=0.1) ``` 三、关键改进(可根据需求添加) 1. 增加批量归一化层 2. 实现Dropout正则化 3. 改用交叉熵损失函数 4. 添加L2正则化项 5. 实现Adam优化器 6. 增加验证集早停机制 四、实际应用建议 1. 对于真实项目建议使用成熟框架(PyTorch/TensorFlow) 2. 数据预处理需要加强(标准化、数据增强) 3. 超参数需要系统调优(学习率、网络深度等) 4. 需要添加模型评估模块(准确率计算等) 这个实现展示了神经网络的核心机制,实际应用中还需考虑: - 更高效的矩阵运算 - GPU加速支持 - 更复杂的网络结构 - 正则化技术应用 - 完善的评估体系 需要进一步调整或解释哪个部分可以随时告诉我!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值