
教程人工智能机器学习深度学习【免费下载链接】AI-For-Beginners12 Weeks, 24 Lessons, AI for All!项目地址https://gitcode.com/GitHub_Trending/ai/AI-For-Beginners点击查看免费下载本篇技术指南对应 AI-For-Beginners 课程中感知机Perceptron一课的实验Lab任务。课程此前已用感知机完成了 MNIST 手写数字的二分类本实验要求将其扩展为能够识别 0~9 任意数字的多分类器并计算训练集与测试集上的分类准确率、输出混淆矩阵。读完本文你将掌握 One-vs-All 多分类的构造思路、如何复用感知机训练代码训练 10 个二分类器、如何通过argmax完成数字预测以及如何用一次矩阵乘法同时应用全部 10 个感知机的进阶技巧。实验背景从二分类感知机说起感知机Perceptron是最简单的神经网络结构由 Frank Rosenblatt 于 1957 年提出。它是一个二分类模型对于每个输入向量x感知机的输出为 1 或 -1由以下公式计算y(x) f(wᵀx)其中f是阶跃激活函数f(x) 1 当 x ≥ 0 f(x) -1 当 x 0训练感知机的目标是找到一组权重向量w使大部分样本被正确分类即最小化**感知机准则perceptron criterion**定义的误差E(w) -Σ wᵀxᵢtᵢ其中求和只针对被错误分类的训练样本tᵢ对正负样本分别取 1 / -1。通过梯度下降迭代更新权重w(t1) w(t) Σ η·xᵢ·tᵢ其中η是学习率。上述理论在课程讲义中有完整推导。感知机是线性分类器只能区分线性可分的两类数据。MNIST 数据集包含 60000 张手写数字训练样本和 10000 张测试样本均为 28×28 的灰度图每张图即 784 维特征向量。课程在 讲稿 Notebook 中已用感知机完成了0 vs 12 vs 5等二分类任务。本实验的核心挑战是单个感知机只能回答是/否如何让它从 10 个数字中选出一个正确答案实验任务任务原文英文原版见 lab/README.md利用本课中为 MNIST 手写数字二分类开发的代码创建一个能够识别任意数字的多分类器。分别计算训练集与测试集上的分类准确率并输出混淆矩阵confusion matrix。解题思路三条 Hint 与一条关键技巧实验说明给出了三条核心提示外加一条可选的进阶技巧完整继承如下为每个数字构造一个二分类数据集对数字 0~9 中的每一个构建该数字 vs 其他所有数字One-vs-All的二分类训练集训练 10 个不同的感知机每个数字对应一个二分类感知机共 10 个分别负责判断输入是否是数字 k定义分类函数给定一个输入数字综合 10 个感知机的输出判定其最可能属于哪个数字类别。进阶 Hint原文档强调如果把这 10 个感知机的权重合并成一个矩阵就可以通过一次矩阵乘法同时把 10 个感知机应用到输入数字上。然后只需对输出结果执行argmax操作即可找到最可能的数字。这条 Hint 背后的直觉是10 个感知机各自输出一个激活分数wᵀx分数越高代表该感知机越确信输入属于它的数字。哪个感知机的分数最大就把输入判给哪个数字——这正是argmax的含义也是 One-vs-All 多分类的经典范式。起点 Notebook仓库已备好的骨架代码实验以 PerceptronMultiClass.ipynb 为起点。该 Notebook 已替你准备好了数据加载、训练函数和准确率函数需要你在此基础上完成 One-vs-All 扩展。依赖导入import matplotlib.pyplot as plt import numpy as np import pickle import os从课程讲稿复用的感知机训练函数Notebook 中直接给出了课堂上开发的训练函数Notebook 第 50-78 行def train(positive_examples, negative_examples, num_iterations 100): num_dims positive_examples.shape[1] weights np.zeros((num_dims,1)) # 初始化权重 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) # 每 10 轮报告一次当前正负样本准确率 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注意两点权重初始化为全零向量讲稿 Notebook 的版本额外提供了learning_rate参数默认0.01并指出更大的学习率如1.0学得更快但可能越过最优解更小的学习率如0.001收敛更慢但更精细训练中每隔report_frequency 10轮会打印一次正/负样本的分类正确率便于观察收敛过程。准确率函数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_labels0).sum()/float(len(test_labels))见 Notebook 第 102-107 行该函数通过np.c_[test_x, np.ones(...)]为测试特征追加一列全 1 的 bias 维度再与权重做点积并统计预测符号与标签±1一致的比例。这意味着训练特征也应当采用同样的附加 bias 维约定否则权重维度与accuracy()中的test_x维度不匹配——详见下文常见坑。读取 MNIST 数据集Notebook 提供了两种取数方式从网络下载并解压mnist.pkl.gz或直接从本仓库根目录的 data/mnist.pkl.gz 复制讲稿 Notebook 的取数路径即为仓库内的../../../data/mnist.pkl.gz见 Perceptron.ipynb 第 765-766 行。解压后以 pickle 读取with open(mnist.pkl, rb) as mnist_pickle: MNIST pickle.load(mnist_pickle)数据结构为MNIST[Train][Features]训练特征、MNIST[Train][Labels]训练标签以及对应的MNIST[Test]子集。Notebook 中还对训练特征做了归一化展示MNIST[Train][Features].astype(np.float32) / 256.0把像素值从 0~255 缩放到 0~1这对感知机训练的数值稳定性很有帮助。已有的二分类数据构造函数需要你改造Notebook 提供的是两个数字之间的 one-vs-other 数据构造函数第 209-219 行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 版本——正样本仍然是某个数字的全部图像负样本则取除该数字外所有其他数字的图像判定条件从j negative_label改为j ! positive_label。Notebook 中的待办清单Notebook 末尾明确列出了你需要依次完成的工作第 225-231 行为全部 10 个数字创建 10 份 one-vs-all 数据集训练 10 个感知机定义classify函数执行数字分类测量分类准确率并打印混淆矩阵可选改进classify函数使其用一次矩阵乘法完成分类。完整实现One-vs-All 参考解法下面给出一套与仓库骨架代码一致的参考实现注意训练与测试特征统一附加 bias 维。第 1 步构造 10 个 one-vs-all 数据集def get_one_vs_all(positive_label, mnist): 为指定数字构造 one-vs-all 数据集 positive_indices [i for i, j in enumerate(mnist[Labels]) if j positive_label] negative_indices [i for i, j in enumerate(mnist[Labels]) if j ! positive_label] # 关键改动其余全是负样本 positive_images mnist[Features][positive_indices] negative_images mnist[Features][negative_indices] return positive_images, negative_images def add_bias(X): 附加全 1 的 bias 列与 accuracy() 的约定保持一致 return np.c_[X, np.ones(len(X))]第 2 步训练 10 个感知机weights [] # 存放 10 个感知机的权重每个形状为 (785, 1) for digit in range(10): pos, neg get_one_vs_all(digit, MNIST[Train]) pos, neg add_bias(pos), add_bias(neg) # 训练特征也加 bias 维 w train(pos, neg) weights.append(w)训练过程中观察每 10 轮的打印输出正负样本正确率应逐步攀升。这里可以直接复用train()函数无需改动训练算法本身——多分类能力不是靠改算法而是靠10 个二分类器投票组合出来的。第 3 步定义 classify 函数def classify(x, weights): 返回输入数字 x 最可能属于的类别 0~9 x_b np.r_[x, 1] # 与训练一致附加 bias 维 scores np.array([np.dot(x_b, w)[0] for w in weights]) # 10 个感知机的分数 return np.argmax(scores) # 取分数最大的类别classify对单个样本分别计算 10 个感知机的激活值argmax返回得分最高的感知机所对应的数字。第 4 步计算训练/测试准确率并打印混淆矩阵def compute_accuracy(features, labels, weights): X add_bias(features) preds [classify(x, weights) for x in X] return np.mean(preds labels) print(Train accuracy:, compute_accuracy(MNIST[Train][Features], MNIST[Train][Labels], weights)) print(Test accuracy:, compute_accuracy(MNIST[Test][Features], MNIST[Test][Labels], weights))混淆矩阵可用sklearn.metrics.confusion_matrixsklearn 在讲稿 Notebook 中已有使用输出行表示真实标签、列表示预测标签对角线元素即各类别被正确识别的数量非对角线元素暴露了哪些数字之间容易混淆——例如 2 与 5、3 与 8 常出现互相误判。进阶用一次矩阵乘法替代 10 次点积按实验说明的 Hint把 10 个权重向量横向拼接成一个大矩阵即可向量化批量打分# 将 10 个 (785,1) 权重向量拼接为 (785, 10) 的权重矩阵 W np.hstack(weights) # 对整批样本一次矩阵乘法X_bias 形状 (N, 785)结果形状 (N, 10) scores np.dot(add_bias(X), W) preds np.argmax(scores, axis1) # 每行取分数最大的列索引这一写法不仅代码更简洁也充分体现了 Hint 中所有感知机权重合并为矩阵 一次矩阵乘法 argmax的设计思想并且便于直接向量化计算准确率与混淆矩阵。常见坑与原理剖析bias 维度的一致性Notebook 提供的accuracy()内部用np.c_[test_x, np.ones(...)]补了一列 bias而train()的权重维度取决于传入特征的列数。因此建议在训练前就给正/负样本统一附加 bias 列保证权重维度为 785与accuracy()及classify()的约定吻合。这也正是讲稿 Notebook 在玩具问题中显式增加一维恒为 1 的特征来消去偏置项的做法。特征归一化将像素值除以 256.0 归一化到 [0,1] 区间可显著改善梯度下降的数值稳定性建议在训练前对训练与测试特征统一处理。线性可分性的边界感知机本质是线性分类器。讲稿中通过 PCA 降维分析发现0 vs 1在二维投影下可用直线清晰分开而2 vs 5难以找到好的分离投影因此 2 与 5 之间会出现误判Perceptron.ipynb 讨论小节。One-vs-All 方案把 10 类问题拆成 10 个二分类每个二分类仍然受限于线性可分性——这正是实验预期观察到的现象不必追求完美准确率。类别不平衡One-vs-All 中每个感知机的负样本约为正样本的 9 倍。train()每轮只随机抽取一对正负样本可以缓解不平衡影响如需进一步提升可考虑在每轮迭代中按比例采样。XOR 局限单层感知机无法解决 XOR 这类非线性问题讲稿中有专门演示准确率始终不超过 75%这是后续课程引入多层神经网络的动机。学习路径与延伸完成本实验后建议进一步重读课程讲义与讲稿 Notebook巩固感知机准则、梯度下降推导与学习率影响用滑块交互式观察不同学习率0.001~1.0下决策边界的变化理解收敛速度与稳定性之间的权衡在后续课程中学习多层神经网络、卷积网络等非线性分类器——讲稿预告借助神经网络可将 MNIST 十分类准确率提升至 99% 以上并能解决数字不对齐等问题。相关资源索引本实验英文原版说明lessons/3-NeuralNetworks/03-Perceptron/lab/README.md起始 Notebook含骨架代码与待办清单lessons/3-NeuralNetworks/03-Perceptron/lab/PerceptronMultiClass.ipynb课程讲义与理论推导lessons/3-NeuralNetworks/03-Perceptron/README.md讲稿 NotebookMNIST 二分类、PCA、XOR 演示lessons/3-NeuralNetworks/03-Perceptron/Perceptron.ipynbMNIST 数据集pickle/gzip 格式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 Beginn教程人工智能机器学习深度学习AI-For-Beginners 感知器实验实战用 One-vs-All 策略与 argmax 实现 MNIST 多类数字识别AI For Beginners 感知器实验实战用 One vs All 策略与 argmax 实现 MNIST 多类数字识别 本篇技术指南聚焦 AI For教程人工智能机器学习深度学习AI-For-Beginners 实验指南用感知机实现 MNIST 多类数字分类One-vs-AllAI For Beginners 实验指南用感知机实现 MNIST 多类数字分类One vs All 导读 本篇文章围绕 AI For Beginners教程人工智能机器学习深度学习上一篇Draggable 实战指南使用 Droppable 模块实现可拖放元素与 Dropzone 交互下一篇electron-vue 测试指南Karma Mocha 单元测试与 Spectron 端到端测试全解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考