十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ML-For-Beginners 分类实战:用 Scikit-learn 训练菜品分类模型,转 ONNX 后在浏览器中跑推荐 Web 应用

ML-For-Beginners 分类实战:用 Scikit-learn 训练菜品分类模型,转 ONNX 后在浏览器中跑推荐 Web 应用 ML-For-Beginners 分类实战用 Scikit-learn 训练菜品分类模型转 ONNX 后在浏览器中跑推荐 Web 应用【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners本文基于 ML-For-Beginners 课程第 4 节分类的 Applied 课完整走通一条Python 训练 → ONNX 转换 → 浏览器端 ONNX Runtime 推理的模型落地链路用 380 个食材特征训练一个五国菜系分类器把 Scikit-learn 模型转成 ONNX 文件再写一个纯前端的index.html让用户勾选冰箱里的食材后由模型推荐能做的菜系。读完后你将掌握如何确定 ONNX 输入张量维度、如何用nocl/zipmap选项精简模型、如何用 Netron 可视化模型结构以及如何用 ONNX Runtime Web 在浏览器中完成一次完整的同步推理。一、课程定位从 Flask 全栈应用到浏览器端推理这是 ML-For-Beginners 课程12 周、26 课时第 4 周Classification的最后一课承接前面的 Introduction to classification、More classifiers、Yet other classifiers。课程大纲见 4-Classification/README.md。推荐系统是机器学习最实用的方向之一本课正是迈出第一步用本系列一直在用的亚洲与印度菜系数据集训练分类模型并构建一个小型 Web 应用来调用保存好的模型。与之前 第 3 周 Web 应用课用 pickle 保存 UFO 回归模型并在 Flask 中调用不同这一课的目标架构是纯 JavaScript 前端——没有 Python 后端模型以 ONNX 文件形式放在静态网页旁边由浏览器直接加载推理甚至可以离线运行。整条链路为cleaned_cuisines.csv3995 条记录380 个食材特征 │ Scikit-learn SVC(kernellinear, C10) ▼ model.onnxskl2onnx 转换输入 float_input: [None, 380] │ ONNX Runtime Webort.min.jsCDN 引入 ▼ index.html勾选食材 → Float32Array → 浏览器内推理 → alert 推荐菜系二、数据集380 维 one-hot 食材向量本课使用 4-Classification/data/cleaned_cuisines.csv。查看该文件可以确认其结构共 3996 行表头 1 行 数据 3995 行共 382 列第 1 列是数字序号0、1、2…第 2 列是cuisine标签其余380 列全部是食材每列取值为 0/1该菜品是否使用该食材标签为 5 个菜系chinese、indian、japanese、korean、thai各 799 条完全均衡。另外配套一张索引表 4-Classification/data/ingredient_indexes.csv第一行按字母序列出 380 个食材名第二行是对应的 0 起始索引0–379。这张表在后端前端开发中很关键——网页上每个复选框的value就是食材在这张表中的索引例如apple排在第 5 位索引为 4。从数据形态看每一行已经是一个现成的特征向量跳过前 2 列序号和标签剩下的 380 列就是模型的输入。这也是后面 ONNX 张量必须声明为[None, 380]的原因。三、训练分类模型1. 环境与数据准备首先在 notebook 中安装转换工具并引入 pandas!pip install skl2onnx import pandas as pdskl2onnx的作用是把训练好的 Scikit-learn 模型转换成 ONNX 格式是本课从 Python 通向浏览器的桥梁。然后读取 CSV 数据data pd.read_csv(../data/cleaned_cuisines.csv) data.head()删除前两列无用的序号与标签剩下的 380 列食材作为特征矩阵XX data.iloc[:,2:] X.head()标签取cuisine列作为yy data[[cuisine]] y.head()2. 训练与评估本课选用SVC支持向量机因为在此前的课时中它在该数据集上表现良好。引入 Scikit-learn 相关库from sklearn.model_selection import train_test_split from sklearn.svm import SVC from sklearn.model_selection import cross_val_score from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report按 70/30 划分训练集与测试集X_train, X_test, y_train, y_test train_test_split(X,y,test_size0.3)构建并训练线性核 SVC注意两个关键参数C10控制正则化强度probabilityTrue开启概率估计ONNX 转换与预测都需要训练时标签用values.ravel()展平为一维避免 DataFrame 标签带来的形状问题model SVC(kernellinear, C10, probabilityTrue,random_state0) model.fit(X_train,y_train.values.ravel())调用predict()在测试集上预测并打印分类报告检验模型质量y_pred model.predict(X_test) print(classification_report(y_test,y_pred))课程给出的评估结果accuracy 约 0.79precision recall f1-score support chinese 0.72 0.69 0.70 257 indian 0.91 0.87 0.89 243 japanese 0.79 0.77 0.78 239 korean 0.83 0.79 0.81 236 thai 0.72 0.84 0.78 224 accuracy 0.79 1199 macro avg 0.79 0.79 0.79 1199 weighted avg 0.79 0.79 0.79 1199其中support各为 224–257 条与测试集 1199 条3995 × 0.3一致可见五个菜系在测试集上依然均衡。各菜系 recall 在 0.69–0.87 之间indian识别最好chinese相对最弱——作为教学用的推荐起点这个精度已经足够。完整的训练代码在仓库参考实现中4-Classification/4-Applied/solution/notebook.ipynb其第 11 个代码单元完成了从数据读取到 ONNX 落盘的全过程可与上文逐段对照。四、把 Scikit-learn 模型转换成 ONNX转换时最关键的约束是输入张量的维度必须与数据一致本数据集有 380 个食材列因此第二维要写 380第一维None表示批大小不限。from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType initial_type [(float_input, FloatTensorType([None, 380]))] options {id(model): {nocl: True, zipmap: False}}两个要点float_input是输入名。这里给 ONNX 图的输入张量起了个名字前端 JS 里构造feeds字典时必须用同一个名字可以用 Netron 事后核对见下一节options针对id(model)传转换选项。课程示例中传了两个nocl: Truenocl指不把类的详细信息class labels 列表写入模型从而减小模型体积zipmap: False分类模型的默认输出会把标签到分数的映射打包成字典ZipMap结构设为False后输出退化为列表前端读取更直接——results.label.data[0]就是第一个样本的预测标签。然后生成 ONNX 对象并序列化保存到model.onnxonx convert_sklearn(model, initial_typesinitial_type, optionsoptions) with open(./model.onnx, wb) as f: f.write(onx.SerializeToString())运行完整个 notebook 后当前目录就会多出一个model.onnx。仓库中已附带一份转换好的成品可直接用于前端演示4-Classification/4-Applied/solution/model.onnx。五、用 Netron 检查模型结构ONNX 文件是二进制 protobuf 格式在编辑器里无法直接查看。课程推荐免费开源工具Netron一个可视化工具很多研究者用它检查模型是否构建正确下载后直接打开model.onnx可以看到一个结构简单的图——380 维输入、线性分类器节点以及名为float_input的输入和label输出。说明上图与正文首图为同一张课程截图展示 Netron 打开 model.onnx 后的模型图。Netron 在这里有两个实际用途一是对照转换脚本中声明的输入维度380是否与图一致二是确认输入名确为float_input保证前端feeds的键名不会写错。六、构建前端推荐应用场景设定打开冰箱不知道剩菜能做什么——勾选食材让模型告诉你能做哪国菜。在存放model.onnx的同一目录创建index.html先搭骨架!DOCTYPE html html header titleCuisine Matcher/title /header body ... /body /html1. 食材复选框value 即特征索引在body中放一组复选框每个value都是食材在 ingredient_indexes.csv 中的索引h1Check your refrigerator. What can you create?/h1 div idwrapper div classboxCont input typecheckbox value4 classcheckbox labelapple/label /div div classboxCont input typecheckbox value247 classcheckbox labelpear/label /div div classboxCont input typecheckbox value77 classcheckbox labelcherry/label /div div classboxCont input typecheckbox value126 classcheckbox labelfenugreek/label /div div classboxCont input typecheckbox value302 classcheckbox labelsake/label /div div classboxCont input typecheckbox value327 classcheckbox labelsoy sauce/label /div div classboxCont input typecheckbox value112 classcheckbox labelcumin/label /div /div div stylepadding-top:10px button onClickstartInference()What kind of cuisine can you make?/button /div对照 ingredient_indexes.csv 可逐一验证这些索引apple是第 5 个食材0 起始索引 4cherry为 77fenugreek为 126sake为 302soy sauce为 327cumin为 112——与菜系数据集的列顺序完全一致这正是 380 维特征向量能直接喂给模型的原因。2. 引入 ONNX Runtime Web 并编写推理脚本在最后一个/div之后先引入 ONNX Runtime运行时提供跨硬件平台的 ONNX 执行、优化及调用 APIscript srchttps://cdn.jsdelivr.net/npm/onnxruntime-web1.9.0/dist/ort.min.js/script然后是核心脚本块script const ingredients Array(380).fill(0); const checks [...document.querySelectorAll(.checkbox)]; checks.forEach(check { check.addEventListener(change, function() { // toggle the state of the ingredient // based on the checkboxs value (1 or 0) ingredients[check.value] check.checked ? 1 : 0; }); }); function testCheckboxes() { // validate if at least one checkbox is checked return checks.some(check check.checked); } async function startInference() { let atLeastOneChecked testCheckboxes() if (!atLeastOneChecked) { alert(Please select at least one ingredient.); return; } try { // create a new session and load the model. const session await ort.InferenceSession.create(./model.onnx); const input new ort.Tensor(new Float32Array(ingredients), [1, 380]); const feeds { float_input: input }; // feed inputs and run const results await session.run(feeds); // read from results alert(You can enjoy results.label.data[0] cuisine today!) } catch (e) { console.log(failed to inference ONNX model); console.error(e); } } /script逐段拆解这段代码在做的事ingredients数组长度 380、初始全 0即未选任何食材的输入向量。勾选某个复选框时按value食材索引把对应位置置 1取消则置 0——与训练数据的 one-hot 编码一一对应事件监听对每个.checkbox注册change事件实时同步ingredients状态testCheckboxes()校验至少勾选了一个食材避免空向量送入模型startInference()按钮触发内部的四步推理流程用ort.InferenceSession.create(./model.onnx)异步加载模型文件路径相对于网页因此要求 html 与 onnx 同目录把ingredients包装成Float32Array并构造ort.Tensor形状[1, 380]——与转换时声明的FloatTensorType([None, 380])对齐构造feeds { float_input: input }键名float_input必须与模型输入名一致可用 Netron 核对await session.run(feeds)执行推理从results.label.data[0]取出预测标签——因为转换时设了zipmap: Falselabel输出是普通数组直接取第 0 个元素即可弹出You can enjoy xxx cuisine today!仓库中的完整成品页面见 4-Classification/4-Applied/solution/index.html与上文代码一致可直接与model.onnx一起运行。七、运行与测试在index.html所在目录打开终端例如 VS Code 终端确保全局安装了 Node 的http-server包npm 包用npm install -g http-server安装然后输入http-server浏览器会打开 localhost 地址即可看到Check your refrigerator. What can you create?页面试着勾选不同组合观察结果勾选sakesoy sauce这类组合容易得到japanese勾选cumin则更倾向indian。至此你已经拥有一个只有几个输入字段的推荐应用——这正是推荐系统的最小可行起点。八、练习与扩展课程的挑战题见 assignment.md是把它做成一个更完整的新推荐器用 ingredient_indexes.csv 中其余 373 个食材及其索引把index.html的复选框补全也可以换数据按同样的训练 → skl2onnx 转换 → 前端 ONNX Runtime 推理套路做一个基于性格特征的宠物推荐器、基于心情的音乐风格推荐器等使用外部数据时请标注来源。评分标准Rubric要求同时交付网页应用和notebook两份成果且都有文档说明并能正常运行才算达到 Exemplary 档。九、小结与延伸阅读这一课的价值不在算法本身而在于它展示了一条极简的模型交付路径环节工具关键约束训练评估Scikit-learnSVC特征 380 维 one-hotprobabilityTrue格式转换skl2onnxFloatTensorType([None, 380])nocl: True、zipmap: False模型检查Netron核对输入名float_input、380 维输入与label输出前端推理ONNX Runtime Webort.min.jsfeeds键名与形状[1, 380]必须与模型一致本地运行http-serverhtml 与 onnx 同目录相比全栈 Python 应用如 第 3 周 UFO 回归 Flask 应用这种架构没有后端依赖、可静态托管、可离线运行是把模型嵌入 JavaScript 应用包括需要离线场景的典型做法。推荐系统本身是一个内容非常丰富的领域课程还列出了若干延伸阅读主题推荐引擎的原理与挑战读者可在此基础上继续探索召回、排序等更完整的工业级推荐架构。【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表