当前位置: 首页 > article >正文

TT100K数据集类别不平衡?手把手教你用Python筛选并重划分(保留45类实战)

TT100K数据集类别不平衡解决方案Python实战指南当你第一次打开TT100K数据集时可能会被其庞大的图片数量震撼——train文件夹6105张test文件夹3071张other文件夹更是多达7641张。但兴奋过后细看类别分布问题就来了某些交通标志类别只有寥寥几张图片而其他类别却堆积如山。这种极端不平衡的数据分布直接训练模型效果往往惨不忍睹。1. 理解TT100K数据集的核心问题TT100K数据集全称Tsinghua-Tencent 100K是清华大学与腾讯联合发布的交通标志识别数据集。它包含上百种不同类型的交通标志但分布极不均匀数量差异悬殊部分常见标志有上千张图片而稀有标志可能只有个位数样本原始划分不合理train/test/other的划分方式不符合实际训练需求标注格式复杂原始标注信息需要额外处理才能用于主流框架我在处理这个数据集时发现直接使用原始划分训练出的模型在小样本类别上准确率几乎为零。经过多次实验总结出以下关键数据清洗原则数据清洗黄金法则删除样本量不足的类别往往比保留它们更能提升整体模型性能2. 环境准备与数据统计首先确保你的Python环境已安装以下必要库pip install numpy pandas pillow matplotlib opencv-python数据集目录结构通常如下tt100k_2021/ ├── annotations/ ├── other/ ├── test/ └── train/2.1 统计类别分布创建analyze_tt100k.py脚本统计每个类别的图片数量import os import json from collections import defaultdict def count_categories(data_dir): with open(os.path.join(data_dir, annotations.json)) as f: anno json.load(f) cat_count defaultdict(int) for img_id, img_info in anno[imgs].items(): for obj in img_info[objects]: cat_count[obj[category]] 1 return sorted(cat_count.items(), keylambda x: x[1], reverseTrue) if __name__ __main__: data_root tt100k_2021 counts count_categories(data_root) print(Top 10 categories by count:) for cat, cnt in counts[:10]: print(f{cat}: {cnt}) print(\nCategories with 100 samples:) under_100 [(cat, cnt) for cat, cnt in counts if cnt 100] for cat, cnt in under_100: print(f{cat}: {cnt})执行后会输出类似这样的结果Top 10 categories by count: pl100: 1243 pl120: 987 pl80: 876 [...] Categories with 100 samples: pm20: 23 ph4: 15 [...]2.2 可视化分析添加可视化代码更直观理解数据分布import matplotlib.pyplot as plt def plot_category_distribution(counts, threshold100): categories [x[0] for x in counts] counts [x[1] for x in counts] plt.figure(figsize(12, 6)) plt.bar(range(len(categories)), counts) plt.axhline(ythreshold, colorr, linestyle--) plt.xticks(range(len(categories)), categories, rotation90) plt.xlabel(Category) plt.ylabel(Count) plt.title(TT100K Category Distribution) plt.tight_layout() plt.savefig(category_distribution.png) plt.show()3. 数据清洗与类别筛选基于统计结果我们决定只保留样本量≥100的类别。以下是具体实现步骤3.1 创建类别过滤函数def filter_categories(data_dir, min_samples100): with open(os.path.join(data_dir, annotations.json)) as f: anno json.load(f) # 统计有效类别 valid_cats set() cat_count defaultdict(int) for img_id, img_info in anno[imgs].items(): for obj in img_info[objects]: cat_count[obj[category]] 1 valid_cats {cat for cat, cnt in cat_count.items() if cnt min_samples} print(fKeeping {len(valid_cats)} categories with ≥{min_samples} samples) # 过滤标注 new_anno {imgs: {}, types: anno[types]} kept_imgs 0 for img_id, img_info in anno[imgs].items(): valid_objs [obj for obj in img_info[objects] if obj[category] in valid_cats] if valid_objs: new_img_info img_info.copy() new_img_info[objects] valid_objs new_anno[imgs][img_id] new_img_info kept_imgs 1 print(fKept {kept_imgs} images with valid categories) return new_anno, valid_cats3.2 保存过滤后的标注def save_filtered_annotations(annotations, output_path): with open(output_path, w) as f: json.dump(annotations, f, indent2) print(fFiltered annotations saved to {output_path}) # 使用示例 filtered_anno, valid_cats filter_categories(tt100k_2021) save_filtered_annotations(filtered_anno, tt100k_2021/filtered_annotations.json)4. 数据集重新划分策略经过过滤后我们需要将数据重新划分为train/val/test三部分。推荐以下比例数据集比例图片数量示例Train70%~6800Val20%~1900Test10%~10004.1 划分实现代码import random import shutil def split_dataset(data_dir, output_dir, valid_cats, ratios(0.7, 0.2, 0.1)): # 确保输出目录存在 os.makedirs(output_dir, exist_okTrue) for subset in [train, val, test]: os.makedirs(os.path.join(output_dir, subset), exist_okTrue) # 收集所有有效图片路径 img_paths [] for subset in [train, test, other]: subset_dir os.path.join(data_dir, subset) for img_file in os.listdir(subset_dir): if img_file.endswith(.jpg): img_id os.path.splitext(img_file)[0] if img_id in filtered_anno[imgs]: img_paths.append((img_id, os.path.join(subset_dir, img_file))) # 随机打乱并划分 random.shuffle(img_paths) total len(img_paths) train_end int(total * ratios[0]) val_end train_end int(total * ratios[1]) # 复制文件 for i, (img_id, src_path) in enumerate(img_paths): if i train_end: dst train elif i val_end: dst val else: dst test shutil.copy(src_path, os.path.join(output_dir, dst, f{img_id}.jpg)) print(fDataset split complete: {total} images) print(fTrain: {train_end}, Val: {val_end-train_end}, Test: {total-val_end})4.2 划分后验证为确保划分质量建议检查每个子集的类别分布是否均衡是否有图片损坏标注文件是否正确对应def verify_split(output_dir, filtered_anno): # 检查图片完整性 for subset in [train, val, test]: subset_dir os.path.join(output_dir, subset) print(f\nVerifying {subset}:) img_files [f for f in os.listdir(subset_dir) if f.endswith(.jpg)] print(fTotal images: {len(img_files)}) # 检查随机样本 sample random.sample(img_files, min(5, len(img_files))) for img_file in sample: img_id os.path.splitext(img_file)[0] try: img Image.open(os.path.join(subset_dir, img_file)) img.verify() print(f{img_file}: OK, {len(filtered_anno[imgs][img_id][objects])} objects) except Exception as e: print(f{img_file}: Error - {str(e)})5. 高级技巧与优化建议5.1 处理剩余类别的策略对于被过滤掉的小样本类别可以考虑数据增强对剩余样本应用旋转、色彩变换等迁移学习先在大类上预训练再微调小类分层采样确保每个batch包含所有类别样本5.2 性能优化技巧处理大规模数据集时这些技巧可以节省时间# 使用多进程加速文件复制 from multiprocessing import Pool def copy_file(args): src, dst args shutil.copy(src, dst) def parallel_copy(file_pairs, workers4): with Pool(workers) as p: p.map(copy_file, file_pairs)5.3 常见问题排查问题现象可能原因解决方案标注文件缺失路径错误检查annotations.json路径图片数量不符过滤条件太严格调整min_samples阈值内存不足一次加载所有图片改用生成器分批处理6. 完整流程整合将所有步骤整合为可执行脚本process_tt100k.py#!/usr/bin/env python3 Complete TT100K dataset processing pipeline import os import json import random import shutil from collections import defaultdict from PIL import Image from multiprocessing import Pool # [之前定义的所有函数...] def main(): data_dir tt100k_2021 output_dir tt100k_processed min_samples 100 print(Step 1: Analyzing category distribution...) filtered_anno, valid_cats filter_categories(data_dir, min_samples) print(\nStep 2: Saving filtered annotations...) save_filtered_annotations(filtered_anno, os.path.join(output_dir, annotations.json)) print(\nStep 3: Splitting dataset...) split_dataset(data_dir, output_dir, valid_cats) print(\nStep 4: Verifying results...) verify_split(output_dir, filtered_anno) print(\nProcessing complete!) if __name__ __main__: main()执行这个脚本后你将获得一个结构清晰、类别平衡的数据集可直接用于模型训练。在我的实际项目中经过这样的处理后模型在测试集上的mAP提升了约15-20%特别是小样本类别的识别准确率有了显著改善。

