我正在对300K图像的数据集进行多类图像分类。到目前为止,我拍摄了一个约7k图像的小型数据集,但是代码返回内存错误,或者我的笔记本死了。下面的代码将所有图像立即转换为numpy数组,这将在执行最后一行代码时导致我的内存出现问题。 train.csv包含图像文件名和一个热编码标签。代码是这样的:
data = pd.read_csv('train.csv')
img_width = 400
img_height = 400
img_vectors = []
for i in range(data.shape[0]):
path = 'Images/' + data['Id'][
img = image.load_img(path, target_size=(img_width, img_height, 3))
img = image.img_to_array(img)
img = img/255.0
img_vectors.append(img)
img_vectors = np.array(img_vectors)
错误信息:
MemoryError Traceback (most recent call last)
<ipython-input-13-dd2302ae54e1> in <module>
----> 1 img_vectors = np.array(img_vectors)
MemoryError: Unable to allocate array with shape (7344, 400, 400, 3) and data type float32
我想我需要为所有图像使用一批较小的数组来处理内存问题,以避免同时具有一个包含所有图像数据的数组。
[在较早的项目中,我在没有多标签的情况下进行了约225k张图像的图像分类。无论如何,这段代码不会将所有图像数据转换为一个巨型数组。而是将图像数据分成较小的批处理:
#image preparation
if K.image_data_format() is "channels_first":
input_shape = (3, img_width, img_height)
else:
input_shape = (img_width, img_height, 3)
train_datagen = ImageDataGenerator(rescale=1./255, horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_data_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(validation_data_dir, target_size=(img_width, img_height), batch_size=batch_size, class_mode='categorical')
model = Sequential()
model.add(Conv2D(32, (3,3), input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
...
model.add(Dense(17))
model.add(BatchNormalization(axis=1, momentum=0.6))
model.add(Activation('softmax'))
model.summary()
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=nb_validation_samples // batch_size,
class_weight = class_weight
)
因此,我真正需要的是一种如何处理大型图像数据集以进行多标签图像分类而又不会造成内存麻烦的方法。理想的做法是使用包含图像文件名和单点热编码标签的csv文件,并结合数组批处理进行学习。
这里的任何帮助或猜测将不胜感激。
解决您面临的问题的最简单方法是编写服装数据生成器,这是一个tutorial,显示了如何执行此操作。这个想法是,您不用创建flow_from_directory
,而是创建一个服装数据加载器,该加载器从其源路径读取每个图像,并为它们提供对应的标签。实际上,我认为您的数据存储在.csv文件中,其中每一行都包含图像的路径以及图像中存在的标签。因此,您的数据源将具有函数getittem((自我,索引)),该函数将从原始编号索引的路径中读取图像,并与通过读取该原始标签中的标签获得的目标一起返回并对其进行热编码,然后对其求和。