拖动滑块,看看一个神经元的输出是如何计算出来的!
一层就是一组并肩工作的神经元。一个MLP至少有三层:输入层接收原始数据,隐藏层(可以有多层)负责提取复杂的特征,输出层给出最终的预测结果。
信息从输入层开始,逐层向前传递,每一层的神经元都根据上一层的输出进行计算,直到输出层给出一个预测答案。这个过程就像一次性的"猜测"。
网络"学习"和"纠错"的关键。在做出猜测后,网络会将其与正确答案比较,计算出"误差"。然后,这个误差信号会从后向前传播,告诉每一层的连接权重"你们应该如何微调,才能让下次的猜测更准一些"。
MNIST 是一个包含 70,000 张手写数字图像的数据集,每张图片都是 28×28 像素的灰度图像。这是机器学习领域的"Hello World"数据集,非常适合用来学习图像分类。
我们的目标是训练一个神经网络,让它能够识别手写数字(0-9)。这是一个多分类问题,输出层需要 10 个神经元,每个神经元对应一个数字的概率。
在输入神经网络之前,我们需要将图像数据标准化(将像素值从 0-255 缩放到 0-1),这样可以加快训练速度并提高模型性能。
我们使用准确率(Accuracy)来评估模型性能,它表示正确预测的样本比例。对于 MNIST 这样的平衡数据集,准确率是一个很好的评估指标。
激活函数决定神经元的输出是否被"激活",从而引入非线性,使神经网络能够拟合复杂的数据。常见的激活函数包括 Sigmoid、ReLU 和 Tanh。
损失函数用于衡量模型预测与真实标签之间的差距,神经网络的训练目标就是最小化它。分类任务中常用的是交叉熵损失函数(Cross-Entropy Loss)。
学习率是控制神经网络每次参数更新幅度的超参数。学习率太大会导致不稳定,太小则训练缓慢。通常需要结合调参或使用自适应优化器。
不是每次训练都用全部数据,而是分成小批量(如每批 32 张图像)训练,可以提高效率并稳定梯度,是现代深度学习的标准做法。
当模型在训练集上表现很好,但在新数据(测试集)上效果差时,就发生了过拟合。这意味着模型学到了太多训练集的"细节",而不具备泛化能力。
为了防止过拟合,我们可以对模型加入限制,比如 L2 正则化(惩罚过大的参数)或 Dropout(随机丢弃部分神经元),使模型更具泛化能力。
这个动画展示了多层感知机(MLP)在训练过程中的关键步骤:
动画中可以看到:
这个动画展示了神经网络如何识别手写数字:
动画中展示了:
通过修改下方代码,尝试完成以下挑战,观察模型准确率的变化!
hidden_layer_sizes=(128,) 改为
(256,128)),看看模型是否学得更好或更快?
activation='tanh' 或 'relu' 到
MLPClassifier 中),哪个函数带来更高的准确率?
max_iter、batch_size 和
learning_rate_init 参数,探索训练速度与最终效果之间的平衡。
numpy 生成随机数据。sklearn.neural_network 引入 MLPClassifier
构建神经网络模型。StandardScaler 用于对输入数据进行标准化处理。train_test_split 用于将数据拆分为训练集和测试集。time 用于记录模型训练耗时。np.random.rand() 生成 1000 行,每行 784 个特征(模拟 28x28 像素图像)。np.random.randint() 随机生成对应的标签(0 到 9 之间的整数,模拟手写数字)。StandardScaler 将数据标准化,使每个特征均值为 0,方差为 1,有助于加速训练。train_test_split() 将 1000 个样本按 8:2 分成训练集和测试集。MLPClassifier 构建一个具有单隐藏层的多层感知机神经网络。hidden_layer_sizes=(128,) 表示隐藏层包含 128 个神经元。max_iter=20 表示最多训练 20 次(epoch)。early_stopping=True 会在验证集上连续 5 次性能不提升时提前终止训练。validation_fraction=0.1 意味着从训练集中划出 10% 作为验证集用于早停。model.fit(X_train, y_train) 启动训练过程。time.time() 记录并计算耗时。model.score() 分别计算训练集和测试集的准确率。状态: 未训练
最终准确率: N/A
支持上传手写数字图片(JPG、PNG格式)