如何加载符合指定目录结构的RNN模型训练图像标注数据
RNN训练场景下多目录PNG图像+JSON标注加载方案
1. 第一步:先做样本精确配对,生成全局索引
不要上来就直接读文件,先把所有有效样本的路径对应关系理清楚,存缓存避免每次启动训练都重复扫盘:
- 按数据集编号遍历3个数据子集,对编号为i的数据集,分别扫描
dataset{i}_images下所有.png文件、dataset{i}_labels下所有.json文件,提取不带后缀的文件名作为样本唯一ID - 对每个数据集,取图片ID集合和标注ID集合的交集作为有效样本,把「图片绝对路径、对应JSON标注绝对路径、所属数据集编号」三条信息存在全局样本列表里
- 有图无标注、有标注无图的错配/缺失样本直接筛掉,记个日志就行,不用硬留。就用文件名精确匹配,别搞模糊匹配那套,错配的标签比缺样本危害大得多
- 把整理好的全局样本列表存成pickle或者csv缓存,下次训练直接读缓存,不用重复遍历目录
2. 第二步:单样本预处理,对齐RNN输入格式
RNN要求输入是序列格式,预处理的时候直接把数据转成模型能吃的张量,别留到训练循环里做拖速度:
- 图像读取:用PIL或者OpenCV加载PNG,统一转RGB格式,按模型要求做resize、像素值归一化。如果是视觉类RNN任务(比如OCR、手写识别、图像序列分类),把预处理后的图像按固定规则切分成序列:比如按行切分、拆成固定大小的patch展平特征,最终转成形状为
(seq_len, feature_dim)的输入张量 - 标注读取:加载对应JSON文件,按任务要求转成序列标签:如果是序列生成/序列标注任务,先构建固定词表,把标注内容转成词表对应的ID序列,设置全局统一的最大序列长度,短序列补pad token、长序列截断;如果是简单分类任务直接转成类别ID就行
- 额外生成序列有效长度掩码:标记序列里哪些位置是真实数据、哪些是补的pad,后面算RNN loss的时候要把pad部分屏蔽掉,避免无效值干扰梯度计算
3. 第三步:构建批量数据加载器
直接用框架自带的DataLoader实现就行,不用自己写批量加载逻辑:
- 自定义数据集类,初始化时传入之前缓存的全局样本列表,
__getitem__方法里按索引读取对应路径的图片和标注,跑上面的预处理逻辑,返回输入张量、标签张量、长度掩码三个值 - 拆分数据集:按8:1:1的比例把全局样本拆成训练、验证、测试集,拆分的时候做分层抽样,保证三个子集里都包含3个数据集的样本,避免分布偏移
- 配置加载参数:训练集开启随机打乱,根据显存大小设置batch size,开多进程预加载(num_workers设为CPU核心数的1/2到2/3就行,别开满容易卡),开pin_memory加速GPU数据传输;验证集和测试集不用打乱
4. 训练前校验,避免低级错误
正式开训前一定要做校验,省得白跑几个小时:
- 取第一个加载出来的batch,核对张量维度:输入要符合
(batch_size, seq_len, feature_dim)的RNN标准输入形状,标签和掩码维度匹配 - 随机抽10~20个样本,把图片可视化、打印对应标注,确认图片和标签没有错配
- 拿3~5个batch跑一次前向+反向传播,确认loss能正常计算、梯度能正常回传,没有维度不匹配的问题
内容的提问来源于stack exchange,提问作者Matthew Fernandez
相关产品推荐
相关产品推荐

