为何Keras DictionaryIterator调用next()返回全部图像而非单张?
Keras ImageDataGenerator 生成器的 next() 行为解释
问题描述
使用Keras的ImageDataGenerator与flow_from_directory后,对以下代码存在疑问:
sample_training_images, _ = next(train_data_gen) plotImages(sample_training_images[:5])
原本以为next()只会获取单个迭代项,但此处它返回了批量内容,plotImages可以直接绘制前5项。补充信息:
- 下划线
_用于丢弃标签数据 train_data_gen.target_size设置为(150,150)sample_training_images.shape结果为(128,150,150,3)plotImages函数实现如下:
def plotImages(images_arr, probabilities = False): fig, axes = plt.subplots(len(images_arr), 1, figsize=(5,len(images_arr) * 3)) if probabilities is False: for img, ax in zip( images_arr, axes): ax.imshow(img) ax.axis('off') else: for img, probability, ax in zip( images_arr, probabilities, axes): ax.imshow(img) ax.axis('off') if probability > 0.5: ax.set_title("%.2f" % (probability*100) + "% dog") else: ax.set_title("%.2f" % ((1-probability)*100) + "% cat") plt.show()
原因解释
这是Keras数据流生成器本来的工作逻辑:
- 用
flow_from_directory创建的生成器,每次调用next()时,返回的是一整个批量(batch)的数据,不是单个样本。 - 批量的大小由创建生成器时设置的
batch_size参数决定(你这里的batch_size是128,所以sample_training_images的第一个维度是128,对应128张图片)。 - 生成器的核心作用就是分批加载数据,避免一次性把所有数据塞进内存,所以它的迭代单位就是“批次”,而非单个样本。
你之前的误解是把生成器的迭代项当成了单个样本,但在Keras的数据流生成器里,每个迭代项就是一个批次:
sample_training_images是形状为(batch_size, height, width, channels)的数组,其中sample_training_images[i]才是单张图片。- 所以
sample_training_images[:5]能提取这个批次里的前5张图,刚好可以被plotImages函数处理(函数会遍历传入的图片数组,逐个绘制)。
内容的提问来源于stack exchange,提问作者טל להט
相关产品推荐
相关产品推荐

