【发布时间】:2019-01-15 19:50:29
【问题描述】:
我正在尝试使用 Inception V3 模型进行图像分类。来自 Keras 的 ImageDataGenerator 是否会创建添加到我的数据集的新图像?如果我有 1000 张图像,使用此功能是否会加倍到 2000 张用于训练的图像?有没有办法知道创建了多少图像并输入到模型中?
【问题讨论】:
标签: python tensorflow machine-learning keras computer-vision
我正在尝试使用 Inception V3 模型进行图像分类。来自 Keras 的 ImageDataGenerator 是否会创建添加到我的数据集的新图像?如果我有 1000 张图像,使用此功能是否会加倍到 2000 张用于训练的图像?有没有办法知道创建了多少图像并输入到模型中?
【问题讨论】:
标签: python tensorflow machine-learning keras computer-vision
简答: 1) 所有原始图像都只是经过变换(即旋转、缩放等)每个 epoch 然后用于训练,以及 2) [因此] 每个 epoch 中的图像数量等于您拥有的原始图像数量。
长答案:在每个时期,ImageDataGenerator 对您拥有的图像进行转换,并使用转换后的图像进行训练。这组转换包括旋转、缩放等。通过这样做,您以某种方式创建了新数据(即也称为数据增强),但显然生成的图像与原始图像并没有完全不同。这样,学习模型可能会更加稳健和准确,因为它是针对同一图像的不同变体进行训练的。
您需要将fit 方法的steps_per_epoch 参数设置为n_samples / batch_size,其中n_samples 是您拥有的训练数据总数(即在您的情况下为1000)。这样在每个 epoch 中,每个训练样本只增加一次,因此每个 epoch 将生成 1000 个变换图像。
此外,我认为在这种情况下有必要澄清“增强”的含义:基本上,当我们使用ImageDataGenerator 并启用其增强功能时,我们正在增强图像。但是这里的“增强”这个词并不是说,如果我们有 100 个原始训练图像,我们在增强之后每个 epoch 最终有 1000 个图像(即每个 epoch 的训练图像数量不会增加) .相反,这意味着我们在每个 epoch 中对每个图像使用不同的变换;因此,如果我们训练我们的模型,比如 5 个 epoch,我们在训练中使用了每个原始图像的 5 个不同版本(或在整个训练中使用 100 * 5 = 500 个不同的图像,而不是在训练中只使用 100 个原始图像)整个训练)。换句话说,独特图像的总数在整个训练中从头到尾都在增加,而不是在每个 epoch 中增加。
【讨论】:
steps_per_epoch 设置为n_samples / batch_size 以外的任何值都没有意义。如果你这样做step_per_epoch = 2*(n_samples / batch_size),那么每个纪元实际上将是正常情况的两个纪元。
ImageDataGenerator 并启用其增强功能时,我们正在增强图像。但这里的“增强”一词并不意味着,如果我们有 100 个原始训练图像,我们最终会有 1000 个图像每个时期。相反,这意味着我们在每个 epoch 中对每个图像使用不同的变换;因此,如果我们训练我们的模型,比如 5 个 epoch,我们在训练中使用了每个原始图像的 5 个不同版本(或在整个训练中使用 100 * 5 = 500 个不同的图像,而不是在训练中只使用 100 个原始图像)整个培训)。
steps_per_epoch 设置为比实际批次数更高的数字,以便数字产生的批次增加。虽然,我没有看到这种做法很普遍,对我来说没有意义。
这是我试图回答的问题,因为我也有这个问题。
ImageDataGenerator 不会将新图像添加到您的数据集中,因为它不会使您的时代变大。相反,在每个 epoch 中,它将提供稍微改变的图像(取决于您的配置)。无论您有多少个 epoch,它都会始终生成新图像。
因此,在每个 epoch 中,模型都会在不同的图像上进行训练,但不会相差太大。这应该可以防止过度拟合,并在某种程度上模拟在线学习。
所有这些更改都发生在内存中,但如果您想查看这些图像,您可以将它们保存到光盘中,检查它们,查看其中生成了多少,并了解 ImageDataGenerator 的工作原理。为此,将save_to_dir=/tmp/img-data-gen-outputs 传递给函数flow_from_directory。见docs。
【讨论】:
正如官方写的hereImageDataGenerator是一个带有实时数据增强的张量图像数据的批量生成器。数据将被循环(分批)。这意味着将在运行中随机对一批图像应用转换。例如:
train_datagen = ImageDataGenerator(
rescale=1./255, #scale images from integers 0-255 to floats 0-1.
shear_range=0.2,
zoom_range=0.2, # zoom in or out in images
horizontal_flip=True) #horizontal flip of images
在每一个新的时期,都会应用新的随机变换,这样我们每次都会使用一组不同的图像进行训练。获取更多数据并不总是可以实现或可能的,使用ImageDataGenerator 这样会很有帮助。
【讨论】:
y_labels 的列表,flow() 将引发错误。如何实现?
这完全取决于您运行了多少个 epoch,正如 @today 所回答的那样,使用生成器拟合模型将使生成器提供所需数量的图像,具体取决于 steps_per_epoch。
为了让事情更容易理解,将 20 张图像放入两个文件夹(模拟分类数据),从父文件夹创建一个生成器并运行一个简单的 for 循环
count = 0
for image, label in my_test_generator:
count += 1
print(count)
首先你应该确认你看到了消息Found 20 images belonging to 2 classes.,并且循环本身不会在20次迭代后停止,但它会不断增加和无休止地打印(我把我的设置为10k并手动停止了它)。生成器将根据请求提供尽可能多的图像,无论它们是否被增强。
【讨论】:
还要注意:这些增强图像不存储在内存中,它们是在训练时动态生成的,在训练后丢失。您无法再次阅读那些增强的图像。
不存储这些图像是个好主意,因为我们很快就会耗尽内存来存储大量图像
【讨论】:
让我试着通过一个例子以最简单的方式告诉你。
例如:
ImageDataGenerator 应用于具有batch_size = 25 的数据集
steps_per_epoch=total_samples/batch_size
steps_per_epoch 将等于 20
ImageDataGenerator 的说明随机转换)【讨论】:
ImageDataGenerator 类确保模型接收新的 每个时期的图像变化。但它只返回 转换后的图像,不会将其添加到原始语料库中 图片。如果确实如此,那么模型将看到 原始图像多次,这肯定会过度拟合我们的 型号。
【讨论】: