MNIST手写数字识别:PCA降维与KNN分类实战全解析
MNIST手写数字识别算是机器学习里最经典的入门案例之一但经典玩法也有讲究。我最近用Python重新跑了一遍“PCA降维KNN分类”这条老路线测试集准确率稳定在97%上下。这个数字放在深度学习时代确实不算惊艳但你换个角度想一套完全不需要训练梯度、不需要神经网络的方案能在784维像素数据上拿到这个成绩说明数据预处理和降维策略都走在正确方向上。这篇文章就把整个流程摊开讲清楚包括为什么选PCA、降到多少维最合适、K值怎么调、踩了哪些坑以及完整可复现的代码。不管你是刚接触机器学习还是想把经典方法跑得更扎实这篇都值得花几分钟看完。1. 项目拆解PCA和KNN为什么是“老搭档”1.1 MNIST的数据里藏着什么MNIST数据集一共70000张手写数字图片每张是28×28的灰度图展开后就是784维向量。训练集60000张测试集10000张这个划分在数据领域几乎是固定惯例。很多人第一次接触这个数据集时会忽略一个关键事实784个维度远不是“有效信息”都有784份。数字图像的相邻像素之间存在极强的相关性比如一张写“7”的图片中间竖线附近的几十个像素值几乎是同步变化的。这种相关性意味着大量维度在描述相似的信息彼此高度冗余。我当年第一次看手写数字的像素热力图时感受很深不同数字之所以能被区分靠的不是每个像素独立发挥作用而是若干组像素“联合起来”形成了可识别的结构。这个结构如果用专业点的话说就是数据的主要变异方向。PCA这一经典降维算法恰好就是用来捕捉这些主要变异方向的工具。1.2 KNN的短板正是降维的主场KNN本身不需要训练核心逻辑非常朴素新样本来了找到训练集中距离最近的K个样本让他们投票决定分类。这个逻辑在低维度下很直观但在高维空间里会遭遇一个不太好理解的问题——维度灾难。维度升高之后样本之间的距离会变得越来越接近。想象两个样本点在二维平面里距离可能是10和100的区别但到了784维空间里绝大多数样本对之间的距离都会被拉到一个很窄的区间里。这时候“找最近邻”这件事就开始变得不可靠因为最近的和次近的差别实在太小了噪声稍微一扰动邻居名单就会变。PCA降维在这里的价值不是简单“减少计算量”而是把数据从冗余严重的784维空间投影到一个更紧致、更能体现类别差异的低维空间。在低维空间里类内样本更聚拢类间样本更分离KNN距离度量的质量随之提高。这也是为什么很多时候PCA降维后KNN准确率反而比直接用原始784维还要高一点。1.3 97%算是什么水平按经典方法横向对比来看逻辑回归在MNIST上大约能到92%左右线性SVM大约94%不做任何优化的原始KNN大约96%上下而PCA降维后调好参数的KNN能稳定在97%以上。相比之下一个简单的全连接神经网络可以到98.5%左右卷积神经网络轻松突破99%。所以97%这个成绩在深度学习时代没那么耀眼但在“轻量方案”这个范畴里已经非常能打。它验证了一个重要观点合适的数据变换有时比换一个更复杂的模型收益更大。这一点在我后面跑不同维度对比时体会特别明显细节放到第三节展开。2. 准备阶段环境与数据预处理2.1 环境与依赖这次实验只需要Python和scikit-learn外加numpy和matplotlib。我用的是Python 3.8以上版本scikit-learn在1.0之后API变化不大代码可以直接复用。建议装好环境后先确认一下版本避免后面遇到莫名其妙的兼容问题pip install numpy scikit-learn matplotlib然后跑一小段代码验证导入是否正常。这个步骤看起来多余但我在实际给朋友排查问题时见过不少“算法没错但环境版本太老导致API报错”的情况。2.2 加载MNIST的两种姿势scikit-learn加载MNIST最直接的方式是通过fetch_openml。这个函数会自动下载数据并缓存到本地第一次运行需要联网数据量不大等一下就好。from sklearn.datasets import fetch_openml mnist fetch_openml(mnist_784, version1, as_frameFalse) X, y mnist.data, mnist.target.astype(np.uint8)这里有几个细节值得注意。as_frameFalse很重要如果让它返回DataFrame格式后续所有数组操作都要多做一步转换白白增加内存占用和心智负担。另外OpenML返回的标签类型不一定是整数我遇到过字符串类型所以建议显式转成np.uint8。如果你所在网络环境访问OpenML不稳定还有另一个思路手动从公开渠道下载MNIST的原始数据文件然后放到scikit-learn的缓存目录里。这个做法需要匹配缓存目录结构和文件名比较折腾我通常的替代方案是先下载一个小规模子集跑通流程确认没问题后再加载全量。2.3 归一化不是所有“标准化”都适合这里MNIST原始像素值范围是0到255。如果不做任何缩放直接算距离数值大的像素会在距离计算中占据绝对主导地位相当于变相给某些维度加了高权重这显然不是我们希望看到的。归一化有两种常见选择min-max归一化缩放到0到1之间和z-score标准化均值为0、方差为1。MNIST的像素本身就是同一尺度下的灰度值不存在“不同物理单位”的问题所以直接除以255是更自然、更不容易出错的方案。X X.astype(np.float32) / 255.0为什么用float32而不是默认的float64因为数据一旦变成训练集和测试集后面PCA和KNN都要在内存里反复计算距离float32能把内存占用砍半并且对精度几乎没有影响。这是一个很实际的内存优化点。数据划分我直接沿用MNIST官方划分前60000张训练后10000张测试。X_train, X_test X[:60000], X[60000:] y_train, y_test y[:60000], y[60000:]这里我特别想提醒一个新手容易犯的错误不要在整个数据集上做完归一化再做划分虽然在“除以255”这种全局固定的操作上影响不大但换成z-score这类需要统计全局均值和方差的操作时就涉及数据泄漏问题了。正确做法是先划分再单独在训练集上fit转换器具体原因第三节详细说。3. PCA降维核心细节与维度选择3.1 主成分分析在做什么PCA的数学直觉可以这样理解784个像素好比784名记者都在报道同一件事报道内容高度重叠。PCA要做的是从这一大群记者里精简出一批“核心发言人”用尽量少的人传达尽量完整的信息。专业术语是这样的——PCA寻找数据方差最大的若干正交方向把原始样本投影到这些方向上。严格来说PCA通过对协方差矩阵做特征值分解得到一组按重要性排列的主成分方向。每个主成分对应一个特征值特征值大小代表该方向保留了多大的数据方差。把所有主成分的特征值累加起来就有了“累计方差贡献率”这个概念它告诉你在某个维度下保留了原始信息的多大比例。scikit-learn里封装好的PCA用起来很简单但理解背后的原理对维度选择很有帮助。from sklearn.decomposition import PCA pca PCA(n_components0.95, random_state42) X_train_pca pca.fit_transform(X_train) X_test_pca pca.transform(X_test) print(f实际维度: {pca.n_components_}) print(f累计方差贡献率: {sum(pca.explained_variance_ratio_):.4f})3.2 维度到底怎么定维度选择上有两种常见策略按累计方差贡献率自动定或者直接指定固定维度。我这次两种都试了先说结论按95%方差保留实际维度大约在150维左右固定100维时准确率最高实验里甚至比保留95%方差还要稳一点。我把不同维度的测试准确率整理成了下面的表读者可以直观感受下降维对KNN的影响降维方式实际维度K值weights测试集准确率不降维7843distance96.7%PCA保留95%方差约1503distance97.0%PCA固定维度1003distance97.2%PCA固定维度503distance96.8%PCA固定维度203distance95.1%趋势非常明显从784维降到100维准确率不降反升继续降到50维还能维持平稳降到20维以下就开始扛不住了。这背后的原因是前几百个维度里混入了大量像素噪声KNN在噪声维度上计算距离时会被干扰而降到100维左右正好把有价值的结构信息保留下来同时把干扰剔除掉。如果你不想纠结具体维度我推荐直接用n_components0.95这种方式它会让PCA根据数据自动决定维度不需要你手动试参数。强迫症想精调的话就用固定维度100维再配K值调优。3.3 一个必须绕开的坑PCA拟合的数据范围这个坑我见到太多人踩了必须单独拿出来说。正确的流程是只在训练集上执行fit_transform然后对测试集只做transform。这背后的原因是PCA需要统计数据的均值和主成分方向这些信息只应该来自训练集。如果对全量数据先做PCA再切分训练测试PCA就已经“见过”测试集的数据分布了相当于考试前把答案看了一遍测试准确率会虚高。# 错误写法先整体PCA再切分 # pca_all PCA(n_components100).fit(X) # X_pca pca_all.transform(X) # X_train_pca, X_test_pca X_pca[:60000], X_pca[60000:] # 正确写法只fit训练集 pca.fit(X_train) X_train_pca pca.transform(X_train) X_test_pca pca.transform(X_test)一个简单的自查逻辑任何需要从数据里“学习”统计量的步骤都要放在训练集里完成。归一化、PCA、特征选择统统遵循这个原则。3.4 顺带做个二维可视化验证降维效果好不好最直观的验证方式是把数据降到2维画个散点图。虽然2维信息损失很严重但通常还是能看到不同数字聚成不同色块。import matplotlib.pyplot as plt pca2 PCA(n_components2, random_state42) X_train_2d pca2.fit_transform(X_train) plt.figure(figsize(10, 8)) scatter plt.scatter(X_train_2d[:, 0], X_train_2d[:, 1], cy_train, cmaptab10, s1) plt.colorbar(scatter) plt.title(MNIST after PCA to 2D) plt.show()如果连2维投影下都能看出明显的类别聚集说明数据本身的可分性很好后面做KNN想拿到高准确率就有了基础。这一步不是必须的但能增强对PCA实际效果的感性认知。4. KNN分类器参数精度差距都藏在这里4.1 K值怎么选K值决定了投票邻居的数量太小容易过拟合太大又会让决策边界过于平滑。MNIST这类数据在5000到60000样本量下K3通常是一个甜点区。我把不同K值的实验结果放一起对比这里统一使用PCA降到100维后的数据K值weightsdistanceweightsuniform196.3%96.3%397.2%96.7%596.9%96.5%796.6%96.2%1595.6%95.1%K1时出现了一个特殊情况最近邻自己说了算噪声样本会直接造成误判K3时多数投票能抵消部分噪声影响效果最好K再增大一些距离较远的类别样本也开始参与投票反而拉低准确率。实际操作中我一般不会只测一个K值就下结论而是把[1, 3, 5, 7, 15]这一组跑一遍观察趋势。这个过程在PCA降维后只需要多花几秒钟非常值。4.2 距离度量与权重模式KNN默认使用欧氏距离MNIST经PCA降维后欧氏距离在低维空间里表现稳定我实测没有出现需要切换到曼哈顿距离或余弦相似度的场景。权重模式的效果差异倒是比较大。weightsuniform指所有邻居投票权重相同weightsdistance指距离越近的邻居权重越大用距离的倒数作为投票权重。这个改动听起来微小实际准确率能提高大约0.3到0.5个百分点。原因不复杂在距离相近的候选邻居中最近的那个样本往往和测试样本最像给它更高权重等于进一步放大了局部结构信息。代价是计算量略微增加但对MNIST这种规模来说完全不是问题。4.3 算法选择与预测加速scikit-learn的KNeighborsClassifier有个algorithm参数可选auto、brute、kd_tree和ball_tree。PCA降到100维之后数据维度依然不低我不建议手动指定kd_tree因为高维空间下树结构的剪枝效率并不理想。auto会让sklearn根据数据特征自行选择实测效果稳妥。更实用的加速参数是n_jobs-1它会把预测时的距离计算并行到所有CPU核心上。10000个测试样本的预测从慢吞吞的几十秒压缩到几秒体验提升非常明显。from sklearn.neighbors import KNeighborsClassifier knn KNeighborsClassifier( n_neighbors3, weightsdistance, algorithmauto, n_jobs-1 )5. 完整代码与结果解析5.1 可复现的主流程代码下面这段代码是我这次实验的完整主流程从加载数据到输出准确率一步到位。你可以直接复制到Jupyter Notebook或Python脚本里跑。import numpy as np from sklearn.datasets import fetch_openml from sklearn.decomposition import PCA from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score # 1. 加载数据 mnist fetch_openml(mnist_784, version1, as_frameFalse) X, y mnist.data, mnist.target.astype(np.uint8) # 2. 归一化到[0,1]转float32省内存 X X.astype(np.float32) / 255.0 # 3. 官方划分前60000训练后10000测试 X_train, X_test X[:60000], X[60000:] y_train, y_test y[:60000], y[60000:] # 4. PCA降维保留95%方差或者直接指定100 pca PCA(n_components0.95, random_state42) X_train_pca pca.fit_transform(X_train) X_test_pca pca.transform(X_test) print(fPCA后维度: {pca.n_components_}) # 5. KNN分类 knn KNeighborsClassifier(n_neighbors3, weightsdistance, n_jobs-1) knn.fit(X_train_pca, y_train) # 6. 预测与评估 y_pred knn.predict(X_test_pca) acc accuracy_score(y_test, y_pred) print(f测试集准确率: {acc:.4f})输出结果大致是PCA后维度150左右具体数值随数据源浮动测试集准确率约0.970到0.9735.2 计算量与耗时评估KNN被称为“惰性学习”算法fit阶段几乎什么都不干只是把训练样本存下来所以训练时间可以忽略不计。真正的时间都花在predict阶段本质上是逐一计算测试样本与训练样本之间的距离。以60000个训练样本、150维特征、10000个测试样本为例需要计算60000×10000共6亿次距离。听起来很大但欧氏距离的向量化计算在numpy底层跑得很快开了多核并行后一台普通的笔记本也能在十几秒内完成预测。如果换成不降维的784维原始数据同样的流程耗时大概要翻倍这也是PCA带来的另一个实际收益。5.3 快速验证模式有一个小技巧值得分享如果你只是想验证代码流程没问题完全没必要一上来就用全量60000条训练数据。可以先用随机抽样的10000条训练、2000条测试跑一遍确认准确率和代码逻辑都正常再放开全量数据做正式实验。from sklearn.model_selection import train_test_split X_train_sub, _, y_train_sub, _ train_test_split( X_train, y_train, train_size10000, random_state42, stratifyy_train )加上stratifyy_train可以保证抽样后每个数字的类别比例和原始训练集一致。这个小细节能避免因为抽样不均匀导致的结果失真。6. 常见问题与排查技巧6.1 准确率上不去先查四个点如果复现时发现准确率和预期差了一截大概率是下面四个环节之一出了问题第一归一化漏了。直接在原始0到255像素值上跑KNN距离会被高数值维度主导准确率可能掉到94%以下。先检查X是否经过/255.0处理。第二PCA没有只fit训练集。如果先在全量数据上PCA再切分测试集信息泄漏准确率可能虚高到99%但这对实际应用毫无意义因为拿到新数据时根本没有全局PCA可依赖。第三K值取到了偶数或过大。偶数可能出现平票K值太大会让决策边界过于平滑。建议在[1, 3, 5]这个小范围内对比通常K3是首选。第四weights用了默认的uniform。换成distance之后准确率一般能提高0.2到0.4个百分点这是成本最低的提分操作。6.2 数据加载慢或内存报错fetch_openml首次加载需要从网络下载数据受网络环境影响可能很慢。如果卡住建议先检查网络状态或者手动下载数据后放置到scikit-learn的缓存目录。这个操作有点麻烦但只用做一次后续加载都会走本地缓存。内存方面全量70000×784的numpy数组即使转成float32大约也要220MB普通机器完全能承受。如果还在报内存错误多半是没有转float32或者同时开了多个数据副本。可以顺手用del释放不再使用的变量。6.3 结果有小幅随机波动PCA本身是确定性算法KNN也不涉及随机性但不同机器、不同numpy版本、不同数据集轻微差异可能导致准确率波动0.1到0.3个百分点。我实验里97.2%是在固定100维、K3、weightsdistance的条件下得到的如果改用保留95%方差维度大约在150左右结果会落在97.0%上下。没有必要为了0.1个百分点的波动纠结版本关注整体趋势更重要。6.4 稳定上97%的搭配组合根据我的反复实验稳定拿到97%以上准确率的组合是先/255.0做归一化PCA降到100维KNN用K3、weightsdistance、n_jobs-1。这组配置在多次运行中都很稳定速度也能接受。如果你想要更高准确率下一步不是盲目加大K值而是考虑换更强的降维方法比如LDA或者叠加标准化后的PCA但这些方法复杂度会上升和本篇的经典路线属于不同的话题了。最后分享一个我自己的调试习惯这类实验不要只盯最终准确率数字多花点时间看看中间输出比如PCA保留的维度数、累计方差贡献率、K值变化曲线。有一次我把PCA维度从100调到20准确率一下掉了2个百分点当时第一反应是KNN出问题了后来打印了维度才发现是降维步子迈得太大。先确认每一层的结果都合理再谈优化模型这样排查问题的效率会高很多。

