Форматирование большого списка изображений занимает больше времени при использовании многопроцессорной обработки. - PullRequest
0 голосов
/ 04 февраля 2019

Я сейчас обрабатываю 15 тыс. Изображений, но в какой-то момент это число может увеличиться.Я написал функцию, которая вносит несколько изменений в изображения, например, конвертирует их в черно-белые, обрезает, изменяет размеры и затем выравнивает их.Позже я сохраню отформатированные изображения в файл CSV для последующего использования с tenorflow.Я использую многопроцессорный модуль, чтобы использовать больше ядер на моем процессоре.Кажется, что при многопроцессорной обработке требуется больше времени, чем при использовании цикла for для редактирования одного изображения за раз.Я также написал простую версию той же программы, которая возводит в квадрат ряд чисел.Использование многопроцессорности для этого на самом деле быстрее.

Было бы лучше разделить данные на пакеты?Я написал генератор для разных партий, но я не мог заставить его работать с несколькими процессорами.

Сравнивает время форматирования изображений с последовательными вызовами функций многопроцессорной обработки.

            # comparing time for image formating using
            # sequential and multiprocessing
            # vonderasche
            # 2/3/2019

            import multiprocessing as mp
            import time
            import numpy as np
            import cv2
            import os
            import sys

            def my_format_images(image):
                ''' converts to BW, crops, resizes and then flattens the image'''

                image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

                height, width = image.shape

                if (height < width):
                    x_start = int((width - height) / 2)
                    x_end = height + x_start
                    image = image[0:height, x_start:x_end]

                elif (width < height):
                    y_start = int((height - width) / 2)
                    y_end = width + y_start
                    image = image[y_start:y_end, 0:width]

                image = cv2.resize(image, (100, 100))

                image = image.flatten()

                return image

            def load_images(path):
                '''loads images from a provided path'''

                print('loading images')
                image_list = []
                for root, dirs, files in os.walk(path):
                    for file in files:
                        if file.endswith(".jpg"):
                            img = cv2.imread(os.path.join(root, file))
                            image_list.append(img)
                    return image_list

            def main():

                path = 'images'
                images = load_images(path)

                print('total images loaded: ' + str(len(images)))

                # multiprocessing function call
                start_mp_timer = time.time()
                pool = mp.Pool(4)
                result = pool.map(my_format_images, images)
                end_mp_timer = time.time() - start_mp_timer

                # sequential function call
                sum_of_single_thread = []
                start_timer = time.time()
                for i in images:
                    num = my_format_images(i)
                    sum_of_single_thread.append(num)
                end_timer = time.time() - start_timer

                print('multiprocessing time: ' + ' {: 05.5f}'.format(end_mp_timer) + ' sequential time: ' +' {: 05.5f}'.format(end_timer))

            if __name__ == "__main__":
                main()
            main()

Простая версия, которая возводит в квадрат ряд чисел, чтобы увидеть, как работает многопроцессорная обработка.

    # multiprocessing - test using numbers
    # vonderasche
    # 2/3/2019

    import multiprocessing as mp
    import time
    import os

    def square(x):
      ''' prints the current process id and returns the square'''
      print(os.getpid())
      return x**x

    def main():

      data = [4784, 2454, 34545, 54545,
                                  34545, 24545, 1454, 454542, 52221, 11242, 88478, 447511]

      # multiprocessing function call
      pool = mp.Pool(4)
      start_mp_timer = time.time()
      result = pool.map(square, data)
      end_mp_timer = time.time() - start_mp_timer


      #  sequential function call
      sum_of_single_thread = []

      start_timer = time.time()
      for i in data:
          num = square(i)
          sum_of_single_thread.append(num)
      end_timer = time.time() - start_timer

      print('multiprocessing time: ' + '{:05.5f}'.format(end_mp_timer))
      print('sequential time: ' + '{:05.5f}'.format(end_timer))

    if __name__ == "__main__":
      main()

1 Ответ

0 голосов
/ 04 февраля 2019

Я думаю, что вы столкнулись с проблемой, при которой мультипроцессирование копирует память родительского процесса при создании дочерних процессов.См. Использование многопроцессорной памяти Python .

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

Если это так, мое решение было бывыполнить загрузку внутри процессов.

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