相关文章:

TT100K数据集类别不平衡?手把手教你用Python筛选并重划分(保留45类实战)

TT100K数据集类别不平衡解决方案:Python实战指南当你第一次打开TT100K数据集时,可能会被其庞大的图片数量震撼——train文件夹6105张,test文件夹3071张,other文件夹更是多达7641张。但兴奋过后,细看类别分布&#xff0…...

避坑指南:在openEuler 22.03上配置vsftpd虚拟用户,解决PAM认证和SELinux权限问题

深度实战:openEuler 22.03中vsftpd虚拟用户配置全流程与疑难解析 在服务器运维领域,FTP服务作为经典的文件传输方案,其安全配置一直是系统管理员的核心技能。本文将聚焦openEuler 22.03操作系统环境,深入剖析vsftpd虚拟用户模式的…...

代码智能安全:对抗机器学习如何威胁与守护AI编程助手

1. 项目概述:代码智能时代的安全暗礁 作为一名在软件安全与AI交叉领域摸爬滚打了十多年的从业者,我亲眼见证了代码语言模型(CLM)从实验室的奇思妙想,迅速演变为GitHub Copilot、Amazon CodeWhisperer等生产力工具的核心…...

SPSS+Excel搞定SCI必备技能:零代码绘制Logistic回归亚组交互效应图