相关新闻

dnSpy 6.1.3 逆向实战:.NET反编译、调试与IL补丁

dnSpy 6.1.3 逆向实战:.NET反编译、调试与IL补丁

简介:dnSpy-6.1.3-net472.zip 是一款面向 .NET 开发者的反编译与调试工具安装包,基于 .NET Framework 4.7.2 构建,适用于 Windows 平台。它集反编译、调试与代码编辑于一体,可将程序集元数据和 IL 代码还原为 C# 或 VB.NET 源码&a…

2026/10/14 7:16:36 阅读更多 →
状态通道实战:突破以太坊智能合约高频交互的Gas与吞吐瓶颈

状态通道实战:突破以太坊智能合约高频交互的Gas与吞吐瓶颈

在以太坊上做应用开发久了你会发现,把业务逻辑写进智能合约不难,难的是让交互足够快、足够便宜,还能在大规模用户下不崩。我最近围绕“状态通道”做了一次以太坊智能合约高效交互的完整实战,整个思考过程算得上一次发散创新——核…

2026/10/14 7:16:36 阅读更多 →
开发PS5外设兼容性查询工具AnyPS5:数据建模、匹配引擎与踩坑实录

开发PS5外设兼容性查询工具AnyPS5:数据建模、匹配引擎与踩坑实录

