fit_generator в керасе, загружая все в память - PullRequest
0 голосов
/ 12 июня 2018

У меня есть исходные данные (X_train, y_train), и я изменяю эти данные в другое.Исходные данные - это просто изображения с метками.Модифицированные данные должны представлять собой пары изображений для сиамской сети, которых много, и они будут иметь около 30 ГБ в памяти.Поэтому нельзя запустить эту функцию для создания пар на целых исходных данных.Итак, я использовал keras fit_generator, думая, что он загрузит только эту конкретную партию.

Я запустил и model.fit, и model.fit_generator на парах сэмплов, но я заметил, что оба используют одинаковое количество памяти.Итак, я думаю, что некоторые проблемы с моим кодом в использовании fit_generator.Ниже приведен соответствующий код.Ребята, можете ли вы помочь мне с этим?

Код ниже:

    def create_pairs(X_train, y_train):
        tr_pairs = []
        tr_y = []

        y_train = np.array(y_train)
        digit_indices = [np.where(y_train == i)[0] for i in list(set(y_train))]

        for i in range(len(digit_indices)):
            n = len(digit_indices[i])
            for j in range(n):
                random_index = digit_indices[i][j]
                anchor_image = X_train[random_index]
                anchor_label = y_train[random_index]
                anchor_indices = [i for i, x in enumerate(y_train) if x == anchor_label]
                negate_indices = list(set(list(range(0,len(X_train)))) - set(anchor_indices))
                for k in range(j+1,n):
                    support_index = digit_indices[i][k]
                    support_image = X_train[support_index]
                    tr_pairs += [[anchor_image,support_image]]

                    negate_index = random.choice(negate_indices)
                    negate_image = X_train[negate_index]
                    tr_pairs += [[anchor_image,negate_image]]

                    tr_y += [1,0]


        return np.array(tr_pairs),np.array(tr_y) 



    def myGenerator():
        tr_pairs, tr_y = create_pairs(X_train, y_train)
        while 1:
            for i in range(110): # 1875 * 32 = 60000 -> # of training samples
                if i%125==0:
                    print("i = " + str(i))
                yield [tr_pairs[i*32:(i+1)*32][:, 0], tr_pairs[i*32:(i+1)*32][:, 1]], tr_y[i*32:(i+1)*32]




    model.fit_generator(myGenerator(), steps_per_epoch=110, epochs=2,
                  verbose=1, callbacks=None, validation_data=([te_pairs[:, 0], te_pairs[:, 1]], te_y), validation_steps=None, class_weight=None,
                  max_queue_size=10, workers=1, use_multiprocessing=False, shuffle=True, initial_epoch=0)

1 Ответ

0 голосов
/ 12 июня 2018

myGenerator возвращает генератор.

Однако вы должны заметить, что create_pairs загружает полный набор данных в память.Когда вы вызываете tr_pairs, tr_y = create_pairs(X_train, y_train), набор данных загружается, поэтому ресурсы памяти используются.

myGenerator просто пересекает структуру, которая уже находится в памяти.

Решение состоит в том, чтобыcreate_pairs сам генератор.

Если данные представляют собой пустой массив, я могу предложить использовать h5 файлы для чтения фрагментов данных с диска.

http://docs.h5py.org/en/latest/high/dataset.html#chunked-storage

...