SPSSExcel零代码绘制Logistic回归亚组交互效应图:临床研究者的可视化救星"统计结果显著,但图表被审稿人打回重做"——这可能是临床研究者最头疼的问题之一。亚组交互效应分析作为高分SCI文章的"黄金标配",其可视化呈现直…...

【ChatGPT】阳极氧化线 Global SI 自动化系统深度拆解、爆炸图10张、信息图10张、C++代码框架

深度拆解爆炸图...

棋牌网站渗透测试实战:弱口令与SQL注入组合利用

1. 为什么棋牌类网站是渗透测试的“黄金靶场”——从业务逻辑反推攻击面你有没有试过在凌晨两点,打开一个刚注册的棋牌平台,随手输了个“admin/admin123”,页面直接跳转到后台管理首页?我第一次遇到这种事时,手都停在键…...

告别驱动冲突:在预装NVIDIA驱动的Deepin V23 Beta3上干净安装指定版本显卡驱动

深度清理与精准部署:Deepin V23 Beta3下NVIDIA驱动版本管理的终极指南当你在Deepin V23 Beta3上勾选"集成NVIDIA闭源驱动"时,系统究竟做了哪些改动?这个问题困扰着许多需要特定驱动版本支持CUDA或AI框架的用户。预装驱动带来的便利…...

Win10硬盘分区后盘符出现黄色感叹号?别慌,这是BitLocker在‘待机’,教你5分钟彻底关闭它

Win10硬盘分区后盘符出现黄色感叹号?5分钟解除BitLocker待机状态全指南当你完成Win10硬盘分区调整后,突然发现资源管理器中的盘符旁出现了醒目的黄色感叹号标志,这确实会让人心头一紧。别担心,这并非硬盘故障或数据丢失的征兆&…...

Mac上mitmproxy HTTPS抓包实战:证书配置与Python脚本化

1. 为什么Mac用户需要真正掌握mitmproxy,而不是只装个Charles? 在Mac上做移动端或Web前端调试时,很多人第一反应是打开Charles——界面友好、点几下就能看到HTTP请求。但真正在一线做过API联调、小程序逆向、自动化测试或安全审计的人心里都清…...

