多元分类与神经网络前向传播:手写数字识别实现与踩坑全记录
我花了两天时间啃完这门经典课程第三周的课后练习把多元分类和神经网络前向传播从头到尾实现了一遍。整个过程踩了不少坑也把很多原本知其然不知其所以然的细节彻底搞明白了。这篇就把整个实现思路、关键代码、踩坑记录完整写出来希望能帮你少走弯路。这个练习的核心是两件事第一用正则化逻辑回归训练多个二分类器组合成能识别手写数字的多元分类模型第二体验神经网络的前向传播流程——不需要训练权重直接用课程提供的参数跑通一次预测。无论你是刚学完逻辑回归、准备进入神经网络阶段还是卡在某个实现细节里出不来这篇文章都值得你看下去。1. 为什么这道题值得认真做从二分类到多分类的关键跨越逻辑回归在数学上是个二元分类模型可现实中大部分分类问题都不止两个类别。手写数字识别就是个典型例子——你要区分0到9一共10个类别。怎么把二元分类器扩展成多元分类器这是机器学习里第一个真正需要设计模式思维的地方。课程给出的方案是一对一One-vs-All策略训练10个独立的二元分类器每个分类器只回答一个特定问题——这张图是数字3吗、这张图是数字7吗以此类推。预测时把图片输入全部10个分类器拿置信度最高的那个答案作为最终结果。这套思路后来在神经网络里也以完全不同的形式出现了神经网络不再训练10个独立的模型而是用一层多个输出神经元并行完成这件事每个输出神经元对应一个类别最后用softmax或直接取最大值决定结果。理解了ex3的One-vs-All再看神经网络最后一层的设计你会发现逻辑完全相通——只是实现效率高得多。我在做这道题之前总觉得多元分类就是把二元分类多套几层做完之后才意识到问题没这么简单。真正关键的是每个分类器的正负样本怎么定义、输出概率怎么合并、预测置信度怎么比较这些细节才是工程落地的重点。而且练习的负载数据本身就很有挑战——手写数字潦草、笔画粗细不均、甚至还有倾斜比教科书上那些干净分布的数据点棘手得多。用这个数据集训练一个能上90%准确率的模型你会对特征质量比模型复杂度更重要这句话有切身体会。这道题在整门课的练习序列里也是个分水岭前三题是在理解基础模型到ex3开始你要自己组合多个子模型协同工作同时第一次接触神经网络的概念。我建议不要直接抄网上的答案而是按下面的思路自己把每一步走通。2. 数据和接口细节加载、可视化和特征向量的维度理解不论用什么框架实现第一步都是把数据彻底看懂。ex3提供了两个数据文件一个包含5000个训练样本的输入矩阵X以及对应的标签向量y另一个是给神经网络部分用的预训练权重。先别急着跑模型花10分钟把数据本身的形态、范围、含义搞清楚后面能省大量排查时间。2.1 数据矩阵的真实含义X是一个5000行、400列的矩阵每一行是20像素乘以20像素的灰度图像被展平后得到的一维向量。所以每张图最初是个20x20的矩阵按行或者按列串起来就得到400个数值。这些数值是像素灰度理论范围应该是0到255但课程已经把数据归一化到0到1之间了。读数据时有个特别容易忽视的坑y变量里存的标签并不是0-9而是1-10。其中数字0对应的标签是10数字1-9对应的标签是1-9。这个1代表1、10代表0的映射关系在训练单独分类器和计算准确率时很容易出错。我第一次就是忘了转换映射导致最后准确率看起来怎么都不对排查了半天才发现是标签偏移了。加载完数据后强烈建议做一个可视化步骤用reshape将某一行数据还原成20x20的矩阵用图像方式把前100个样本显示出来对着y标签验证自己读入的数据是否正确。不要跳过这一步否则可能在后续所有步骤里带着错误数据白跑。2.2 逻辑回归部分的输入输出约定逻辑回归部分的核心函数大致是损失函数costFunction接收参数向量theta、特征矩阵X、标签向量y和正则化系数lambda返回损失值J和梯度grad。这里的theta维度必须和特征数匹配——特征是400维加上偏置项变成401维所以theta是401维的向量。X的第一列全部设为1作为偏置项。优化阶段使用fmincg内置的高级优化器时需要把theta、X、y、lambda作为参数传递进去优化器迭代更新theta让损失函数最小化。每次调用只训练一个分类器对应一个数字类别。训练10次后得到一个10行401列的theta矩阵每一行对应一个数字分类器的参数。这部分细节下面展开细说。3. 正则化逻辑回归损失函数、梯度公式和向量化实现的坑正规化逻辑回归是这次的主菜。表面上只是把标准逻辑回归加一个正则项但实现起来梯度、损失、向量化三个环节都有各自的细节坑。我一个个拆开说。3.1 损失函数和梯度的标准形式单个样本的逻辑回归损失是交叉熵加上正则项后的整体目标函数长这样损失项取每个样本的预测概率和真实标签的交叉熵求和取平均。梯度项在原有梯度基础上theta的所有分量除了偏置项theta0额外加一个lambda / m乘以该分量的值。注意偏置项不参与正则化。这是很多教程容易含糊带过的地方——正则化惩罚的是特征权重不是偏置。如果连偏置项一块惩罚了模型的平移自由度会受损结果会偏。实现时有一个高效向量化写法避免逐样本for循环用sigmoid函数计算假设值h一个矩阵乘法就能算出全部样本的预测概率。损失计算则可以直接用矩阵运算和log运算一次算出全部样本的交叉熵之和。梯度中非正则化的部分可以表示成X^T乘以(h-y)这个式子看起来抽象本质上就是在累计每个特征维度上的误差。熟悉矩阵求导的人会理解这个操作的来源不熟悉的可以先当作公式记下来后面做数值梯度验证时自然会确信它是对的。3.2 用数值梯度验证你写的梯度对不对写梯度函数的时候有个非常有价值的验证方法数值梯度检验。基本原理是暴力近似求导——在某个点theta上对第j个分量加一个极小量epsilon计算损失变化量除以2倍epsilon就得到该方向上的数值导数。拿数值导数和你的解析梯度对比如果两者非常接近说明解析梯度写对了。这个方法在正式训练前花十分钟做一次可以避免后面训练出的模型莫名其妙不收敛却找不到原因。我这次写代码时梯度里忘记加正则项数值检验立刻爆出巨大差异一查就发现了问题。如果跳过这步直接跑优化损失值可能也会下降但训练出的分类器准确率会很不理想问题隐藏得很深。数值梯度检验的注意点是epsilon不能选太大也不能选太小过大近似误差明显过小浮点精度出问题。一般取1e-5附近比较稳。检验时用个小样本子集比如100个样本就够了全量跑会很慢。3.3 为什么偏置项在正则化里被特殊对待刚开始我直接把所有theta都加了正则项答案也不报错但分类器在测试集上的表现会比正确处理差一截。你要知道为什么偏置项被区别对待偏置项控制的是决策边界整体平移它不直接对应某个具体特征的权重。把所有特征权重同等惩罚时如果偏置也被无差别惩罚优化器就必须在降低损失和缩小偏置之间做无意义的妥协这会扭曲整个决策边界的位置。类比来说正则化像是在对模型的幅度收税但偏置项只是模型的零点位置不应该交这个税。这个细节在面试里也经常被问到值得记牢。4. fmincg和fminunc怎么选优化器背后的工程考量课程练习特别要求用fmincg而不是自己写梯度下降。fmincg和fminunc是两种不同的高级优化器前者基于共轭梯度法后者基于拟牛顿法BFGS。两者都不需要你手动设定学习率内部会自适应推进步长这对新手非常友好。这里先说清楚一个理念问题为什么课程不让你自己实现梯度下降来优化因为在工业界实践中优化器本身是一门学问。手写梯度下降时学习率、动量、收敛判据都要自己调对新手来说这些都是额外负担。高级优化器把这些细节都封装好了让你可以专注于模型本身。这也是编程思维和机器学习思维的一个差异——前者喜欢掌控一切后者知道什么时候该把成熟工具利用起来。fmincg和fminunc在小型问题上的收敛速度差异不是重点重点是接口约定fmincg要求传入一个函数句柄该函数接受theta参数返回损失和梯度同时要传入一个初始theta向量和选项结构体。有个细节坑是直接写fmincg(costFunction, theta, options)这种形式会报错或行为怪异因为costFunction除了theta还依赖X、y、lambda这些额外参数。正确做法是构造一个匿名函数把这些额外参数捕获进来每次只用theta作为自变量。如果读过相关文档会看到官方推荐的做法正是我上面描述的这个模式。从选项里可以设定最大迭代次数和是否输出过程信息。我第一次跑用默认值结果训练过程完全黑盒只能在结束后看准确率。后来显式打开输出选项每一轮迭代的损失值变化一目了然对判断是否收敛非常有帮助。5. 从单个分类器到完整预测系统训练、组装和评估的完整流程有了能优化单个逻辑回归分类器的工具接下来要把10个分类器全部训练出来并组装成统一的预测系统。5.1 训练循环和all_theta矩阵训练层面用一个for循环遍历1到10这10个类。每个循环里做三件事第一把y重映射成当前类别的二值标签——是当前数字则标为1否则标为0第二调用fmincg优化当前分类器的theta第三把训练好的theta存到一个矩阵的对应行。这个模块如果封装成函数会清爽很多。函数返回一个叫all_theta的矩阵维度是10乘以401每一行是某个数字分类器的完整参数向量。注意数字1排在矩阵第1行数字0排在第10行因为y标签里0对应10。这个顺序在预测阶段要记住否则输出结果会错乱。初始化theta时我用的全零向量。对逻辑回归来说全零初始化是可行的——因为损失函数是凸函数不管从哪开始优化都能收敛到全局最优这和神经网络必须随机初始化有本质区别。这里可以与后面对比着理解为什么神经网络不能用全零初始化因为对称性问题。这个细节到神经网络训练时你就会深有体会。5.2 预测函数概率矩阵的行列含义预测时把整个X矩阵输入到所有分类器中得到一个5000行10列的概率矩阵。第i行第j列表示第i个样本被第j个分类器判定为正类的概率。实际预测就是逐行找最大值所在列的索引。某学习者写过一个简短的预测函数靠一个矩阵乘法和一次sigmoid调用就拿到了全部概率再用max函数顺着列方向找出每行最大值及索引。索引从1开始且对应数字1到10最后要把10映射回0。我在预测阶段犯过一个很低级的错误没有把全零特征矩阵里的偏置列处理好。训练时X第一列全是1预测时如果忘了加这一列矩阵维度直接对不上。这个错误虽然会立即报维度错误、容易发现但一旦数据刚好巧合匹配就会出隐藏问题所以养成训练和预测走同一条预处理流程的习惯值得刻意培养。5.3 准确率评估和每个类别的独立表现训练完成后在训练集上算准确率大概在95%左右不同实现略有浮动。这个数字看着不错但建议进一步看看每个类别各自的准确率不要只看平均。每个数字独立来看表现是有差异的有些数字容易混比如4和9、3和8这些形近数字单个类别准确率可能掉到90%以下。这提醒我们准确率均值高不代表每个类别都健康。在真实项目里如果某个类别是高风险类别比如医疗诊断里的某种罕见病单独看该类的召回率比看整体准确率重要得多。模型评估不能只看汇总指标这一点到后面学习精确率、召回率时会反复出现。6. 神经网络初体验不训练权重只跑一次前向传播ex3的后半部分不是训练神经网络而是直接给你一组训练好的权重让你实现前向传播跑通预测。很多人觉得这半部分太简单但它是理解神经网络正向工作原理的关键一步。6.1 三层结构的数据流动过程这里的神经网络是三层结构输入层400个神经元对应400像素特征、隐藏层25个神经元、输出层10个神经元对应10个数字类别。课程给好的权重Theta1维度是25乘以401Theta2维度是10乘以26。25后面为什么跟401因为输入层400个特征加一个偏置单元隐藏层25个神经元同理加偏置后变成26个输入。前向传播的逻辑很直白输入数据从输入层进入加权求和后用sigmoid激活得到隐藏层的输出隐藏层的输出作为下一层的输入再次加权求和、再用sigmoid激活得到最终输出。所谓神经元被激活与否就是sigmoid函数输出的值是否显著接近1。第一次看到想到原来我前面手工训练出的10个独立分类器这里用一组权重并行完成了——输出层10个神经元本质上就起了多分类器的作用。区别在于这里不是独立优化每个输出而是共享隐藏层特征表达权重在训练时是一起调整的。这种共享特征表达正是神经网络高效的地方。我建议实现时逐步打印每一层的维度变化确认每一步矩阵相乘是合法的。很多新手在这里被维度搞晕先手算一下第一层输入是5000乘以401乘Theta1转置25乘以401得到5000乘以25的隐藏层活跃值加上偏置列得5000乘以26再乘Theta2转置10乘以26得到5000乘以10的输出层值。中间任何一步维度不匹配都会立刻暴露出来。6.2 从逻辑回归到神经网络同一个思想的不同载体前向传播实现完之后我最大的收获是突然理解了逻辑回归和神经网络之间的关系。神经网络的一层本质上是多个逻辑回归单元的组合但层与层之间通过非线性激活函数叠加表达能力大大增强了。注意一个关键细节在隐藏层计算出a1之后、输入到输出层之前必须再插入一列1作为偏置。这个偏置单元在神经网络里同样不参与特征表达只是给该层的加权和提供了一个可调节的偏移。如果漏掉这一步矩阵维度对不上训练好的Theta2也没法用预测结果就乱了。神经网络部分用课程给的权重跑出来准确率在97%以上高于前面逻辑回归的95%。为什么更高因为神经网络的特征表达是数据驱动学到的而逻辑回归用的是原始像素直接组合。像素级别的特征表达能力有限神经网络学到的是更高层的抽象模式。7. 整个练习做完后的几个认知升级7.1 关于调包和手写的重新认识做这道题之前我总觉得自己手写一切实现才算真正理解。做完后发现在机器学习工程里合理选用成熟优化器不是偷懒是正确分工。fmincg背后的共轭梯度实现细节绝大多数场景不需要你重写你需要理解的是它的接口约定、收敛含义、以及什么时候换用别的优化器。这和深度学习里用现成框架的基本道理一脉相承——工程价值在于组件搭配和问题建模不是重复造轮子。7.2 有哪些可以继续深挖的扩展方向如果你做完这个练习还有余力我建议你按这几个方向继续探索一是自己实现简单的反向传播训练神经网络把给好权重跑前向升级成自己学到权重。你会发现难点从计算过程转移到维度管理和梯度推导。二是把数据稍作增强旋转、平移、加噪声观察准确率怎么变化。这能让你提前体验真实项目中数据质量对模型表现的主导作用。三是试着把逻辑回归部分换成支持向量机、决策树等不同模型对比它们在相同数据上的表现差异。这种模型对比实验是机器学习从业者的日常基本功。7.3 一个实用建议从一开始就写好调试辅助工具我在这次练习中体会很深的一点是调试工具前置能省下大量时间。数值梯度检验和维度打印这两个小工具在这次练习里帮我快速定位了至少四个问题。养成写模型之前先写验证工具的习惯后面做复杂项目时收益巨大。数值检验思路在神经网络的反向传播实现里同样适用届时光靠看代码找错会非常痛苦梯度检验几乎是救命稻草。回到开头说的那句话这门课练习的真正价值不在分数而在亲手把每个公式变成能跑的代码并且理解每一步为什么这么做。希望这篇笔记能帮你在ex3上少走一些弯路——尤其是那个标签映射、那个偏置列、那个匿名函数传参的坑。如果过程中卡住了对照着我上面说的排查思路一步步查大概率能自己找到问题所在。

