
简介面向图像分类与计算机视觉研究者提供一套基于 Python 3 的 ImageNet 子集自助下载方案。核心脚本可指定类别数量和每类图片张数自动从 ImageNet 图像 URL 中随机筛选并抓取样本用于快速搭建训练集、验证集或进行小规模实验尤其适合模型预训练前的数据检查、类别均衡测试以及教学演示。压缩包包含 7 个文件从类型上看既有可执行下载脚本也有记录类别的文本清单、映射类别编号的 JSON 文件以及 Markdown 格式的详细使用说明整体仅 1.55MB轻量且便于携带。附带 CSV 格式的 URL 状态统计表可辅助判断当前链接可用比例减少下载失败README 中还说明了工具的编写思路并分析 ImageNet 图片链接现状。已有 1000 人学习下载适合有一定 Python 基础的数据科学学习者和开发者能够节省手工筛选图片的时间快速获得可用的自定义数据集。 做深度学习视觉项目的人几乎都绕不开 ImageNet。但很多人对它是又爱又恨——想用硬盘空间和下载时长不答应不用又总觉得做分类实验少了点什么。ImageNet-Datasets-Downloader 这个开源小工具解决的就是这个扎心问题按需从 ImageNet 拉取指定类别的图片做一个完全自定义规模的数据集。我最初拿到这个工具是在做一个小样本分类实验只需要 5 个类、每类几百张图如果去拖全量数据不但要准备几百 GB 空间还要忍受漫长的下载和解压时间。而这个工具直接在命令行里就搞定了适合迁移学习微调、少样本学习、模型快速验证这类场景也适合刚入门想动手跑通一套训练流程的同学。1. 为什么还需要一个 ImageNet 下载器1.1 全量数据集的天坑ImageNet 全量数据集体积惊人ILSVRC2012 的压缩包就有 100 多 GB解压之后训练集加验证集接近 150 GB。就算你的硬盘装得下下载过程也极其折磨——很多人挂在半夜下载第二天醒来发现某个分卷校验失败只能重来。更麻烦的是官方下载流程要先注册、同意条款再通过校园邮箱或机构权限申请个人想直接拿链接并不轻松。全量数据对大多数场景其实是浪费的。你只是想测试一个新网络结构或者做一次迁移学习实验根本用不到一千个类、上百万张图。每张图都要经过解码、缩放、增强数据加载反而成了训练瓶颈。这时如果能只下载目标类别的图片整个过程就从“重型工程”变成了“轻量准备”。1.2 按需抽取的真实场景我遇到过几种情况特别适合用这类工具做二分类或小规模多分类基线实验比如动物和交通工具的区分验证一个新提出的数据增强策略先用少量真实图片观察效果复现论文时需要某个类子集的统计分布教学演示时不想让学生一上来就面对几百 GB 的数据集。这类场景的共同点是类别可控、数据量可控、样本质量和格式尽量贴近 ImageNet。ImageNet-Datasets-Downloader 的思路正好对路——它通过指定 ImageNet 的 WordNet IDwnid来决定下载哪些类再用参数控制每个类下载多少张图。2. 先搞懂工具背后的数据组织WordNet ID 与 ImageNet 对齐2.1 Synset 是什么ImageNet 的类别不是简单的字符串标签而是 WordNet 中的 synset同义词集比如“狗”这个类对应一个 synset它包含 dog、domestic dog、Canis familiaris 等多个同义表达。每个 synset 都有一个唯一的 ID 作为标识这就是我们常说的 wnid形如 n02084071。ImageNet 的很多类别标签都直接沿用这个 wnid而不是重新设计一套编码体系。这个设计带来一个好处只要你会查 WordNet就能在 ImageNet 里准确地找到所有下属类别尤其是父子层级关系。比如狗是一个父类 synset下面还细分了猎犬、牧羊犬、伴侣犬等子类每个子类也都有各自的 wnid。下载时想要“全部狗类”还是“某一种狗”取决于你选择哪一个层级的 synset。2.2 如何快速定位你要的 wnid目前最直接的方式是访问 ImageNet 官网的同步词表单页按其类目浏览或用关键词搜索页面会列出对应的 wnid。如果你想用程序化方式可以访问 ImageNet 的 API 接口比如用 synset 的 ID 获取同义词集信息和图片 URL 列表。另一个比较省事的办法是直接下载 ImageNet 官方提供的类别映射文件里面包含了从 wnid 到类别描述文本的完整对应关系。我自己常用的是先看 ILSVRC2012 的类别文件因为它和目前多数视觉模型的输出类别完全一致。比如文件里第一行是 n01440764 tench第二行是 n01443537 goldfish。你只需要打开这个文本文件按关键词搜一下就能拿到目标类别的 wnid。这里要特别提醒ImageNet 的类别名和日常自然语言并不完全一致比如“猫”在 WordNet 里可能对应多个 synset比如 domestic cat 是 n02121808而 big cat 是另一个 ID。如果你想找所有猫科图片建议把父类 wnid 下的子类全部展开再合并下载。3. 环境准备与工具安装3.1 依赖与安装这个工具本质上是一段 Python 脚本核心依赖是 requests 和 tqdm有版本还用到 click 来解析命令行参数。我用的版本是基于 Python 3.7 以上环境跑的建议直接使用虚拟环境安装避免污染系统 Python。git clone https://github.com/madhav-madhusoodanan/ImageNet-Datasets-Downloader.git cd ImageNet-Datasets-Downloader pip install -r requirements.txt如果你不想 clone也可以直接下载仓库里的核心脚本再把依赖装上。需要注意这个项目并非官方维护不同分支的命令行参数可能略有差异。我最初用的时候仓库主分支的入口文件是Imagenet_downloader.py后来看到一些 fork 版本改成了main.py。所以动手前先看一眼 README确认你本地这个版本的入口文件叫什么。3.2 命令行参数说明大多数版本的参数都围绕这几个核心项参数作用示例--classes或--wnids指定要下载的 WordNet ID 列表多个之间用空格分隔n02084071 n02121808--images或--num_images每个类别需要下载的图片数量200以我本地的版本为例实际调用格式如下python Imagenet_downloader.py \ --classes n02084071 n02121808 \ --images 200执行后工具会在当前目录生成以 wnid 命名的文件夹图片依次写入其中。有些 fork 版本还会支持输出目录指定、并发线程数、超时时间等扩展参数可以根据需要自行查看。4. 实操从零下载自定义 ImageNet 子集4.1 获取类别清单并拼出下载命令假设我想做一个包含狗和猫的二分类数据集每类 200 张图片。第一步拿到两个类的 wnid狗是 n02084071家猫是 n02121808。然后执行上面的命令。这里建议把命令写成一个 shell 脚本方便后续调整类别或数量时复用。mkdir -p my_imagenet_subset cd my_imagenet_subset python ../Imagenet_downloader.py \ --classes n02084071 n02121808 \ --images 200下载过程会显示进度条和当前正在处理的文件。因为是逐批请求图片 URL速度不会特别快200 张图每类通常需要几分钟到十几分钟取决于网络状况和网站响应速度。4.2 下载过程与目录结构这个下载器的工作逻辑并不复杂先根据 wnid 向 ImageNet 的公开接口请求该 synset 下的图片 URL 列表然后逐一下载。实际效果是每个 wnid 对应一个文件夹里面是 JPEG 图片文件文件名一般带有原始 ID 信息结构大致如下my_imagenet_subset/ ├── n02084071/ │ ├── n02084071_1.JPEG │ ├── n02084071_2.JPEG │ └── ... └── n02121808/ ├── n02121808_1.JPEG └── ...这种按 wnid 命名的目录结构本身已经满足 PyTorch 的ImageFolder格式要求因为ImageFolder会直接把每个子目录名当作类别标签。不过 wnid 可读性太差训练时还需要一份映射表把 n02084071 映射成狗把 n02121808 映射成猫。4.3 校验与清洗下载完成不等于可以直接进训练管线。ImageNet 的数据来自互联网不少图片链接可能已经失效或内容发生了变化。常见问题包括下载到一半图片损坏无法解码某些图片实际是缩略图或空白图个别图片被原站点反爬拦截返回了错误页面。因此我每次下载完都会跑一遍简单校验用 OpenCV 或 PIL 打开所有文件无法解码的直接删掉。from PIL import Image import os for root, _, files in os.walk(my_imagenet_subset): for f in files: path os.path.join(root, f) try: img Image.open(path) img.verify() except Exception: os.remove(path) print(removed, path)不要小看这一步我曾有一批数据训练到一半才发现有几十张损坏图片导致 Batch 训练时随机报错排查了很久。先清洗后面能省很多事。5. 进阶把下载内容变成可直接训练的数据集5.1 按 ImageFolder 标准整理文件很多视觉训练的代码默认使用torchvision.datasets.ImageFolder它要求目录按类别名/图片文件组织。现在我们的目录是按 wnid 组织的类别名就是 wnid这没问题。但如果想让训练代码直接显示可读标签最好把文件夹重命名成英文标签比如dog、cat。mv n02084071 dog mv n02121808 cat这里要注意重命名会让后续手工核对 wnid 变得麻烦所以一定要把映射关系记录好。我习惯在数据集根目录放一个labels.txt每行是“文件夹名 可读描述”方便随时查。5.2 标签映射与 WordNet 对齐讲到这里就不得不提“WordNet 和 ImageNet 对齐”这个热门问题。很多模型是以 ImageNet 的 1000 类为基准训练的比如 ResNet、EfficientNet 在torchvision里的预训练权重输出类别按 ILSVRC2012 的 1 到 1000 索引排列。当你自定义数据集时如果希望使用这些预训练权重做迁移学习就需要搞清楚自己选出来的 wnid 对应模型输出索引的哪一位。查索引的方式很简单官方的imagenet_class_index.json已经给出索引到 wnid 的映射。你可以直接加载这份 JSON 文件反查出某个 wnid 对应的输出索引是多少。这样在替换模型最后的全连接层时就不会搞混类别顺序。import json with open(imagenet_class_index.json) as f: class_index json.load(f) wnid_to_idx {v[0]: int(k) for k, v in class_index.items()} print(wnid_to_idx[n02084071]) # 输出狗类在预训练模型中的索引这个操作在处理一些“从 ImageNet 子集初始化并微调”的论文复现时尤其重要标签对齐错一位整个实验结论都可能反转。5.3 训练集/验证集划分下载器本身只负责把图片拉到本地并不提供 train/val 切分。自己写脚本划分很直接按比例随机抽样把文件移动或软链到train和val目录下。我更推荐用软链而不是复制因为自定义数据集一般不大复制也能接受但软链更省空间适合反复调整划分比例。mkdir -p dataset/train/dog dataset/val/dog cd dataset find ../dog -type f | sort | head -n 160 | xargs -I {} ln -s {} train/dog/ find ../cat -type f | sort | head -n 160 | xargs -I {} ln -s {} train/cat/简单做的话用 Python 脚本写个随机切分更灵活还可以顺便把清洗步骤合并进去。6. 常见问题与避坑记录6.1 下载到一半不动了这个工具在请求图片时如果网络状态不佳可能会卡在某个文件上。大多数情况下是因为目标站点的响应超时或者连接被断开。我的处理办法是不要死等直接中断进程然后删除对应目录里不完整的文件重跑。很多版本本身没有断点续传功能所以最稳妥的做法是设置一个合理的线程间隔或加入超时参数。如果你用的版本支持--timeout参数建议设置成 10 到 20 秒避免因为一两张图拖死整个任务。6.2 下载数量和设置不一致这个基本属于预期内。ImageNet 原始图片 URL 中有一部分已经失效下载器尽力去请求也可能返回 404尤其是年份比较久的 synset。这种情况下实际下载的图片数会小于你设定的数量。我一般会直接把期望数量上调 20% 到 30%下载完成后清洗删掉坏图最后数量就差不多了。6.3 图片打不开或内容不对这个问题主要来自原始站点的反爬或跳转机制有时候保存下来的文件内容其实是 HTML 而不是 JPEG。用文件头检查可以快速发现file n02084071/*.JPEG | grep -v JPEG image | head如果发现大量非图片文件说明下载环境被目标网站识别了可以考虑更换下载时间段或调整请求间隔尽量模拟正常访问。数据量要求不高的实验也可以改为使用官方提供的image-net.org的图片下载接口按 synset 拉取。6.4 想下载的类在 ImageNet 里没有ImageNet 的类别集合是固定的它覆盖 WordNet 中约 2 万多个名词 synset但日常概念并不一定都在里面。想确认某个类别是否存在最直接的方式是去 ImageNet 官网搜索界面输入关键词如果返回为空那就只能换用其他数据集或者自己收集图片并清洗。实在想用 ImageNet 的预训练模型权重也可以选择离目标概念最近的 synset比如“无人机”不好找就用“飞机”相关的 synset 做近似替代。7. 一些体会做视觉实验越久越觉得“数据准备”这件事不应该成为启动项目的阻碍。以前我喜欢一次性下载全套数据觉得“都拿下来总没错”结果每次都被存储和预处理拖住手脚。后来改成按需抽取反而让实验迭代快了不少。ImageNet-Datasets-Downloader 虽然体量不大代码也不算复杂但它把一个很长链条中的关键环节切得足够短让任何普通开发者都能在几分钟内拿到一份可用的自定义 ImageNet 子集。如果你只是跑个实验验证想法完全不必去啃全量数据。最后再分享一个小技巧用这类工具生成的数据集最好把 wnid 映射和下载日期记录在同一个说明文件里。因为 ImageNet 的图片内容会随时间变化同一 wnid 在不同时间下载可能得到不同的图片集合。留一份 meta 信息实验出问题时你才知道数据到底是不是变化的那个变量。数据集小有小的好处但前提是每一步都干净、可追溯。本文还有配套的精品资源点击获取