Как работать с большим набором данных для классификации изображений по меткам с точки зрения памяти и пакетов - PullRequest
0 голосов
/ 19 января 2020

Я работаю над набором данных из 300К изображений, выполняя мультиклассовую классификацию изображений. До сих пор я взял небольшой набор данных из примерно 7 тысяч изображений, но код либо возвращает ошибку памяти, либо мой ноутбук просто умирает. Приведенный ниже код преобразует все изображения в массив 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

Я полагаю, мне нужна партия меньших массивов для всех изображений, чтобы справиться с проблемой памяти, чтобы избежать наличия одного массива с все imagedata в то же время.

В более раннем проекте я выполнил классификацию изображений без нескольких меток с около 225 тыс. изображений. В любом случае, этот код не преобразует все данные изображения в один гигантский массив. Скорее, он помещает изображения в меньшие партии:

#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-файлом, содержащим метки имени файла и метки с горячим кодированием в сочетании с пакетами массивов для обучения.

Любая помощь или предположения здесь будут с благодарностью.

1 Ответ

1 голос
/ 19 января 2020

Самый простой способ решить проблему, с которой вы столкнулись, - написать генератор данных костюма. Вот учебник , в котором показано, как это сделать. Идея состоит в том, что вместо использования flow_from_directory вы создаете сгенерированный загрузчик данных костюма, который считывает каждое изображение с его исходного пути и дает вам соответствующие метки. Практически я думаю, что ваши данные хранятся в файле .csv, где каждая строка содержит путь к изображению и метки, присутствующие на изображении. Таким образом, в вашем канале данных будет функция getittem (self, index), которая будет считывать изображение из пути в индексе необработанных чисел и возвращать его вместе с целью, полученной при считывании меток в этом необработанном и одном горячем закодируйте их, затем сложите их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...