相关新闻

不锈钢防火门|耐腐蚀防火一体

不锈钢防火门|耐腐蚀防火一体

作为一线技术人员,经常遇到客户在潮湿、盐雾、有酸碱腐蚀的项目里踩坑,普通镀锌钢质防火门用两三年就锈蚀掉漆,门框门扇变形,防火密封失效,消防验收直接卡壳。这种场景下,不锈钢防火门就是兼顾防火与防腐的…

2026/10/15 10:30:26 阅读更多 →
Claude Code npm 安装后如何接入国内大模型?TaoToken 统一 Key 配置思路

Claude Code npm 安装后如何接入国内大模型?TaoToken 统一 Key 配置思路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 10:30:26 阅读更多 →
Impala离线查询实战:架构原理、内存调优与元数据管理

Impala离线查询实战:架构原理、内存调优与元数据管理

1. 为什么离线场景下 Impala 依然值得单独拿出来讲 大数据圈子里有个挺有意思的现象:一提到交互式查询,很多人第一反应就是"上 Flink SQL"或者"换 ClickHouse",好像 Impala 已经是上个时代的产物了。但如果你真正在离线数…

2026/10/15 10:30:26 阅读更多 →

最新新闻

12306 Android订票源码实战:架构解析与全流程避坑指南

12306 Android订票源码实战:架构解析与全流程避坑指南

