)
教程人工智能机器学习深度学习【免费下载链接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!项目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners点击查看免费下载本实验是 AI for Beginners 课程「感知机Perceptron」一课配套的动手练习核心任务是把课程中用于二分类的感知机代码推广到全部 10 个手写数字通过训练 10 个「一对其余One-vs-All」二分类感知机构建多分类器并在训练集与测试集上计算分类精度、输出混淆矩阵。读完本文你将掌握 One-vs-All 策略、把 10 个感知机权重合并为一次矩阵乘法的推理技巧以及用argmax与confusion_matrix完成多分类预测与评估的完整流程。一、实验背景从二分类感知机到十类数字识别感知机Perceptron是一个二分类模型给定输入向量 x其输出只有两种取值1 或 -1由权重向量 w 与阶跃激活函数共同决定。在 lessons/3-NeuralNetworks/03-Perceptron/README.md 的课程中我们已经用手写实现训练出能够区分两个 MNIST 手写数字如 0 与 1、2 与 5的感知机并观察到其对「2 vs 5」这类较难线性分离的数字对会出现误分类。本实验作业说明原文见 translations/el/lessons/3-NeuralNetworks/03-Perceptron/lab/README.md英文原版见 lessons/3-NeuralNetworks/03-Perceptron/lab/README.md要求将这一能力扩展到完整的数字识别问题实验任务使用本课中为 MNIST 手写数字二分类开发的代码创建一个能够识别任意数字的多分类器。计算其在训练集和测试集上的分类精度并打印混淆矩阵confusion matrix。实验给出了三条关键提示构成了完整的解题思路对每个数字构造一个「该数字 vs 其余所有数字」的二分类数据集训练 10 个不同的二分类感知机每个数字一个定义一个能对输入数字进行分类的函数。关键提示如果把这 10 个感知机的权重合并成一个矩阵就可以通过一次矩阵乘法同时把 10 个感知机应用到输入数字上最可能的数字只需对输出施加argmax操作即可得到。二、感知机核心原理速览在动手前先回顾支撑本实验的感知机数学模型完整推导见 lessons/3-NeuralNetworks/03-Perceptron/Perceptron.ipynb。设模型有 N 个输入特征感知机的输出由公式y(x) f(wᵀx)给出其中 w 为权重向量f 为阶跃激活函数一个通用的线性模型还应当包含偏置项 b即理想情况下应计算y f(wᵀx b)。为简化模型课程代码采用了一个常用技巧给输入特征增加一个恒等于 1 的维度从而把偏置并入权重向量这一技巧在本文的参考实现中同样会用到。训练感知机即寻找能最小化误差的权重 w。误差由感知机准则perceptron criterion定义E(w) -Σ wᵀxᵢ·tᵢ其中求和只针对被错误分类的训练样本 itᵢ 对正例取 1、对负例取 -1。采用梯度下降法从初始权重 w⁽⁰⁾ 出发每步按下式更新w⁽ᵗ⁺¹⁾ w⁽ᵗ⁾ η·Σ xᵢ·tᵢ这里 η 是学习率。需要说明的是感知机是线性分类器只有当两类样本能被一条直线超平面分开时训练才会收敛。课程 notebook 中经典的 XOR 实验表明精度始终无法超过 75%这正是感知机无法解决非线性可分问题的著名案例。本实验将利用 MNIST 数字在 784 维像素空间中「足够线性可分」的特性把线性感知机组合成实用的多分类器。三、环境与数据准备实验的起始 notebook 是 lessons/3-NeuralNetworks/03-Perceptron/lab/PerceptronMultiClass.ipynb其中已包含数据加载、样本展示与感知机训练代码可直接在其基础上完成剩余步骤。实验环境的依赖以 NumPy、Matplotlib、pickle 为核心混淆矩阵部分可选用 scikit-learn。import matplotlib.pyplot as plt import numpy as np import pickle import os import randomMNIST 数据集以 pickle 压缩格式存放在仓库的 data/mnist.pkl.gz包含 60000 张训练手写数字和 10000 张测试手写数字每张是 28×28 像素共 784 个灰度特征。从仓库根目录加载import gzip with gzip.open(data/mnist.pkl.gz, rb) as f: MNIST pickle.load(f, encodinglatin1) # 查看第一个样本的像素区间与标签 print(MNIST[Train][Features][0][130:180]) print(MNIST[Train][Labels][0]) # 像素值归一化到 [0, 1)便于感知机训练 train_features MNIST[Train][Features].astype(np.float32) / 256.0 train_labels MNIST[Train][Labels] test_features MNIST[Test][Features].astype(np.float32) / 256.0 test_labels MNIST[Test][Labels]数据对象的结构为MNIST[Train][Features]、MNIST[Train][Labels]以及对应的MNIST[Test][...]。归一化前的像素取值范围是 0255/256.0将特征缩放到 01 区间这对权重更新幅度的稳定性有帮助。启动 notebook 中还提供了「该数字 vs 另一个数字」的数据集构造函数是后续 One-vs-All 改造的基础def set_mnist_pos_neg(positive_label, negative_label): positive_indices [i for i, j in enumerate(MNIST[Train][Labels]) if j positive_label] negative_indices [i for i, j in enumerate(MNIST[Train][Labels]) if j negative_label] positive_images MNIST[Train][Features][positive_indices] negative_images MNIST[Train][Features][negative_indices] return positive_images, negative_images四、One-vs-All用 10 个二分类感知机构造多分类器4.1 数据集构造从 one-vs-other 到 one-vs-all多分类的核心思想是「分解」一个感知机只会回答「是/否」那就为每个数字准备一个专用感知机让它回答「这个数字 / 不是这个数字」。为此需要把上面的set_mnist_pos_neg改造为 one-vs-all 版本——正类只保留目标数字负类则包含其余全部 9 个数字def one_vs_all(digit): 为数字 digit 构造 该数字 vs 其余所有数字 的数据集 positive_indices [i for i, j in enumerate(MNIST[Train][Labels]) if j digit] negative_indices [i for i, j in enumerate(MNIST[Train][Labels]) if j ! digit] return (MNIST[Train][Features][positive_indices], MNIST[Train][Features][negative_indices])注意负类索引条件从j negative_label变为j ! digit这正是实验提示第 1 条「this digit vs. all other digits」的实现。4.2 感知机训练函数启动 notebook 提供了课程中使用的感知机训练代码随机采样一个正例和一个负例按梯度下降规则更新权重每 10 次迭代报告一次正/负例准确率def train(positive_examples, negative_examples, num_iterations 100): num_dims positive_examples.shape[1] weights np.zeros((num_dims,1)) # 初始化权重为 0 pos_count positive_examples.shape[0] neg_count negative_examples.shape[0] report_frequency 10 for i in range(num_iterations): pos random.choice(positive_examples) neg random.choice(negative_examples) z np.dot(pos, weights) if z 0: # 正例被误判为负例 weights weights pos.reshape(weights.shape) z np.dot(neg, weights) if z 0: # 负例被误判为正例 weights weights - neg.reshape(weights.shape) if i % report_frequency 0: pos_out np.dot(positive_examples, weights) neg_out np.dot(negative_examples, weights) pos_correct (pos_out 0).sum() / float(pos_count) neg_correct (neg_out 0).sum() / float(neg_count) print(Iteration{}, pos correct{}, neg correct{}.format(i,pos_correct,neg_correct)) return weights该实现即梯度下降更新规则w ← w ± x的直接编码当正例输出z 0时把权重朝正例方向拉x当负例输出z ≥ 0时把权重朝反方向拉-x。感知机是线性模型特征维度num_dims由positive_examples.shape[1]决定。由于我们沿用课程中「增加恒为 1 的偏置维度」的技巧训练前应先用下面的辅助函数对特征做增广def add_bias(X): 给特征矩阵追加一列恒为 1 的偏置维度使权重向量包含偏置项 return np.c_[X, np.ones(len(X))]4.3 参考实现训练 10 个感知机对应实验提示第 2 条对 09 每个数字分别训练一个感知机并收集所有权重all_weights [] # 依次存放 10 个感知机的权重 for d in range(10): pos, neg one_vs_all(d) w train(add_bias(pos), add_bias(neg), num_iterations100) all_weights.append(w) # 每个 w 的形状为 (785, 1)训练过程中观察到的正/负例正确率会快速上升初始约 50%随后逼近 90% 以上课程 notebook 中 0 vs 1 实验的真实输出即呈现这一规律。由于「数字 d vs 其余数字」的数据集在多数情况下是近似线性可分的one-vs-all 训练通常可以稳定收敛。五、classify 函数与矩阵乘法技巧对应实验提示第 3 条我们需要定义一个对任意输入图片输出数字 09 的分类函数。朴素做法是逐一运行 10 个感知机取输出分数最高的数字def classify_one(sample, all_weights): 朴素实现依次用 10 个感知机打分取分数最高者作为预测 x np.r_[sample, 1.0] # 补上偏置维度 scores [float(np.dot(x, w)) for w in all_weights] return int(np.argmax(scores))实验还给出了更优雅的向量化方案——把 10 个感知机的权重按列拼成一个矩阵用一次矩阵乘法完成全部 10 次打分即启动 notebook 中「可选用一次矩阵乘法实现改进版 classify」这一步# 将 10 个 (785,1) 权重向量拼成 (785,10) 的矩阵 # 第 d 列就是数字 d 的感知机权重 W np.concatenate(all_weights, axis1) def classify_matrix(X): 一次矩阵乘法同时跑完 10 个感知机再用 argmax 取最可能的数字 Xb np.c_[X, np.ones(len(X))] scores np.dot(Xb, W) # 形状 (N, 10) return np.argmax(scores, axis1)这里scores[i][d]是第 i 个样本在「是否为数字 d」的感知机上的原始得分得分越高说明越像该数字argmax(axis1)逐行取最大值所在列索引即为预测的类别。这与实验提示中「Most probable digit can then be found just by applyingargmaxoperation on the output」完全一致且避免了 Python 循环、充分发挥 NumPy 向量化的性能优势。六、精度评估与混淆矩阵6.1 分类精度课程中二分类精度使用如下辅助函数补上偏置列后与权重点积再比较符号是否与标签一致def accuracy(weights, test_x, test_labels): res np.dot(np.c_[test_x, np.ones(len(test_x))], weights) return (res.reshape(test_labels.shape) * test_labels 0).sum() / float(len(test_labels))多分类场景下直接比较classify_matrix的预测结果与真实标签即可训练集与测试集都要计算def multiclass_accuracy(X, y): return float((classify_matrix(X) y).mean()) print(Train accuracy:, multiclass_accuracy(train_features, train_labels)) print(Test accuracy:, multiclass_accuracy(test_features, test_labels))6.2 打印混淆矩阵混淆矩阵是评估多分类器的最佳可视化工具行代表真实标签列代表预测标签对角线上的数字表示被正确分类的样本数非对角线元素则揭示「某个数字被误认为哪个数字」的系统性错误。实验要求将其打印出来可直接使用 scikit-learnfrom sklearn.metrics import confusion_matrix pred_test classify_matrix(test_features) cm confusion_matrix(test_labels, pred_test) print(cm)阅读矩阵时重点关注两点一是对角线元素是否显著大于同行其他元素整体正确率二是哪些数字对之间存在明显混淆。从课程 notebook 的 PCA 分析可知0 与 1 在降维投影后仍可用直线清楚分开而 2 与 5 很难找到能彻底分离两类样本的投影——因此「2 被误判为 5」之类的非对角线数值通常偏大这是感知机线性分类能力的固有边界而非代码缺陷。七、完整实验步骤与自检清单启动 notebook PerceptronMultiClass.ipynb 中明确列出了需要完成的全部步骤与本文各节一一对应为全部数字创建 10 个one-vs-all数据集第四节训练 10 个感知机第四节定义classify函数完成数字分类第五节测量分类精度并打印混淆矩阵第六节可选用一次矩阵乘法实现改进版classify函数第五节。建议按以下顺序自检确认每个 one-vs-all 数据集中正类样本数 ≈ 该数字样本数负类样本数 ≈ 其余数字样本数之和确认训练前对正、负特征都调用了add_bias使权重维度为 785784 像素 1 偏置确认classify_matrix中scores的列数为 10argmax(axis1)输出形状与标签一致对比训练集与测试集精度若两者差异悬殊需检查是否存在过拟合或负类样本量失衡问题。八、进阶思考与课程衔接为什么可以这样做one-vs-all 把 10 分类问题分解为 10 个二分类问题每个感知机只需找到一个超平面把「该数字」与「其余数字」分开。MNIST 数字在 784 维像素空间中整体近似线性可分因此这套组合方案能够取得可观精度。线性分类器的边界感知机的分类能力与逻辑回归等价。遇到 2 与 5 这类难以线性分离的数字对时训练可能停滞在 85% 左右的精度后续课程将引入多层神经网络等非线性分类器解决该问题并在完整 10 类 MNIST 任务上达到 99% 以上的精度。后续实验的复用本实验训练好的权重矩阵 W 即为一个「无隐藏层的线性分类器」它直观演示了神经网络前向传播中矩阵乘法与 argmax 决策的基础模式是理解课程后续 04-OwnFramework 与 05-Frameworks 中框架实现的重要铺垫。相关仓库文件索引实验说明本文所依据文档translations/el/lessons/3-NeuralNetworks/03-Perceptron/lab/README.md英文原版 lessons/3-NeuralNetworks/03-Perceptron/lab/README.md实验起始 notebook/lessons/3-NeuralNetworks/03-Perceptron/lab/PerceptronMultiClass.ipynb课程讲义lessons/3-NeuralNetworks/03-Perceptron/README.md课程 notebook含二分类实验、XOR 局限、PCA 分析lessons/3-NeuralNetworks/03-Perceptron/Perceptron.ipynbMNIST 数据集data/mnist.pkl.gz赞分享教程人工智能机器学习深度学习【免费下载链接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!项目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners点击查看免费下载相关推荐AI for Beginners 感知机实验指南基于 One-vs-All 策略构建 MNIST 多类数字分类器AI for Beginners 感知机实验指南基于 One vs All 策略构建 MNIST 多类数字分类器 本文为 AI For Beginners 课教程人工智能机器学习深度学习AI-For-Beginners 感知器实验实战用 One-vs-All 策略与 argmax 实现 MNIST 多类数字识别AI For Beginners 感知器实验实战用 One vs All 策略与 argmax 实现 MNIST 多类数字识别 本篇技术指南聚焦 AI For教程人工智能机器学习深度学习AI-For-Beginners 感知机实验实战用 one-vs-all 策略与 10 个二分类感知机构建 MNIST 手写数字多分类器AI For Beginners 感知机实验实战用 one vs all 策略与 10 个二分类感知机构建 MNIST 手写数字多分类器 本篇技术指南以 AI教程人工智能机器学习深度学习上一篇基于 esp-iot-solution 的 ESP32 小智语音 AI 聊天机器人示例详解esp_xiaozhi 组件与流式 ASR LLM TTS 实战下一篇DeepSeek Harness 重复工具调用守护插件 dsh-repeat-tool-reminder循环卫生拦截机制与配置实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考