我正在尝试使用预训练的InceptionV3模型对food-101 dataset进行分类,其中包含101个类别的食物图像,每个类别1000个 . 我已经将这个数据集预处理成一个单独的hdf5文件(我认为这比在训练时加载图像相比是有益的)到目前为止,其中包含以下表格:
数据拆分是标准的70%列车,20%验证,10%测试,因此例如valid_img的大小为20200 * 299 * 299 * 3 . 标签是针对Keras的一个编码,因此valid_labels的大小为20200 * 101 .
This hdf5 file has a size of 27.1 GB ,所以它不适合我的记忆 . (有8 GB,虽然在运行Ubuntu时实际上只有4-5演出可用 . 而且我的GPU是带有2 GB VRAM的GTX 960,到目前为止,当我尝试启动时,它似乎有1.5 GB可用于python训练脚本) . 我正在使用Tensorflow后端 .
我的第一个想法是使用带有双嵌套for循环的 model.train_on_batch()
,如下所示:
#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页面上找到的一些示例之后, I still dont really get how should I implement a custom generator, which would read in batches of data from my hdf5 file. 有人可以为我提供一个很好的示例或指针吗?如何将自定义批处理生成器与图像扩充相结合?或者也许更容易实现 train_on_batch()
的某种手动验证和批量洗牌?如果是这样,我也可以使用一些指针 .
3 回答
如果我理解正确,您希望使用HDF5中的数据(不适合内存),同时在其上使用数据扩充 .
我和你的情况相同,我发现这些代码可能对一些修改有所帮助:
https://gist.github.com/wassname/74f02bc9134897e3fe4e60784f5aaa15
你想写一个函数,它从HDF5加载图像然后
yield
s(而不是return
s)它们作为一个numpy数组 . 下面是一个简单的示例,它使用OpenCV直接从给定目录中的.png / .jpg文件加载图像:显然你必须修改它才能从HDF5读取 .
编写完功能后,用法很简单:
再次修改以反映您正在从HDF5而不是目录中读取的事实 .
这是我用h5文件每个时代的随机数据的解决方案 . 指数表示火车或val指数列表 .