我正在尝试使用预训练的InceptionV3模型对food-101数据集进行分类,该数据集包含101个类别的食物图像,每个类别1000个。到目前为止,我已经将该数据集预处理为单个hdf5文件(与培训时随身加载图像相比,这是有益的),其中包含以下表格:
数据拆分是标准的70%训练,20%验证,10%测试,因此例如valid_img的大小为20200 * 299 * 299 * 3。标签是对Keras进行单编码的,因此有效标签的大小为20200 * 101。
这个hdf5文件的大小为27.1 GB,因此不适合我的内存。(有8 GB,尽管在运行Ubuntu时实际上只能使用4-5个演出。而且我的GPU是带有2 GB VRAM的GTX 960,到目前为止,当我尝试启动时,它似乎有1.5 GB可用于python训练脚本)。我正在使用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, )
Run Code Online (Sandbox Code Playgroud)
我用这种方法的问题是,train_on_batch为验证或批处理改组提供了0支持,因此批处理在每个时期都不是相同的顺序。
因此,我着眼于model.fit_generator()哪个具有与相同的功能fit(),以及内置的功能,ImageDataGenerator您可以使用CPU来同时进行图像增强(旋转,水平翻转等),从而使您的模型成为更强大。我的问题是,如果我正确理解该ImageDataGenerator.flow(x,y)方法,则该方法需要同时获取所有样本和标签,但是我的训练/验证数据无法放入我的RAM中。
这是我认为自定义数据生成器出现的地方,但是在广泛浏览了我在Keras GitHub / Issues页面上可以找到的一些示例之后,我仍然没有真正知道如何实现自定义生成器,该生成器将分批阅读我的hdf5文件中的数据。有人可以给我提供一个很好的例子或指示吗?如何将自定义批处理生成器与图像增强功能结合在一起?或者,也许更容易实现某种手动验证和批量改组train_on_batch()?如果是这样,我也可以在其中使用一些指针。
Jes*_*lan -1
您想要编写一个函数,从 HDF5 加载图像,然后将它们作为 numpy 数组yield存储(而不是存储)。return这是一个简单的示例,它使用 OpenCV 直接从给定目录中的 .png/.jpg 文件加载图像:
def generate_data(directory, batch_size):
"""Replaces Keras' native ImageDataGenerator."""
i = 0
file_list = os.listdir(directory)
while True:
image_batch = []
for b in range(batch_size):
if i == len(file_list):
i = 0
random.shuffle(file_list)
sample = file_list[i]
i += 1
image = cv2.resize(cv2.imread(sample[0]), INPUT_SHAPE)
image_batch.append((image.astype(float) - 128) / 128)
yield np.array(image_batch)
Run Code Online (Sandbox Code Playgroud)
显然,您必须修改它才能从 HDF5 读取。
一旦你编写了你的函数,用法就很简单:
model.fit_generator(
generate_data('~/my_data', batch_size),
steps_per_epoch=len(os.listdir('~/my_data')) // batch_size)
Run Code Online (Sandbox Code Playgroud)
再次修改以反映您正在从 HDF5 而不是目录中读取的事实。
| 归档时间: |
|
| 查看次数: |
6441 次 |
| 最近记录: |