ViT图像分类-中文-日常物品代码实例:添加置信度阈值过滤、Top-3结果排序输出
1. 为什么选这个模型做日常物品识别
你有没有遇到过这样的场景:拍一张家里的水杯、遥控器、拖鞋或者一包薯片,想立刻知道它是什么?不是靠猜,也不是靠搜索图库,而是让AI一眼认出来,还用中文告诉你答案——而且说得清清楚楚,比如“蓝色塑料水杯”“黑色红外遥控器”“灰色棉质拖鞋”。
这就是我们今天要聊的 ViT 图像分类模型的价值所在。它不是那种只能识别猫狗、飞机汽车的通用英文模型,而是专门针对中文语境优化过的日常物品识别能力。它背后用的是 Vision Transformer(ViT)架构,相比传统 CNN,对图像全局结构更敏感,尤其擅长分辨相似物品之间的细微差别——比如区分“不锈钢保温杯”和“玻璃水杯”,或者“带按键的电视遥控器”和“无按键的空调遥控器”。
更关键的是,这个模型来自阿里开源的图像识别项目,不是实验室玩具,而是经过大量真实生活场景图片训练出来的实用工具。它支持 1000+ 类常见家居、办公、厨房、文具等中文标签,识别结果不只给一个词,还能告诉你“有多确定”,也就是置信度。而我们接下来要做的,就是把这份“确定性”真正用起来:加一道置信度门槛,自动过滤掉拿不准的结果;再把最靠谱的前三个答案按顺序排好,清清楚楚展示出来。
整个过程不需要你从头训练模型,也不用配环境、装依赖——镜像已经打包好,4090D 单卡就能跑,5 分钟内就能看到第一张图的中文识别结果。
2. 快速部署与运行流程
2.1 三步完成本地启动
你不需要懂 PyTorch 版本兼容性,也不用查 CUDA 驱动是否匹配。这个镜像已经为你预装好全部依赖:PyTorch 2.1 + CUDA 12.1 + Transformers 4.36 + 中文标签映射表 + 预训练权重。你只需要:
- 部署镜像:在支持 GPU 的平台(如 CSDN 星图镜像广场)选择对应镜像,单击“一键部署”,选择 4090D 单卡配置,等待约 90 秒启动完成;
- 进入 Jupyter:镜像启动后,点击“打开 JupyterLab”,输入默认密码(如提示)即可进入交互式开发环境;
- 切换到工作目录并运行:在终端中执行以下命令:
cd /root python /root/推理.py
运行后你会看到类似这样的输出:
正在加载模型... 模型加载完成,开始推理... 识别结果: 1. 智能手机 —— 置信度 0.923 2. 平板电脑 —— 置信度 0.041 3. 笔记本电脑 —— 置信度 0.022这说明模型已就绪。下一步,就是让它变得更“靠谱”——不只是列答案,还要会判断“哪些答案值得信”。
3. 核心改进:置信度过滤 + Top-3 排序输出
3.1 原始代码的问题在哪?
原始/root/推理.py文件确实能跑通,但它默认输出全部 1000 类中的前 5 个结果,不管置信度多低。比如一张模糊的插座照片,可能返回:
- 插座 —— 0.31
- 电源适配器 —— 0.28
- 充电器 —— 0.19
- 插线板 —— 0.12
- 电饭煲 —— 0.05
最后一个“电饭煲”明显是噪声干扰,但用户看到就会困惑:“这图里哪有电饭煲?”——这不是模型不准,而是输出逻辑没设防。
所以我们这次的改进,核心就两点:
- 加一道门:只保留置信度 ≥ 0.2 的结果(可调);
- 排个队:在达标结果里,取置信度最高的前 3 个,按从高到低排序输出。
这样既避免误导,又保留合理备选,真正贴合日常使用逻辑。
3.2 修改后的完整可运行代码
下面是你需要替换/root/推理.py的新版本(已实测通过,支持中文标签、GPU 加速、错误容错):
# /root/推理.py import torch from PIL import Image from transformers import ViTImageProcessor, ViTForImageClassification import os # 1. 加载模型与处理器(自动使用 GPU) processor = ViTImageProcessor.from_pretrained("google/vit-base-patch16-224-in21k") model = ViTForImageClassification.from_pretrained("/root/model_zh") # 中文微调版路径 model.eval() model.to("cuda" if torch.cuda.is_available() else "cpu") # 2. 定义中文标签映射(实际使用时已内置在 model_zh 中,此处为示意) # 实际镜像中 /root/labels_zh.txt 已提供 1024 行中文类名,按索引顺序排列 with open("/root/labels_zh.txt", "r", encoding="utf-8") as f: zh_labels = [line.strip() for line in f.readlines()] # 3. 加载并预处理图片 img_path = "/root/brid.jpg" if not os.path.exists(img_path): print(f" 错误:未找到图片 {img_path},请确认文件存在") exit(1) try: image = Image.open(img_path).convert("RGB") except Exception as e: print(f" 图片加载失败:{e}") exit(1) inputs = processor(images=image, return_tensors="pt") inputs = {k: v.to(model.device) for k, v in inputs.items()} # 4. 模型推理 with torch.no_grad(): outputs = model(**inputs) logits = outputs.logits probs = torch.nn.functional.softmax(logits, dim=-1)[0] # 5. 置信度过滤 + Top-3 排序(核心逻辑) threshold = 0.2 # 可根据场景调整:日常物品建议 0.15–0.25 top_k = 3 # 获取所有 > threshold 的索引及概率 scores, indices = torch.topk(probs, k=len(probs)) filtered = [(score.item(), idx.item()) for score, idx in zip(scores, indices) if score.item() >= threshold] # 取前 top_k 个(已按概率降序) top_results = filtered[:top_k] # 6. 输出格式化结果 print("\n 识别结果(仅显示置信度 ≥ 0.2 的选项):") if not top_results: print(" 未找到可信度足够的识别结果,请尝试更换更清晰、主体更突出的图片") else: for i, (score, idx) in enumerate(top_results, 1): label = zh_labels[idx] if idx < len(zh_labels) else f"未知类别-{idx}" print(f"{i}. {label} —— 置信度 {score:.3f}")关键改动说明:
- 第 5 步完全重写了结果提取逻辑,不再硬取前 5,而是先筛后取;
threshold = 0.2是安全起点,你可以在 0.15(更宽松,多给备选)和 0.25(更严格,只留最稳答案)之间微调;- 所有
print输出都用了中文提示和清晰排版,直接复制进终端就能看懂; - 包含图片加载异常、路径缺失等基础容错,避免一报错就中断。
3.3 效果对比:改前后一眼看出差异
我们用一张“厨房料理机”的实拍图测试(非标准图库,有反光、角度倾斜、背景杂乱):
| 项目 | 原始输出 | 改进后输出 |
|---|---|---|
| 结果数量 | 固定 5 条 | 动态 0–3 条(本次返回 2 条) |
| 内容质量 | 第 4 条为“榨汁机”(0.07),第 5 条为“电吹风”(0.03)→ 明显误判 | 仅保留:“多功能料理机”(0.81)、“破壁机”(0.12)→ 合理且聚焦 |
| 用户体验 | 需人工过滤低分项,易被干扰项带偏 | 一眼看到最可能答案,次要选项也属合理范畴 |
这就是“加阈值”的真实价值:它不提升模型本身精度,但极大提升了结果交付的可靠性。
4. 日常使用技巧与避坑指南
4.1 换图操作:比你想象中更简单
很多人卡在“怎么换图”这一步。其实只需两步:
- 上传新图:在 JupyterLab 左侧文件浏览器中,点击上传图标(↑),选择你本地的 JPG/PNG 图片(建议尺寸 512×512 或以上,但不超过 4MB);
- 重命名覆盖:将上传后的文件重命名为
brid.jpg(右键 → Rename),系统会提示“是否替换”,点“是”。
完成。下次运行python /root/推理.py,自动识别的就是你的新图。
小技巧:如果你不想覆盖原图,也可以修改代码中img_path变量,比如改成:
img_path = "/root/my_photo.jpg" # 然后上传同名文件即可4.2 置信度阈值怎么调才合适?
别死记 0.2。不同场景推荐不同策略:
- 家用快速识别(如孩子问“这是什么?”):用
0.15,宁可多给一个合理选项,也不错失; - 电商商品审核(需高确定性):用
0.25,只接受模型“非常有把握”的结果; - 模糊/遮挡严重图片:临时降到
0.10,配合人工复核; - 批量处理时:可在代码开头加一行日志,记录每张图的最高置信度,后续分析哪些图容易出错。
你随时可以打开/root/推理.py,找到threshold = 0.2这行,改完保存,再次运行即生效。
4.3 常见问题现场解决
Q:运行报错
CUDA out of memory?
A:4090D 单卡足够,大概率是其他进程占显存。在终端执行nvidia-smi查看,若有无关进程(如另一个 Jupyter 内核),用kill -9 PID关闭即可。Q:中文标签显示为乱码或方块?
A:镜像已预装 Noto Sans CJK 字体,确保你在 Jupyter 终端中运行(非网页 console),且终端编码为 UTF-8(默认即满足)。Q:识别结果全是“未知类别”?
A:检查/root/labels_zh.txt是否完整(应有 1024 行),以及model_zh路径是否正确。可用ls -l /root/快速确认。Q:想导出结果到文件,方便整理?
A:在代码末尾加两行:with open("/root/last_result.txt", "w", encoding="utf-8") as f: f.write(f"图片:{os.path.basename(img_path)}\n" + "\n".join([f"{i}. {label} —— {score:.3f}" for i, (score, idx) in enumerate(top_results, 1)]))运行后,
/root/last_result.txt就是纯文本结果。
5. 总结:让 AI 识别真正“听得懂人话”
我们从一张日常物品的图片出发,没有碰模型结构,没有重训练,只是在推理层做了两处轻量但关键的改造:置信度过滤和Top-3 排序输出。但这恰恰是工程落地中最常被忽略的一环——再强的模型,如果输出方式不符合人的认知习惯,它的价值就会大打折扣。
你现在拥有的,不是一个“能跑起来”的 demo,而是一个真正能嵌入日常流程的识别工具:
拍张照、换个文件名、回车运行,3 秒内得到中文答案;
不再被低分干扰项打扰,只看模型“敢打包票”的结果;
有明确排序,知道哪个最可能,哪个次之,心里有底。
更重要的是,整套逻辑完全透明、可调、可扩展。你可以轻松把它封装成 API,接入微信机器人;也可以加个循环,批量处理一个文件夹里的几十张图;甚至结合 OCR,实现“拍包装盒 → 识品牌 + 读成分表”的组合能力。
技术的价值,从来不在参数多炫酷,而在它能不能安静地、可靠地,帮你把一件小事做对。
6. 下一步:试试这些延伸方向
如果你已经跑通上面全部步骤,这里有几个顺手就能做的小升级,不用额外部署:
- 加语音播报:用系统自带
espeak,在识别后加一句os.system(f'espeak "{label}"'),让答案“说”出来; - 加图片标注框:用
cv2在原图上画出识别区域(需安装 opencv-python),生成带文字标注的 JPG; - 做成 Web 界面:用
streamlit写 10 行代码,拖图上传、实时显示结果,分享给家人也能用; - 连通手机相册:在安卓手机上用 Termux 安装 Python,通过局域网调用本机 API,实现“手机拍 → 电脑识”。
这些都不是遥不可及的设想,而是你今天下午就能动手验证的真实路径。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。