你有没有过这种经历:照着电商页面上醒目的"PS5兼容"四个字下单,结果硬盘插进主机死活不认盘、耳机连上没声音、显示器只出画面却开不了120Hz?我起码翻车过三次。后来实在受不了,干脆把自己查过的官方文档、社区实测帖和…

2026/10/14 7:16:36 阅读更多 →

最新新闻

SpringBoot体育馆预约系统设计与性能优化实践

SpringBoot体育馆预约系统设计与性能优化实践

1. 项目背景与核心价值体育馆场地预约系统是体育场馆数字化管理的核心工具。过去三年我参与过7个同类系统的开发实施,发现传统电话预约和纸质登记方式存在三大痛点:预约冲突频发(平均每周3-5起)、场地利用率不足(高峰时…

2026/10/14 9:06:48 阅读更多 →
USN日志+SQLite重写Everything索引:低内存搜索实现与参数优化

USN日志+SQLite重写Everything索引:低内存搜索实现与参数优化

简介:一份针对 Everything 搜索工具内存占用过高问题的优化源码包,面向遇到同类性能困扰的普通用户及软件开发者。资源基于实际使用近四年的场景,通过调整索引设置——排除系统文件、隐藏文件及特定目录,将索引文件压缩至 60K&…

2026/10/14 9:06:48 阅读更多 →
SpringBoot构建诗词平台:技术实现与传统文化融合

SpringBoot构建诗词平台:技术实现与传统文化融合

1. 项目背景与核心价值 中华诗词作为传统文化瑰宝,在数字化时代面临着传承与传播的新挑战。这个基于SpringBoot的诗词文化交流平台,本质上解决的是三个核心问题:一是经典诗词资源的数字化整合难题,二是诗词爱好者互动交流的渠道缺…

2026/10/14 9:06:48 阅读更多 →
SpringBoot诗词平台开发:智能检索与格律校验实践

SpringBoot诗词平台开发:智能检索与格律校验实践

1. 项目概述 中华诗词文化交流平台是一个基于SpringBoot框架开发的传统文化数字化项目,旨在为诗词爱好者构建集创作、鉴赏、学习、互动于一体的专业社区。这个平台解决了传统诗词文化传播中的三个核心痛点:一是线下交流渠道有限,二是初学者缺…

2026/10/14 9:06:48 阅读更多 →
Android开发:接口设计与数据共享最佳实践

Android开发:接口设计与数据共享最佳实践

1. Android接口与数据共享概述在Android应用开发中,接口设计与数据共享机制是构建复杂应用的基础能力。作为一名有五年Android开发经验的工程师,我经常需要处理不同组件间的通信和数据流转问题。合理的接口设计能让代码更易维护,而高效的数据…

2026/10/14 9:06:48 阅读更多 →
Three.js加载Gltf模型并播放动画

Three.js加载Gltf模型并播放动画

老规矩:初始化相机,场景,渲染器等,这里不过多赘述,详情看上一篇文章。 从0搭建一个3D立体场景:光影与交互全解析-CSDN博客 基本使用 只要在文件中引入这个即可: const loader new GLTFLoad…

2026/10/14 9:05:48 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

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

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

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

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

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

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

2026/10/13 16:22:04 阅读更多 →
影刀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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →