gpt4 book ai didi

python - Keras 自定义数据生成器,适用于无法放入内存的大型 hdf5 文件

转载 作者:行者123 更新时间:2023-12-02 04:34:58 25 4
gpt4 key购买 nike

我正在尝试使用预训练的 InceptionV3 模型对 food-101 dataset 进行分类,其中包含 101 个类别的食物图像,每个类别 1000 个。到目前为止,我已将此数据集预处理为单个 hdf5 文件(我认为这与训练时加载图像相比是有益的),其中包含以下表格:

Food-101 hdf5 file structure

数据分割是标准的 70% 训练、20% 验证、10% 测试,因此,例如 valid_img 的大小为 20200*299*299*3。标签是针对 Keras 进行单编码的,因此 valid_labels 的大小为 20200*101。

这个 hdf5 文件大小为 27.1 GB,因此它无法放入我的内存中。 (有 8 GB,尽管在运行 Ubuntu 时实际上可能只有 4-5 GB 可用。而且我的 GPU 是 GTX 960,带有 2 GB VRAM,到目前为止,当我尝试启动时,Python 看起来有 1.5 GB 可用训练脚本)。我正在使用 Tensorflow 后端。

我的第一个想法是使用 model.train_on_batch() 和双重嵌套 for 循环,如下所示:

#Loading InceptionV3, adding my fully connected layers, compiling model...    

dataset = h5py.File('/home/uzoltan/PycharmProjects/food-101/food-101_299x299.hdf5', 'r')
epoch = 50
for i in range(epoch):
for i in range(100): #1000 images can fit in the memory easily, this could probably be range(10) too
train_images = dataset["train_img"][i * 706:(i + 1) * 706, ...]
train_labels = dataset["train_labels"][i * 706:(i + 1) * 706, ...]
val_images = dataset["valid_img"][i * 202:(i + 1) * 202, ...]
val_labels = dataset["valid_labels"][i * 202:(i + 1) * 202, ...]
model.train_on_batch(x=train_images, y=train_labels, class_weight=None,
sample_weight=None, )

我对这种方法的问题是 train_on_batch 为验证或批量改组提供 0 支持,因此每个时期的批处理顺序不同。

因此,我寻找了 model.fit_generator() ,它具有提供与 fit() 相同的所有功能的良好特性,并且具有内置的 ImageDataGenerator 你可以与CPU同时进行图像增强(旋转、水平翻转等),从而使你的模型更加稳健。我的问题是,如果我理解正确的话,ImageDataGenerator.flow(x,y) 方法需要同时使用所有样本和标签,但我的训练/验证数据不适合我的 RAM。

这是我认为自定义数据生成器发挥作用的地方,但是在广泛查看了 Keras GitHub/Issues 页面上的一些示例之后,我仍然不知道应该如何实现自定义生成器,它会从我的 hdf5 文件中批量读取数据。 有人可以为我提供一个很好的示例或指针吗?如何将自定义批量生成器与图像增强结合起来?或者也许更容易为 train_on_batch() 实现某种手动验证和批量改组?如果是这样,我也可以在那里使用一些指针。

最佳答案

对于仍在寻找答案的人,我围绕 ImageDataGeneator 的 apply_transform 制作了以下“粗略包装器”方法。

from numpy.random import uniform, randint
from tensorflow.python.keras.preprocessing.image import ImageDataGenerator
import numpy as np

class CustomImagesGenerator:
def __init__(self, x, zoom_range, shear_range, rescale, horizontal_flip, batch_size):
self.x = x
self.zoom_range = zoom_range
self.shear_range = shear_range
self.rescale = rescale
self.horizontal_flip = horizontal_flip
self.batch_size = batch_size
self.__img_gen = ImageDataGenerator()
self.__batch_index = 0

def __len__(self):
# steps_per_epoch, if unspecified, will use the len(generator) as a number of steps.
# hence this
return np.floor(self.x.shape[0]/self.batch_size)

def next(self):
return self.__next__()

def __next__(self):
start = self.__batch_index*self.batch_size
stop = start + self.batch_size
self.__batch_index += 1
if stop > len(self.x):
raise StopIteration
transformed = np.array(self.x[start:stop]) # loads from hdf5
for i in range(len(transformed)):
zoom = uniform(self.zoom_range[0], self.zoom_range[1])
transformations = {
'zx': zoom,
'zy': zoom,
'shear': uniform(-self.shear_range, self.shear_range),
'flip_horizontal': self.horizontal_flip and bool(randint(0,2))
}
transformed[i] = self.__img_gen.apply_transform(transformed[i], transformations)
return transformed * self.rescale

可以这样调用:

import h5py
f = h5py.File("my_heavy_dataset_file.hdf5", 'r')
images = f['mydatasets/images']

my_gen = CustomImagesGenerator(
images,
zoom_range=[0.8, 1],
shear_range=6,
rescale=1./255,
horizontal_flip=True,
batch_size=64
)

model.fit_generator(my_gen)

关于python - Keras 自定义数据生成器,适用于无法放入内存的大型 hdf5 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47059698/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com