11.2. ループを並列処理する方法#
画像処理では、同じアルゴリズムを大量の画像のバッチに適用することがよくあります。このセクションでは、joblib を使用してループを並列処理する方法を提案します。以下は、このような繰り返しタスクの例です。
import skimage as ski
def task(image):
"""
Apply some functions and return an image.
"""
image = ski.restoration.denoise_tv_chambolle(
image[0][0], weight=0.1, channel_axis=-1
)
fd, hog_image = ski.feature.hog(
ski.color.rgb2gray(image),
orientations=8,
pixels_per_cell=(16, 16),
cells_per_block=(1, 1),
visualize=True
)
return hog_image
# Prepare images
hubble = ski.data.hubble_deep_field()
width = 10
pics = ski.util.view_as_windows(
hubble, (width, hubble.shape[1], hubble.shape[2]), step=width
)
リスト pics
の各要素に対して task
関数を実行するには、for ループを記述するのが一般的です。このループの実行時間を測定するには、ipython を使用して %timeit
で実行時間を測定できます。
def classic_loop():
for image in pics:
task(image)
%timeit classic_loop()
このループをコーディングするもう 1 つの方法は、同じ効率を持つコンプリヘンションリストを使用することです。
def comprehension_loop():
[task(image) for image in pics]
%timeit comprehension_loop()
joblib
は、コンプリヘンションリストがあれば for ループを簡単に並列処理する方法を提供するライブラリです。ジョブの数も指定できます。
from joblib import Parallel, delayed
def joblib_loop():
Parallel(n_jobs=4)(delayed(task)(i) for i in pics)
%timeit joblib_loop()