Как избежать чрезмерного использования памяти при обучении нескольких моделей в Tensorflow - PullRequest
0 голосов
/ 06 апреля 2020

В настоящее время я пишу фрагмент кода, цель которого - объяснить, как применение различных коэффициентов отсева влияет на производительность обобщенной c модели CNN в нескольких наборах данных.

Я настроил ее так, для каждого набора данных я тренирую 10 разных моделей (с 10 различными показателями отсева) в общей сложности 3 раза и регистрирую точность для каждого прогона и отсева. Надеюсь, этот фрейм данных немного лучше объясняет то, что я сказал:

enter image description here

Код выглядит примерно так:

for i, dataset in tqdm(enumerate(datasets)):
    dataset_path = pathlib.Path(args.input_folder) / dataset

    ds_train, ds_test, ds_validation = loader.get_image_data_generators(dataset_path, BATCH_SIZE)
    CLASS_NAMES = list(ds_train.class_indices.keys())

    INPUT_SHAPE = ds_train.next()[0].shape[1:]
    OUTPUT_SIZE = ds_train.next()[1].shape[1]

    ds_train_size, ds_test_size, ds_validation_size = loader.get_split_sizes(dataset_path)

    performance = {'dataset': [], 'dropout_rate': []}

    # Pre-fill dictionary with dataset and dropout labels.
    performance['dataset'] = [dataset for i in range(DROPOUT_STEPS)]
    performance['dropout_rate'] = [i/DROPOUT_STEPS for i in range(DROPOUT_STEPS)]

    for run_i in range(RUNS):
        performance[f'run_{run_i}_acc'] = []

        for i in range(DROPOUT_STEPS):

            # Compute dropout rate.
            dropout_rate = i / DROPOUT_STEPS

            # Initialize model
            model = models.Sequential()
            model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=INPUT_SHAPE))

            model.add(layers.MaxPooling2D((2, 2)))
            model.add(layers.Conv2D(64, (3, 3), activation='relu'))

            model.add(layers.MaxPooling2D((2, 2)))
            model.add(layers.Conv2D(64, (3, 3), activation='relu'))

            model.add(layers.Flatten())
            model.add(layers.Dense(64, activation='relu'))
            model.add(layers.Dropout(dropout_rate))
            model.add(layers.Dense(OUTPUT_SIZE, activation='softmax'))

            model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

            model.fit(
                x=ds_train,
                epochs=EPOCHS, 
                steps_per_epoch=math.ceil(ds_train_size / BATCH_SIZE), 
                validation_data=ds_validation, 
                validation_steps=math.ceil(ds_validation_size / BATCH_SIZE)
            )

            test_loss, test_accuracy = model.evaluate(ds_test, steps=math.ceil(ds_test_size / BATCH_SIZE))
            performance[f'run_{run_i}_acc'].append(test_accuracy)
            print(f'✔️  Dropout rate {dropout_rate} resulted on {test_accuracy}')

    df = pd.DataFrame(performance)
    print(df)

    df.to_pickle(f'output/performance/{dataset}-perf.pkl')

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

enter image description here

Как бы я go об оптимизации этого кода, избегая чрезмерного использования памяти? Сохраняет ли Tensorflow какие-либо временные файлы во время итерации между запусками или даже выпадающими шагами? Если да, то как мне сбросить память при каждом цикле l oop?

Спасибо за помощь.

...