飞机100分类数据集测试集评估:细粒度图像识别实战指南

发布时间:2026/8/27 12:21:00
飞机100分类数据集测试集评估:细粒度图像识别实战指南 简介在深度学习图像识别任务中细粒度分类要求模型具备区分高度相似子类的能力挑战远高于普通分类。飞机100分类数据集正是聚焦此类问题的典型基准其测试集作为独立的评估标准用于衡量模型在未见样本上的泛化能力。围绕测试集开展评估时需重点把握数据加载与预处理一致性、模型推理与Top-1/Top-5指标计算、混淆矩阵与误差分析等关键环节同时严格防范测试集泄漏确保结果的可靠性。借助该测试集开发者可以系统比较CNN与ViT等不同架构在细粒度识别中的表现并为模型选型、数据增强策略优化以及移动端轻量化部署提供量化依据。本文从实际工程视角梳理了一套可复现的飞机测试集评估流程为从事图像分类与视觉识别工作的工程师提供参考。1. 飞机100分类数据集整体设计与思路拆解做深度学习图像识别的人手里多少都会囤几个数据集。但说实话能让人认认真真把“测试集”单独拿出来研究的真不多。这次我拿到的是一个飞机100分类数据集的测试集100个类别、全部是飞机覆盖各种民航客机、战斗机、螺旋桨飞机、无人机甚至一些原型机。用途很明确——拿来评估图像识别模型的泛化能力和细粒度分类水平。1.1 这类数据集到底解决什么问题飞机分类在图像识别里属于典型的细粒度分类任务。什么叫细粒度就是大类大家都认识但小类非常容易搞混。你让一个模型去区分“猫”和“狗”这不算难但让它区分“波音737-800”和“空客A320neo”难度立刻上来了。这两种飞机从远处看都是单通道窄体客机机头弧度、翼尖小翼、发动机短舱形状都有差异但普通分辨率下这些差异可能只占几十个像素。飞机100分类数据集的价值就是把这个问题聚焦到了极致。100个类别意味着模型不能靠“整体像飞机”这种粗粒度特征混过去它必须学会关注细节。比如垂尾的形状、发动机的数量和位置、起落架舱门的设计、机身涂装的特定布局甚至机翼后掠角的角度差异。这些特征放在通用图像分类数据集里是噪声放在飞机100分类任务里就是决定性的判别依据。我见过不少人拿这个数据集做模型选型评估比如对比ResNet50、EfficientNet、ViT在细粒度任务上的表现差异。也有做迁移学习的用ImageNet预训练权重在训练集上微调再拿测试集验证泛化效果。还有做数据增强策略研究的比如AutoAugment、RandAugment到底能不能提升细粒度分类的鲁棒性。测试集在这些场景下就是一把尺子测量的是模型在“没见过的飞机图片”上的真实表现。1.2 为什么单独把测试集拎出来说很多人对测试集的理解就是“用来测精度的那一批图片”这个理解没错但不够完整。在深度学习工作流里数据通常被拆成三份训练集、验证集、测试集。训练集用来更新模型参数验证集用来调超参和做早停测试集只在最后一刻使用模拟的是“模型部署到真实环境”时的表现。飞机100分类数据集的测试集单独拿出来说是有道理的。第一它代表了一个固定的、不可变更的评估基准。你在训练集上做任何调整、做多少轮迭代、换什么增强策略测试集都不参与这些过程。只有这样最终在测试集上得到的指标才是可信的。第二细粒度分类任务里训练集和测试集的分布差异往往比通用分类更大。飞机的拍摄角度、光照条件、背景复杂程度、图片分辨率在训练集和测试集之间可能存在肉眼可见的差异——这正是测试集存在的意义检验模型是否真的学到了“飞机类别”的本质特征而不是背下了训练集中的具体图像。我把话说得更直白一点如果你只有一个训练集你做的所有评估本质上都是“开卷考试”模型完全有可能通过记忆图片来拿高分。而测试集是一场“闭卷考试”考的才是模型真正的理解能力。飞机100分类数据集的测试集一旦被污染——比如训练时不小心把测试集图片混进去了——那这个评估结果就彻底失去参考价值。所以做这个数据集评估之前首要任务就是确认测试集和训练集完全隔离。注意我见过有人把测试集当验证集用反复跑、反复看结果然后根据结果去调模型。这属于典型的“测试集泄漏”严格来说已经让测试集失去了评估意义。验证集做的事不应该让测试集再重复一遍。2. 数据集解构目录、标签与类别体系拿到一个数据集第一件事不是直接扔给模型跑而是先把它的结构和标签体系摸清楚。这一步看起来简单但恰恰是翻车率最高的环节。我拆飞机100分类数据集的时候按下面几个维度来梳理。2.1 一份标准的飞机100分类测试集长什么样以我常用的这份测试集为例目录结构大概是这样的aircraft_100_test/ ├── images/ │ ├── 000001.jpg │ ├── 000002.jpg │ ├── ... │ └── 010000.jpg ├── labels.csv ├── class_names.txt └── meta/ ├── train_val_split.txt └── original_source.txtimages目录下是纯图片文件文件名通常是数字编号不带类别信息这是为了防止有人直接靠文件名“作弊”。labels.csv保存了每张图片对应的类别id通常有两列——图片文件名和类别标签标签可能是一个数字id也可能直接是字符串类名。class_names.txt则是类别id和类别名称的映射表顺序基本是固定的模型输出层的大小就由这个文件的行数决定。图片数量和类别数量需要重点确认。一个完整的测试集100个类别每个类别可能放10到30张图片总量大约在1000到3000张之间。为什么要控制这个数量因为测试集不需要很大关键在于覆盖性。如果每个类别只有5张图那评估结果方差就很大如果每个类别放50张又占存储空间而且类别间数量严重不均衡时平均精度会被多数类带偏。我倾向于每个类别至少15到20张这样既能算单类别准确率又能在统计上有一定意义。图片格式和分辨率也要看。常见的是JPEG分辨率为224x224或更大。有些测试集的图片原始尺寸并不统一这会直接影响预处理流程。我在实际使用中遇到过600x400的图也遇到过1920x1080的图这说明数据来源可能混杂了网络图片和拍摄图片。针对这种情况统一缩放到模型输入尺寸之前要决定是直接resize还是先做中心裁剪这个选择会直接影响最终指标后面我会详细说。2.2 类别体系如何设计与校验飞机100分类的类别体系设计是一个容易被忽略但实际上非常讲究的问题。100个类到底怎么分是按制造商分——波音、空客、巴航工业、庞巴迪还是按机型分——波音737、波音747、空客A320、空客A380还是按用途分——民航客机、军用战斗机、通用航空、无人机我见过的一份类别清单是混合式的波音737-800波音747-400空客A320-200空客A350-900塞斯纳172派珀PA-28苏-27米格-29F-16战隼“全球鹰”无人机这种分类方式对模型提出了一个很有意思的挑战波音737-800和波音737-900之间的差异极小几乎只有机身长度和舱门数量不同而苏-27和米格-29都是双发重型战斗机气动布局相似如果不看尾锥结构和进气口位置很容易混淆。类别体系设计得越“刁钻”模型被逼着去关注的特征就越细这其实是好事因为模型学到的特征会更鲁棒迁移到其他细粒度任务时也更有效。校验标签时有几个坑要特别注意。最容易踩的坑是类别id和类别名错位——class_names.txt里的第37行对应的是波音737但labels.csv里编号37的图片其实是空客A320。这种错位很难用肉眼发现因为模型训练时它学到的是一个“错误但自洽”的映射最终测试集精度还会很高但实际部署时完全不能用。我的经验是抽20到30张图片人工确认真实类别再去对照labels.csv和class_names.txt三重校验。这个工作量不大但能避免灾难性的错误。另一个坑是类别不均衡。100个类如果有几个类别图片特别多比如波音737系列占了三成而某些冷门原型机只有一两张那么模型会倾向于把不确定的样本预测为高频类别。处理方式有两种一是在训练阶段用类别加权采样二是在评估阶段除了算整体准确率之外单独算每个类别的准确率取平均也就是balanced accuracy。后者对测试集的评估结果来说更公平。3. 实操过程用测试集跑通一个完整评估流程理论说多了容易飘实际操作才是硬功夫。下面我把用这份飞机100分类测试集评估模型的完整流程走一遍包括数据加载、预处理、模型推理、指标计算和结果分析。这套流程我实测过很多次直接照着用就行。3.1 数据加载与预处理第一步是把图片从目录里读进来并和处理标签对应上。如果labels.csv不是ImageFolder的标准结构我一般用Pandas读取标签再做映射然后配合PIL或OpenCV读取图片。数据加载这块有两个容易出问题的地方。第一图片损坏。数据集的图片源来自网络偶尔会出现几张小图片、全黑图、或者文件头不对的图。如果加载时报错不能直接跳过——跳过图片会导致labels.csv和数据集实际内容错位。我一般会先扫描一遍所有图片确认识别率坏图单独剔除并同步修正标签文件。第二图片的颜色通道。多数图片是RGB三通道但有些灰度图读进来是单通道如果不转成RGB模型推理时就会因为通道数不匹配报错或者某些框架自动广播导致结果异常。预处理环节使用torchvision的transforms来处理。这里有一个关键选择resize加中心裁剪还是直接resize以ResNet为例标准流程是先把短边缩放到256再在中心裁剪出224x224。这种方式在ImageNet上表现稳定但用在飞机识别上有一个潜在问题——如果图片里飞机本身很小只在画面中心占据一小块区域中心裁剪后可能会把机头和机翼截掉导致关键特征丢失。我的经验是对飞机这种“主体尺寸变化大”的识别任务如果你不确定图片里飞机占比宁可先resize到256x256再做224x224的中心裁剪也别直接拉伸到224x224——直接拉伸会让飞机长宽比失真细粒度特征跟着变形。更稳妥的方案是先用一个目标检测模型把飞机裁出来再送进分类器但在纯分类任务里没必要搞这么复杂resize加中心裁剪就够用了。标准化参数直接用ImageNet的均值方差就行因为模型权重是在ImageNet上预训练的。如果你用的是自训练模型且没用ImageNet初始化那标准化参数必须重新统计否则模型输入分布直接错掉精度会掉得莫名其妙。下面给出一段完整的数据加载代码基于PyTorchimport pandas as pd import torch from torch.utils.data import Dataset from PIL import Image from torchvision import transforms class AircraftTestDataset(Dataset): def __init__(self, img_dir, label_csv, transformNone): self.img_dir img_dir self.df pd.read_csv(label_csv) # 需要包含 filename, label_id 两列 self.transform transform or transforms.Compose([ transforms.Resize((256, 256)), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize( mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225] ) ]) def __len__(self): return len(self.df) def __getitem__(self, idx): row self.df.iloc[idx] img_path f{self.img_dir}/{row[filename]} image Image.open(img_path).convert(RGB) label int(row[label_id]) image self.transform(image) return image, label注意一个细节Image.open(img_path).convert(RGB)这一步的convert(RGB)不能省。即使原图是RGB这个转换也能把灰度图、带透明通道的PNG统一到RGB三通道。3.2 模型推理与评估指标模型选择上我用得最多的是ResNet50和ViT-B/16作为两个对照基准。ResNet50是CNN的经典代表在细粒度分类上性能稳定、调试方便ViT-B/16预训练权重大在ImageNet上表现更好但在小数据集上容易过拟合需要靠正则化和数据增强拉住。如果你只是想快速跑通流程ResNet50是最省心的选择。推理时有一个性能优化建议如果测试集图片有2000张逐张送进GPU会浪费大量时间在Python和CUDA之间的数据传输上。正确做法是组装一个DataLoaderbatch_size设为32或64用模型一次前向推理一个batch最后把输出拼接起来。GPU显存不够时优先降batch_size不要改用CPU硬扛——2000张图在CPU上跑ResNet50时间会从几分钟膨胀到半小时以上。评估指标的核心是Top-1和Top-5准确率。对飞机100分类这种类别间高度相似的细粒度任务Top-5准确率往往是更真实的能力反映。举个例子某张图真实类别是波音737-800模型Top-1预测成了波音737-900Top-5预测结果里其实包含了正确类别。从工程角度看这个模型并非“不认识这架飞机”只是无法区分737的两个子型号。如果评估指标只看Top-1你会低估模型的实际能力但反过来如果只看Top-5你又会忽略它在最细粒度区分上的不足。两个指标放一起看才有意义。除了准确率我还建议加一个混淆矩阵分析和单类别精度回收计算。混淆矩阵能直观看出哪些类别之间经常被混淆单类别精度和召回率则能发现“某个类别几乎没被模型正确预测过”的极端情况。比如苏-27和米格-29这种气动布局非常相似的飞机混淆矩阵里的这两块区域通常颜色很深这代表模型确实学到了相似的视觉特征但还无法区分其中的细微差异——这也是后续优化方向的重要信号。from torch.utils.data import DataLoader from torchvision import models import torch dataset AircraftTestDataset(aircraft_100_test/images, aircraft_100_test/labels.csv) loader DataLoader(dataset, batch_size64, shuffleFalse, num_workers4) model models.resnet50(weightsmodels.ResNet50_Weights.IMAGENET1K_V2) model.fc torch.nn.Linear(model.fc.in_features, 100) # 自定义类别数 model.load_state_dict(torch.load(aircraft_100_model.pth)) model.eval() all_preds [] all_labels [] import torch.nn.functional as F with torch.no_grad(): for images, labels in loader: outputs model(images) probs F.softmax(outputs, dim1) top5_preds probs.topk(5, dim1).indices # 取前5个预测 all_preds.append(top5_preds) all_labels.append(labels) all_preds torch.cat(all_preds, dim0) all_labels torch.cat(all_labels, dim0) top1_correct (all_preds[:, 0] all_labels).sum().item() top5_correct (all_preds all_labels.view(-1, 1)).any(dim1).sum().item() print(fTop-1 Accuracy: {top1_correct / len(all_labels):.4f}) print(fTop-5 Accuracy: {top5_correct / len(all_labels):.4f})这段代码就是标准的评估流程不需要复杂化。唯一要留意的是model.eval()不能漏否则模型里的Dropout和BatchNorm在推理时仍然以训练模式运行输出结果会带随机性复现性完全失控。3.3 结果解读与误差分析指标算出来只是第一步真正的分析才刚刚开始。我会把错误样本单独拎出来按错误类型分成三组第一组是“类别近邻错误”比如737-800被预测成737-900A320被预测成A321。这类错误说明模型已经学到了“这是波音737”或“这是空客A320家族”但缺乏区分子型号所需的精细特征。优化方向有两个一是把分辨率从224提到384让小尺寸的特征更清晰二是增加局部区域注意力机制比如在模型尾部加一个SE模块或CBAM注意力模块让网络关注机头、机翼这些判别性区域。第二组是“跨家族错误”比如把波音737预测成空客A320。这类错误说明模型学到的特征还不够深入可能是因为图片中飞机的朝向、角度比较刁钻或者遮挡严重。我排查这类错误时会去检查原始图像确认是否存在特殊机头形状、发动机短舱位置等关键区域如果这些区域在图片中确实可见但模型没抓住那就要考虑数据增强策略比如随机擦除——强制模型不要只依赖某一个局部的特征而是同时利用多个部位来做判断。第三组是“完全离谱错误”比如把一架波音747预测成战斗机。这种错误通常不是模型能力问题而是图片质量问题——可能是一架飞机只占画面极小区域被背景干扰也可能是图片经过了裁剪、拉伸飞机形状已经严重变形。这类错误在评估时可以直接剔除但在报告中要如实记录剔除原因不能为了让数字好看而忽略问题。每个类别的准确率也要单独算尤其关注那些准确率远低于平均值的类别。如果某个类别只有两三类图片且准确率为0那很可能是类别样本太少模型缺乏足够的数据支撑如果某个类别有20张图、准确率仍然为0那就是类别本身视觉特征太接近其他类别需要专门处理。4. 常见问题与排查技巧实录跑规模大一点的数据集各种意外真的会把人整崩溃。下面这些问题全是我在实际评测飞机100分类数据集时踩过的坑按照出现频率从高到低排一下。建议遇到问题时直接对照这个表来排查能省不少时间。问题现象可能原因排查方案加载图片时偶发崩溃图片文件损坏或格式非标准一次性扫描全部图片剔除损坏项并同步修正标签推理结果和论文/他人报告中差异巨大预处理不一致测试集划分不一致模型输入尺寸不同逐项确认图像缩放方式、裁剪区域、标准化参数Top-1很低但Top-5很高模型已掌握大类别但细粒度区分不足提高输入分辨率、增加注意力机制或者考虑更强的骨干网络某类别准确率明显偏低类别图片数量不均衡或视觉混淆度高查看混淆矩阵确认具体是被谁带偏的再做针对性数据补充同一模型多次推理结果不一致没有调用model.eval()Dropout仍在运行推理前务必设置eval模式测试集跑完想调整超参数再跑测试集被当验证集反复使用严格遵循训练/验证/测试三段分离测试集只在最终阶段使用一次4.1 图片读取与预处理不可控因素图片读取这块最容易阴沟翻船的是“你以为能读实际读不了”。我遇到过一个情况数据集里99%的图片都是标准JPEG但有几张图片文件后缀是.jpg实际编码却是PNG。PIL加载这种文件不会报错因为PIL会按文件头自动识别编码但某些框架的加载器是按后缀强制解码的结果就是这几张图直接崩溃。还有一类问题是非常规分辨率。大部分模型的预处理管线都假设输入尺寸固定但飞机图片里偶尔会出现超宽全景照片或者竖屏照片直接resize到224x224会把飞机拉成一个不自然的长条严重扭曲细粒度特征。我的建议是进入评估流程前先统计一遍全部图片的长宽比和分辨率分布做到心中有数。如果极端长宽比的图片占比超过5%最好先按长边缩放并进行pad操作或者用检测框先裁出飞机主体再送进分类网络。预处理另一个被忽视的环节是EXIF信息。手机或相机拍摄的图片可能包含旋转信息某些加载器会忽略EXIF方向标记导致图片变成横躺的。飞机图片一旦发生旋转模型几乎不可能正确预测。排查方法很简单随机抽几张图片人工看一眼如果有旋转情况用PIL的ImageOps.exif_transpose统一处理。4.2 指标对不上的深层原因“为什么我的结果和论文里写的差了5个点”这个问题几乎每隔几天就有人问。答案往往不神秘就是几个细节没对齐。第一是预处理管线不一致。论文里的输入分辨率可能是384而你在代码里用的是224论文用了随机裁剪做测试时增强而你只用了最朴素的resize。这些差异会直接反映在准确率上。我在评估时坚持“训练和测试使用同一套预处理规范”如果预训练模型是在特定预处理基础上训练的那么测试时也务必使用完全一致的预处理参数。第二是测试集版本不同。数据集可能在命名上完全一致但内部文件有细微差异。我自己就遇到过两个版本的labels.csv一个是某位博主重新整理过的另一个是官方原始版本标签重合率只有96%。官方渠道的数据集只要标了版本号就不要再跟第三方混着用。评估前先做一个简单的数据完整性校验统计图片总数量、类别总数、每个类别的图片数量和数据集描述文档做比对。第三是模型权重的问题。如果用的是torchvision.models.resnet50(weights...)默认的权重版本不同最终结果也会差零点几个点。在复现结果时务必记录权重版本号、PyTorch版本、CUDA版本和随机种子。评估结果想要稳定可复现这几个信息必须固定。4.3 关于数据泄漏的坑数据泄漏这个词听起来很高级但实际发生的情况往往很朴素。最常见的一种你从网络爬取飞机图片做训练而测试集也是从相似渠道汇总的两者之间包含了完全相同的图片——同一张照片在训练集和测试集里各出现了一次。模型相当于已经“见过”了测试图最终准确率会虚高。这种情况在飞机数据集里尤其容易发生因为飞机爱好者社区传播图片非常广泛同一张航空摄影作品会出现在多个平台。排查泄漏的方法是图片去重。最简单的方案是计算每张图片的感知哈希pHash将训练集和测试集的感知哈希进行比对相似度超过阈值就标记为疑似重复再人工确认。如果在测试集里发现了和训练集几乎一样的图片稳妥的做法是直接剔除或者把它从测试集里移出不要让“背答案”的图片拉高你的评估指标。另一个容易被忽视的泄漏路径是标签泄漏——严格来说和图片无关但影响结果。比如有些数据集的图片文件名本身包含类别缩写或者labels.csv里除了类别id之外还带了一列“来源网站”之类的信息。如果你的模型输入里不小心把这些带进去了本质上也是一种间接泄漏。处理方式是只保留评估必需的字段别把多余的信息传到模型分支里。5. 扩展方向从100类到更复杂的细粒度识别飞机100分类数据集只是起点把评估流程跑通之后能扩展的方向非常多。这里说几个我认为最值得投入精力的方向也是在实际项目中验证过可行的。5.1 从整机分类到部件级识别整机分类做到90%以上的准确率之后边际收益会迅速下降。此时更好的思路是往下沉一层做部件级识别——识别飞机的机头类型、发动机短舱形状、翼尖小翼样式、尾翼构型。这些部件特征组合起来就是识别飞机型号的“指纹”。实战中我试过用检测模型先定位部件的关键区域再结合整机分类特征去投票最终效果比单纯分类器做集成还要稳定。细粒度领域有一个经典的一阶/二阶注意力思路第一阶段用全局特征找出“哪里存在关键差异”第二阶段对差异区域的局部特征做精细识别。在航空器识别上这个思路执行起来非常直观——机头曲线最陡的地方、翼尖小翼上翘的角度、发动机挂架的形状这些区域提取出来之后即使分辨率不够高也能提供很好的判别信息。5.2 自监督与半监督在飞机识别上的应用飞机图片的网络来源非常丰富但标注成本高尤其是细粒度分类的标注需要懂航空知识的人才能准确区分机型。因此半监督学习路线很有意思先用少量已标注的飞机图片训练一个初始模型再用它对大量未标注的飞机图打伪标签挑置信度高的样本加入训练集如此迭代。自监督预训练也可以做比如用MAE或MoCo在一大批无标注飞机图上预训练特征提取器再在少量标注数据上微调能明显缓解标签不足的问题。但用自监督或半监督流程时测试集的使用边界需要更加严格。伪标签只能从“无标签的真实数据”里生成绝不能用测试集去生成伪标签并反向加入训练——这属于严重的测试集泄漏而且这种方式在学术和实际部署中都是明确禁止的。正确的做法是把测试集当作最终验收标准中间任何策略迭代都用验证集来决定是否保留。5.3 面向移动端和边缘设备的轻量化这套流程跑通之后自然会有人问“模型能不能放到手机上跑”飞机识别应用典型的场景包括航空摄影爱好者拍完照后快速识别机型、机场调度辅助系统的边缘端初筛、无人机识别其他航空器等。这些场景的共同限制是算力低、内存小不能直接跑ResNet50甚至ViT。用测试集做轻量化评估时需要关注的不再只是Top-1/Top-5准确率而是精度和时延的平衡点。我一般会同时测MobileNetV3、EfficientNet-Lite、GhostNet这些轻量网络的准确率再配合同一测试集上的单帧推理耗时。比如在iPhone 13上EfficientNet-Lite单帧推理可以压到10毫秒以内但准确率比ResNet50低4到6个百分点。这个差距在有些场景可以接受有些场景不能接受关键看业务容忍度。部署层的另一个常见需求是安卓窗口图像识别——简单说就是在手机屏幕上截取当前画面将画面中的飞机区域送到分类模型里再把识别结果叠加显示出来。这种方案对识别延迟敏感上一段说的轻量化评估在这类场景下特别重要。不过窗口截取和分类模型本身是两层逻辑分类模型的好坏直接决定了最终识别效果的上限。如果项目最终要部署我建议测试集里专门追加一组“低质量图片”子集——模拟低分辨率、强压缩噪声、运动模糊的真实场景。这批子集在开发阶段不参与任何模型选择只在最终验收时作为加试题。实测下来很多在标准测试集上准确率很高的模型遇到低分辨率图片时性能会断崖式下跌。提前准备一张“压力测试卷”总比上线之后被真实环境笑话强。6. 踩坑之后的几点实用经验最后聊几个我自己在飞机100分类数据集的评测中反复验证过的经验不一定成体系但很实用。先说训练和测试的预处理一致性。无论你用什么模型训练时用了随机裁剪、随机翻转、颜色抖动测试时就必须只用确定的预处理管线。很多人训练涨点全靠增强策略但测试时忘了关掉随机增强那出来的结果波动会非常大。我的习惯是训练和测试的transforms分开写测试transform永远固定不包含任何随机操作。再说测试集的使用时机。我在实践中的建议是拿到数据集后先不要急着看测试集先把训练集和验证集的划分做好。把测试集“晾”在一边只在模型最终定稿之后才跑一次。如果过程中因为什么原因看了测试集、调了模型那就要意识到这个测试集已经“脏”了最终指标只能作为参考不能作为结论。实际项目里如果遇到这种情况我会去寻找新的测试数据重新建一个干净测试集而不是继续在旧测试集上反复比划。关于Top-1和Top-5的选择没有绝对的对错取决于业务需求。如果你做的功能是“飞机型号识别给航空爱好者看”Top-1必须高因为用户没有耐心看5个候选答案自己去猜如果你做的是“机场地勤辅助系统”Top-5可以接受因为最后还有人工确认环节模型的关键价值在于不把正确识别选项漏掉。飞机100分类数据集恰好能同时提供这两项指标这也是它适合做细粒度识别基准的原因。最后一个很现实的建议记录评估的完整环境信息。跑一次测试集之前把Python版本、框架版本、CUDA版本、模型权重版本、输入分辨率、预处理方式、随机种子全部记录下来。同一套代码一周后你重跑可能就得乱掉。一个规范的评估记录能让你未来复现结果、排查问题时节省大量时间。这些看着不重要的“琐事”往往是项目后期最值钱的东西。本文还有配套的精品资源点击获取