Многопроцессорная обработка Python для ускорения сравнения изображений - PullRequest
0 голосов
/ 26 ноября 2018

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

Ниже приведен фрагмент кода, который сравнивает мою текущую реализацию задачи с одним процессом с одной реализацией многопроцессорной попытки, вдохновленной ответом здесь )

from time import time
import numpy as np
from multiprocessing import Pool

# generate test data
im_list_1 = [np.random.random((320, 640)).astype(np.float32) for num in range(350)]
im_list_2 = [np.random.random((320, 640)).astype(np.float32) for im in range(11)]

# functions used for single process implementation
def mse(im1, im2):
    return np.mean(np.square(im1 - im2))

def compare_mse(im_list_1, im_list_2):
    results = np.zeros((len(im_list_1), len(im_list_2)), dtype=np.float32)
    for row in np.arange(len(im_list_2)):
        for col in np.arange(len(im_list_1)):
            results[col, row] = mse(im_list_1[col], im_list_2[row])
    return results

# functions used for multi-process implementation
def mse_worker(im1, im2):
    return mse(im1, im2)

def mse_data_stream(a, b):
    for i, im1 in enumerate(a):
        for j, im2 in enumerate(b):
            yield (i, j), (im1, im2)

def proxy(args):
    return args[0], mse_worker(*args[1])

def pool_compare_mse(im_list_1, im_list_2):
    pool = Pool(processes=4)
    results = pool.map(proxy, mse_data_stream(im_list_1, im_list_2))
    Y = np.zeros((len(im_list_1), len(im_list_2)))
    for k, v in results:
        Y[k[0], k[1]] = v
    return Y

# test both scenarios
t_start = time()
compare_mse(im_list_1=im_list_1, im_list_2=im_list_2)
print ('single process took {} seconds'.format(time() - t_start))

t_start = time()
Y = pool_compare_mse(im_list_1, im_list_2)
print ('multi-processing took {} seconds'.format(time()-t_start))

Мой вопрос - (как) эта задача может быть паралелизирована в многопроцессорной обработке Python (или аналогичной) с существенным приростом производительности?В попытке дать количественную оценку «значимым», вдвое больше времени обработки с 3 процессами (в сравнении с 1) будет большой выигрыш.

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

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