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

Colab调用flow_from_directory报listdir传参为BatchDataset错误求解

报错核心原因

代码混用了两套互不兼容的Keras数据加载API,同时存在多处参数配置错误:

  • ImageDataGenerator.flow_from_directory()的第一个入参必须是字符串格式的数据集本地路径,你传入的train_ds、val_ds是tf.keras.utils.image_dataset_from_directory()返回的BatchDataset类型的数据集对象,不是路径,底层调用os.listdir()读取路径时直接触发类型错误。
  • 两套数据加载逻辑不能拼接使用:要么全程用image_dataset_from_directory加载数据集,要么全程用ImageDataGenerator+flow_from_directory传入路径生成迭代器,不能把前者生成的数据集对象传给后者的接口。
  • 代码还存在其他会导致运行失败的逻辑错误:
    • 重复定义img_width、img_height,先赋值150又被覆盖为32,分辨率设置混乱
    • 模型输出层配置和损失、分类模式不匹配:最后一层用1个神经元+sigmoid激活是二分类配置,却搭配了多分类用的categorical_crossentropy损失和categorical分类模式
    • model.fit()传入了未定义的变量nb_train_samples、nb_validation_samples、epochs,且验证集参数名错误写成了val_ds,正确参数名是validation_data
可直接运行的修正代码

以下方案统一用更简洁、不易出错的image_dataset_from_directoryAPI,不需要手动统计样本数,修正了所有配置冲突,直接替换原代码即可:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Activation, Dropout, Flatten, Dense, Conv2D, MaxPooling2D, Rescaling
from tensorflow.keras.losses import sparse_categorical_crossentropy
from tensorflow.keras.optimizers import Adam
import matplotlib.pyplot as plt
import tensorflow as tf
import os

# -------------------------- 可根据实际需求调整的配置项 --------------------------
batch_size = 32
# 32*32分辨率过低容易丢失图像特征,统一用150*150
img_width, img_height, img_num_channels = 150, 150, 3
no_epochs = 30 
# 自动读取数据集下的分类文件夹数量,不需要手动硬编码
data_path = '/content/drive/MyDrive/Colab Notebooks/Training_Data'
no_classes = len([x for x in os.listdir(data_path) if os.path.isdir(os.path.join(data_path,x))])
# -----------------------------------------------------------------------------

# 拆分训练、验证集
train_ds = tf.keras.utils.image_dataset_from_directory(
  data_path,
  validation_split=0.2,
  subset="training",
  seed=123,
  image_size=(img_height, img_width),
  batch_size=batch_size)

val_ds = tf.keras.utils.image_dataset_from_directory(
  data_path,
  validation_split=0.2,
  subset="validation",
  seed=123,
  image_size=(img_height, img_width),
  batch_size=batch_size)

# 在线数据增强
data_augmentation = Sequential([
  tf.keras.layers.RandomFlip('horizontal'),
  tf.keras.layers.RandomRotation(0.2),
  tf.keras.layers.RandomZoom(0.2),
])

# 像素值归一化到0-1区间
rescale = Rescaling(1./255)

# 优化数据集加载速度
AUTOTUNE = tf.data.AUTOTUNE
train_ds = train_ds.map(lambda x,y: (rescale(data_augmentation(x, training=True)), y)).cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.map(lambda x,y: (rescale(x), y)).cache().prefetch(buffer_size=AUTOTUNE)

# 搭建CNN模型
input_shape = (img_width, img_height, img_num_channels)
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (3, 3)))   
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
# 输出层匹配分类数,多分类用softmax激活
model.add(Dense(no_classes))
model.add(Activation('softmax'))

# 编译模型,损失函数匹配整数格式标签(不需要手动转独热编码)
model.compile(loss=sparse_categorical_crossentropy,
              optimizer=Adam(learning_rate=1e-4),
              metrics=['accuracy'])

# 启动训练
history = model.fit(
    train_ds,
    validation_data=val_ds,
    epochs=no_epochs
)

# 绘制训练/验证的准确率、损失曲线
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(no_epochs)

plt.figure(figsize=(12,4))
plt.subplot(1,2,1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1,2,2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
注意事项
  • 如果你的数据集是二分类(只有2个分类文件夹),把模型最后输出部分改成model.add(Dense(1))、model.add(Activation('sigmoid')),损失函数替换为tf.keras.losses.BinaryCrossentropy()即可。
  • 训练前确认数据集目录结构符合要求:Training_Data文件夹下直接存放以分类名命名的子文件夹,每个子文件夹内存放对应类别的图片,不要嵌套多余层级。
  • 如果训练时触发显存不足报错,把batch_size调小到16或者8即可。
  • 初始学习率设为1e-4比Adam默认的1e-3更稳定,不容易出现训练不收敛、验证集精度震荡的问题。
  • 如果你更习惯用ImageDataGenerator的写法,需要删掉所有image_dataset_from_directory相关代码,直接把数据集路径字符串作为第一个参数传给flow_from_directory(),同时手动统计训练、验证集样本数给对应变量赋值,配置复杂度更高,优先使用上面给出的修正方案。

内容的提问来源于stack exchange,提问作者อิม อัฐวงศ์

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:01:10