【深度学习实战】从零构建数据集标签:手把手生成训练与验证清单
1. 为什么需要训练清单文件
当你从GitHub克隆一个深度学习项目准备复现时,第一个拦路虎往往就是数据集处理。我见过太多新手卡在这一步:明明下载了数据集,却不知道如何让模型正确读取。这就像买了一堆食材却不知道菜谱,空有数据却无法训练。
train.txt和val.txt这两个看似简单的文本文件,实际上是模型训练的"导航地图"。它们记录了所有训练集和验证集图片的路径信息,让模型知道去哪里找数据。没有这两个文件,就像让出租车司机去接人却不给地址一样荒谬。
我处理过的服装分类数据集就是个典型例子。原始数据按照类别存放在不同文件夹里:
data/ ├── train/ │ ├── downjacket/ │ ├── flareskirt/ │ └── ... └── val/ ├── downjacket/ └── ...这种结构虽然直观,但PyTorch等框架无法直接识别。手动创建清单文件又太耗时,特别是当你有4000张图片时。这就是为什么我们需要自动化脚本——它能把几小时的手工活变成几秒钟的自动处理。
2. 数据集目录结构设计
好的目录结构是成功的一半。经过多个项目实践,我总结出一个黄金法则:保持一致性、可扩展性和可移植性。下面是我推荐的目录布局:
project_root/ ├── data/ │ ├── myself/ # 自定义数据集 │ │ ├── train/ # 训练集 │ │ │ ├── class1/ # 类别文件夹 │ │ │ └── class2/ │ │ └── val/ # 验证集 │ │ ├── class1/ │ │ └── class2/ ├── examples/ │ └── myself/ │ ├── create_filelist.sh # 生成脚本 │ ├── train.txt # 输出文件 │ └── val.txt关键细节:
- 使用全英文路径,避免中文和空格(比如用
downjacket而不是"羽绒服") - 图片命名建议采用
类别_序号.后缀格式(如downjacket_001.jpg) - 验证集比例通常占20%-30%,我的服装数据集就是按这个比例划分的
注意:在Linux环境下,路径区分大小写。曾经有个项目因为把
Tshirt写成tshirt导致脚本报错,排查了整整两小时!
3. Shell脚本编写实战
现在来到核心部分——编写自动化脚本。别被"Shell脚本"吓到,其实它就像一份烹饪步骤说明。下面是我优化后的脚本,比原始版本更健壮:
#!/bin/bash # 配置路径(根据实际修改) DATA_DIR="../data/myself" # 数据集路径 OUTPUT_DIR="." # 输出目录 echo "正在生成train.txt..." rm -f $OUTPUT_DIR/train.txt # 清理旧文件 # 遍历所有训练集类别 for class_dir in $DATA_DIR/train/*; do if [ -d "$class_dir" ]; then find "$class_dir" -name "*.jpg" -o -name "*.jpeg" -o -name "*.png" >> $OUTPUT_DIR/train.txt fi done echo "正在生成val.txt..." rm -f $OUTPUT_DIR/val.txt # 遍历所有验证集类别 for class_dir in $DATA_DIR/val/*; do if [ -d "$class_dir" ]; then find "$class_dir" -name "*.jpg" -o -name "*.jpeg" -o -name "*.png" >> $OUTPUT_DIR/val.txt fi done echo "文件列表生成完成!"改进亮点:
- 使用循环语句替代硬编码路径,适应任意类别数量
- 支持多种图片格式(jpg/jpeg/png)
- 相对路径设计,增强可移植性
- 添加执行状态提示,更友好
常见问题处理:
- 如果遇到
Permission denied错误,先给脚本添加执行权限:chmod +x create_filelist.sh - 路径中包含空格时,要用引号包裹变量(如
"$class_dir")
4. 高级技巧与错误排查
在实际项目中,我积累了一些血泪经验,能帮你少走弯路:
路径处理陷阱:
- 绝对路径 vs 相对路径:建议在脚本内统一转换为绝对路径
REAL_PATH=$(realpath "$class_dir") echo "$REAL_PATH" >> train.txt - Windows和Linux路径差异:如果在Windows开发,注意反斜杠转换
sed -i 's/\\/\//g' train.txt # 将\替换为/
数据校验技巧: 生成文件后,建议用这些命令检查:
wc -l train.txt # 统计行数(图片总数) head -n 5 train.txt # 查看前5行路径是否正确 grep " " train.txt # 检查是否包含空格路径性能优化: 当处理超大规模数据集(10万+图片)时:
- 使用
parallel命令加速:parallel -j 8 find {} -name "*.jpg" ::: $DATA_DIR/train/* >> train.txt - 添加进度显示:
find "$class_dir" -name "*.jpg" | pv -l >> train.txt
一个真实案例:有次处理50万张商品图片时,原始脚本跑了20分钟。加入并行处理后,时间缩短到3分钟——这就是自动化脚本的价值!
5. 与深度学习框架集成
生成的文件列表最终要用于模型训练。以PyTorch为例,通常有两种使用方式:
方式一:自定义Dataset类
from torch.utils.data import Dataset class ImageDataset(Dataset): def __init__(self, file_list): self.file_list = [] with open(file_list) as f: for line in f: self.file_list.append(line.strip()) def __getitem__(self, idx): img_path = self.file_list[idx] # 添加图像加载和预处理代码 return image, label方式二:使用框架内置工具如PyTorch的ImageFolder,但需要调整目录结构:
data/ ├── class1/ │ ├── img1.jpg │ └── img2.jpg └── class2/ ├── img3.jpg └── img4.jpg重要提示:如果使用绝对路径,当把项目迁移到其他机器时,需要更新路径。建议在训练代码中添加路径前缀配置项。
我曾经遇到一个坑:团队协作时,同事的路径是/home/user/data,而我的是/Users/name/data,导致脚本报错。后来我们统一改用相对路径,问题迎刃而解。
6. 扩展应用场景
这个技术不仅限于图像分类,经过简单改造可以用于:
- 多标签分类:在每行路径后添加标签
/path/to/img1.jpg 0,1,5 /path/to/img2.jpg 3,7 - 目标检测:关联标注文件路径
find "$class_dir" -name "*.jpg" | while read img; do echo "$img ${img%.*}.xml" >> train.txt done - 跨模态数据:同时处理图像和文本
find images/ -name "*.jpg" | while read img; do text="${img/images/texts}.txt" echo "$img $text" >> multimodal.txt done
在智能硬件项目中,我还用类似方法处理过传感器时序数据。原理相通,只是文件扩展名从.jpg变成了.csv。