Windows关机修复机制:漏洞补丁静默安装原理与实操

1. 这不是“一键修复”,而是系统级补丁调度机制的落地实践很多人看到“360安全卫士漏洞修复全新升级”这个标题,第一反应是:又一个弹窗广告式功能更新。但如果你真点开设置页、翻过日志、对比过前后两次关机流程的系统行为,就会发…...

Unity项目降级回退的四层错误诊断与三步修复法

1. 这不是版本降级,是Unity项目“时空错位”的典型症状 很多人看到“unity回到低版本报错”,第一反应是:“不就是把高版本工程拖进低版本编辑器里打开嘛?点一下确定不就完了?”——我去年在接手一个外包美术团队交付的…...

AssetStudio深度原理与Unity资源逆向实战指南

1. 这不是“又一个Unity资源提取教程”,而是我三年里反复重装AssetStudio的总结AssetStudio、Unity资源提取、Unity游戏逆向、Unity AssetBundle解析——这几个词,几乎是我过去三年在独立游戏开发、MOD社区支持和老游戏存档修复工作中出现频率最高的关键…...

8051单片机16位SFR访问原理与安全实践

1. 16位特殊功能寄存器(SFR)的基础概念在8051单片机开发中,特殊功能寄存器(Special Function Register,简称SFR)是CPU与外围设备交互的关键接口。标准的8位SFR使用sfr关键字定义,而16位SFR则需要…...

Tomcat路径规范化漏洞:CVE-2024系列信息泄露深度解析

1. 这三个CVE不是“远程代码执行”,但比很多RCE更值得你立刻放下手头工作去查Apache Tomcat 信息泄露漏洞CVE-2024-21733、CVE-2024-21733、CVE-2024-24549和CVE-2024-34750——光看编号就容易让人划走:又是一堆CVE,又得翻公告,又…...

FModel深度指南:UE5.3+ Pak解包与Nanite资源导出实战

1. 这不是“下载器”,而是一把解构现代游戏资产的手术刀很多人第一次听说FModel,是在某个游戏论坛里看到一句轻描淡写的“用FModel扒资源”。于是下载、双击、拖进exe——结果卡在“Loading Pak Files”十分钟不动,或者导出一堆黑屏贴图、错位…...

Fiddler HTTPS抓包失败原因与证书信任机制详解

1. 为什么HTTPS抓包总在“证书这关”卡死?——不是Fiddler不行,是系统和APP联手设防Fiddler HTTPS抓包避坑指南:从证书安装失败到APP抓包不全的完整解决方案——这个标题里藏着太多人反复踩坑却始终没想通的真相。我带过三届移动测试团队&…...

APP 的架构设计

APP 的架构设计是指构建移动应用时的整体结构规划,主要解决“代码怎么组织、模块怎么分工、数据怎么流动、功能怎么扩展”等问题。一个好的架构能让 APP 更稳定、更易维护、更易多人协作和长期迭代。下面从常见架构模式 → 核心分层 → 设计原则 → 技术选型 → 实际…...

Netcat (nc) 全面使用指南

Netcat 被誉为网络工具中的"瑞士军刀",是一个功能强大的网络调试和诊断工具。它可以在 TCP/UDP 协议下进行连接、监听、端口扫描、文件传输和代理转发等操作。 一、安装与基本语法 1.1 安装方法 操作系统安装命令Ubuntu/Debiansudo apt install netcat…...

SSH Host key verification failed 原因与安全处理指南

1. 这个报错不是故障,而是SSH在认真履职“Host key verification failed”——第一次看到这个提示时,我正远程部署一个客户服务器,敲完ssh user192.168.3.45回车,终端突然卡住两秒,然后跳出这行红字,后面还…...

别再只用XGBoost了!用Python手把手教你玩转Stacking和Blending模型融合

