You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用ImageDataGenerator对读取的图片文件进行正确排序

这个问题是因为ImageDataGenerator默认采用字符串字典序对文件名排序,不会自动解析文件名中的数字做数值排序,所以会出现img(1)排在img(2)前面、但img(10)也排在img(2)前面的情况,你可以通过以下两种方案解决:

方案1:使用flow_from_dataframe手动控制排序(无需修改源文件,最灵活)

你可以先自行读取所有文件路径,按自然数值排序后再喂给生成器,全程可控不需要修改原文件名。
完整代码示例:

import os
import re
import pandas as pd
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# 自然排序辅助函数:拆分文件名中的数字和文本,按数值排序数字部分
def natural_sort_key(s):
    return [int(text) if text.isdigit() else text.lower() for text in re.split(r'(\d+)', s)]

# 配置参数
img_folder = "替换为你的图片文件夹路径"
img_size = (224, 224) # 替换为你需要的图片尺寸
batch_size = 32

# 读取所有图片文件并按自然序排序
img_list = sorted(
    [f for f in os.listdir(img_folder) if f.lower().endswith(('.jpg', '.jpeg', '.png'))],
    key=natural_sort_key
)

# 构造DataFrame供flow_from_dataframe使用
img_df = pd.DataFrame({
    "filename": img_list,
    "label": [0]*len(img_list) # 有监督学习场景替换为和排序后文件名对应的真实标签即可
})

# 初始化生成器并加载数据
datagen = ImageDataGenerator(rescale=1./255) # 替换为你需要的预处理规则
data_generator = datagen.flow_from_dataframe(
    dataframe=img_df,
    directory=img_folder,
    x_col="filename",
    y_col="label",
    target_size=img_size,
    batch_size=batch_size,
    class_mode="raw", # 无标签场景可改为"input",根据自身需求调整
    shuffle=False # 需保持排序必须设为False,需要打乱训练时再按需开启
)

方案2:批量补零重命名文件名(一劳永逸,后续无需修改加载逻辑)

如果允许修改源文件名,可以把文件名中的数字补零到相同位数,比如img(1).jpg改为img(001).jpg、img(10).jpg改为img(010).jpg,补零后默认的字典序就和数值序完全一致,直接用原生flow_from_directory也能按预期顺序加载。
批量重命名代码示例:

import os
import re

img_folder = "替换为你的图片文件夹路径"
digit_length = 3 # 按最大文件数调整,比如最多999张设为3,最多9999张设为4

for filename in os.listdir(img_folder):
    if not filename.lower().endswith(('.jpg', '.jpeg', '.png')):
        continue
    # 提取文件名中的数字
    match_res = re.search(r'img\((\d+)\)', filename)
    if not match_res:
        continue
    origin_num = match_res.group(1)
    # 补零构造新文件名
    new_num = origin_num.zfill(digit_length)
    suffix = os.path.splitext(filename)[1]
    new_filename = f"img({new_num}){suffix}"
    # 重命名
    os.rename(
        os.path.join(img_folder, filename),
        os.path.join(img_folder, new_filename)
    )

重命名完成后直接用原生flow_from_directory加载即可,无需额外修改参数。

内容的提问来源于stack exchange,提问作者Aomsup PANLIMA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 01:39:04