TensorFlow flow_from_dataframe()报invalid filenames错误解决方案
问题背景
在Windows系统下使用Jupyter-lab,基于TensorFlow、Keras在经典Cats-Dogs猫狗数据集上练习目标识别任务,参照网络教程编写代码时,触发图片文件名相关警告。
训练文件夹路径为 C:\Users***\Documents\PetImages\Cats_Dogs,文件夹内所有jpg文件均已重命名为一位整数顺序编号,文件夹结构参考:
警告触发位置为flow_from_dataframe的x_col参数,多轮排查未定位根因。
报错信息
C:\Users\***\anaconda3\lib\site-packages\keras\preprocessing\image.py:989: UserWarning: Found 34876 invalid image filename(s) in x_col="filename". These filename(s) will be ignored. warnings.warn('Found {} invalid image filename(s) in x_col="{}". '.
核心代码
代码中IDG指代ImageDataGenerator库,数据加载核心逻辑如下:
train_generator = train_datagen.flow_from_dataframe(train_df, "C:/Users/Edo/Documents/PetImages/Cats_Dogs",x_col='filename',y_col='category', target_size=Image_Size, class_mode='categorical', batch_size=batch_size) validation_datagen = IDG(rescale=1./255) validation_generator = validation_datagen.flow_from_dataframe( validate_df, "C:/Users/***/Documents/PetImages/Cats_Dogs", x_col='filename', y_col='category', target_size=Image_Size, class_mode='categorical', batch_size=batch_size )
排查与解决方案
该警告的核心触发逻辑是:flow_from_dataframe会读取传入DataFrame的x_col列存储的文件名,和传入的目录路径拼接后查找本地文件,所有拼接后路径不存在、文件无法被识别为有效图片的条目,都会被判定为无效文件名并忽略。可按以下步骤逐一排查修复:
- 核对DataFrame存储文件名与实际文件名是否匹配
绝大多数这类报错都是重命名文件后,没有重新遍历文件夹生成新的训练/验证DataFrame,DataFrame里存储的还是原数据集的旧文件名(比如cat.0.jpg、dog.1.jpg),和目录里现有的一位数编号文件名完全不匹配,直接导致上万条文件查找失败。
在Jupyter中运行以下代码,对比两边文件名样例即可快速确认问题:# 打印DataFrame中存储的前10个文件名 print("DF存储文件名:", train_df['filename'].head(10).values) # 打印目标文件夹下实际存在的jpg文件名 import os img_dir = "C:/Users/Edo/Documents/PetImages/Cats_Dogs" actual_jpgs = [f for f in os.listdir(img_dir) if f.lower().endswith('.jpg')] print("文件夹实际文件名:", actual_jpgs[:10]) - 检查Windows文件扩展名隐藏导致的命名错误
Windows系统默认隐藏已知文件类型的扩展名,重命名时如果没有开启扩展名显示,很容易出现以为文件命名为1.jpg、实际文件全名为1.jpg.jpg的情况,导致路径拼接后找不到文件。可打开资源管理器的「查看」选项卡,勾选「文件扩展名」,确认所有图片后缀正确,无重复后缀问题。 - 重新生成过滤无效项的DataFrame
直接遍历目标文件夹生成DataFrame,自动过滤损坏图片、系统隐藏文件、临时文件,从根源避免文件名不匹配问题:import os import pandas as pd from PIL import Image from sklearn.model_selection import train_test_split img_dir = "C:/Users/Edo/Documents/PetImages/Cats_Dogs" valid_files = [] labels = [] for f in os.listdir(img_dir): # 仅处理jpg格式文件 if not f.lower().endswith('.jpg'): continue file_path = os.path.join(img_dir, f) # 校验图片可正常读取,跳过损坏文件 try: img = Image.open(file_path) img.verify() valid_files.append(f) # 按自己的标签规则替换映射逻辑,示例为文件名首字符1对应猫、0对应狗 labels.append('cat' if f.startswith('1') else 'dog') except Exception as e: print(f"跳过无效文件:{f}") # 生成全量数据集并拆分训练、验证集 full_df = pd.DataFrame({'filename': valid_files, 'category': labels}) train_df, validate_df = train_test_split(full_df, test_size=0.2, random_state=42) train_df = train_df.reset_index(drop=True) validate_df = validate_df.reset_index(drop=True) - 统一路径写法
代码中所有路径统一使用正斜杠书写,避免Windows反斜杠带来的转义字符识别问题。
内容的提问来源于stack exchange,提问作者EDOARDO ROSSO
相关产品推荐
相关产品推荐