别再只用XGBoost了!用Python手把手教你玩转Stacking和Blending模型融合当你在Kaggle竞赛中反复调整XGBoost参数却始终无法突破0.01的AUC提升,或者在业务场景中发现单一模型对某些特殊样本总是预测失误时,或许该换个思路了——就像交响乐团需要…...

从客户分群到市场细分:系统聚类法在Python/R中的商业案例分析

从客户分群到市场细分:系统聚类法在Python/R中的商业案例分析在商业分析领域,数据驱动的决策正变得越来越重要。无论是电商平台的用户画像构建,还是零售行业的市场细分,亦或是金融领域的风险评估,聚类分析都扮演着关键…...

qmcdump完整指南:3步轻松解密QQ音乐加密文件

qmcdump完整指南:3步轻松解密QQ音乐加密文件 【免费下载链接】qmcdump 一个简单的QQ音乐解码(qmcflac/qmc0/qmc3 转 flac/mp3),仅为个人学习参考用。 项目地址: https://gitcode.com/gh_mirrors/qm/qmcdump qmcdump是一款简…...

量子机器学习提升软件测试效率的混合优化框架

1. 量子机器学习如何革新软件测试效率在DevOps和敏捷开发成为主流的今天,软件测试面临着前所未有的挑战。传统测试方法在应对现代复杂系统时显得力不从心——根据行业调研,大型系统中测试环节消耗的开发资源高达40-50%。更棘手的是,随着微服务…...

ARM ETE跟踪单元与单次比较器控制技术解析

1. ARM ETE跟踪单元的核心机制解析在嵌入式系统调试领域,ARM的嵌入式跟踪扩展(Embedded Trace Extension, ETE)提供了一套完整的指令执行流监控方案。其核心组件跟踪单元(Trace Unit)通过地址比较器(Address Comparator)实现细粒度的执行监控,能够捕获特…...

3DMAX傻瓜式插件SimpleRope:一键生成绳子软管螺旋线!

3MAX简单绳子插件SimpleRope,从样条线生成螺旋线网格(包括简单的绳子)。本教程将带你全面掌握SimpleRope插件的使用方法,从普通的绳子、柔性的软管,到参数可调的螺旋线,只需一条样条线路径,点击…...

ARM SVE2指令集与USUBWB指令优化实践

1. ARM SVE2指令集概述在当今计算密集型应用领域,向量处理能力已成为衡量处理器性能的关键指标。ARM架构的Scalable Vector Extension 2(SVE2)作为第二代可扩展向量指令集,在2021年随ARMv9架构一同发布,为高性能计算领…...

ARM SVE2向量指令UQSHLR与URSHLR详解

1. ARM SVE2向量指令概述在ARMv9架构中,SVE2(Scalable Vector Extension 2)作为第二代可伸缩向量扩展,为高性能计算和机器学习工作负载提供了强大的并行处理能力。与传统的NEON指令集相比,SVE2最大的特点是支持向量长度…...

【架构实战】解决长文本多轮对话中的“上下文腐化”问题:基于 Multi-Agent 的异步调度引擎设计

大家好,最近在研究 LLM 辅助编程和多角色对话时,我发现了一个非常头疼的问题:“上下文腐化”(Context Rot)。 当你在一个 Session 里塞入多个 System Prompt(比如试图让几个不同的 AI 角色在一个群里聊天&…...

别再死磕OFDMA了!用Python+PyTorch手把手复现NOMA的SIC接收机(附代码)

用PythonPyTorch实战NOMA的SIC接收机:从理论到代码实现在5G和后5G时代,非正交多址接入(NOMA)技术因其卓越的频谱效率而备受关注。与传统的正交多址(OFDMA)不同,NOMA允许用户在相同时频资源上叠加传输,通过功率域复用和先进的接收机…...

ARM Trace Buffer扩展与调试同步机制详解

1. ARM Trace Buffer扩展与调试状态同步机制解析在嵌入式系统和处理器架构设计中,调试与追踪技术是开发人员不可或缺的工具。ARM架构通过Trace Buffer Extension(TBE)提供了强大的指令级执行流追踪能力,其核心原理是通过专用硬件单…...