简介:这是一套面向Android开发学习者与进阶者的12306火车票订票系统完整项目源码,适合希望以真实业务场景提升移动端开发能力的人群。项目覆盖登录注册、车次查询、订单管理、个人信息设置等模块,并串联UI设计、网络通信、JSON解析、数据存储…

2026/10/15 12:17:50 阅读更多 →
CLI工具的交付契约:从impeccable看零妥协工程标准

CLI工具的交付契约:从impeccable看零妥协工程标准

1. “impeccable”不是功能,是CLI工具的命名哲学与交付标准 你第一次在终端里敲下 npx impeccable ,回车后什么都没发生——没有进度条,没有欢迎语,甚至没报错。你怀疑是不是拼错了,又试了一次,还是静默退…

2026/10/15 12:17:50 阅读更多 →
STM32G0B1 FDCAN发送实战:从消息RAM配置到第一帧发出

STM32G0B1 FDCAN发送实战:从消息RAM配置到第一帧发出

简介:这份资源面向使用STM32G0B1进行FDCAN通信开发的嵌入式工程师与学习者,聚焦于结合HAL库实现CAN帧发送的完整工程实践。压缩包共1215个文件,以661个.c源文件、259个.h头文件及103个.s汇编文件为主体,另含IAR与Keil工程配置、链…

2026/10/15 12:17:50 阅读更多 →
2020版cs231n卷积神经网络笔记:从原理到实战的完整复盘

2020版cs231n卷积神经网络笔记:从原理到实战的完整复盘

1. 为什么2020年的cs231n笔记至今仍值得翻出来看如果你正在入门深度学习,或者已经跑过几个Demo但总觉得脑子里缺一张完整的图,那2020年这一版cs231n的卷积神经网络部分,大概率是你绕不开的一份材料。我自己是在做完两个图像分类的小项目之后&…

2026/10/15 12:17:50 阅读更多 →
ST电机库V6.2.1 FOC调试实战:从参数辨识到无感启动的避坑指南

ST电机库V6.2.1 FOC调试实战:从参数辨识到无感启动的避坑指南

简介:ST电机库文件V6.2.1是意法半导体面向嵌入式电机控制开发者推出的软件开发包,聚焦磁场定向控制(FOC)算法,适用于无刷直流电机与交流感应电机的驱动开发。资源面向具备C/C与嵌入式基础的工程师,帮助其快…

2026/10/15 12:17:50 阅读更多 →
LWIP TCP连接状态机解析与优化实践

LWIP TCP连接状态机解析与优化实践

1. LWIP TCP连接状态机解析 在嵌入式网络开发中,理解TCP连接的状态流转是构建稳定通信的基础。LWIP作为轻量级TCP/IP协议栈,其状态机实现直接影响着资源受限设备在网络异常时的恢复能力。去年调试工业物联网网关时,我就因为没吃透状态转换规则…

2026/10/15 12:16:50 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →