1. ホーム
  2. python

delayed() 関数は何をするのですか (Python で joblib を使用した場合)

2023-09-23 23:43:11

質問

私は のドキュメントを読みました。 が何を意味しているのか理解できません。 The delayed function is a simple trick to be able to create a tuple (function, args, kwargs) with a function-call syntax.

以下のように操作したいリスト(allImages)を繰り返し処理するために使っています。

def joblib_loop():
    Parallel(n_jobs=8)(delayed(getHog)(i) for i in allImages)

これは私が望むように(そして私の8つのコアをすべて使ってスピードアップして)私のHOG機能を返しますが、私はそれが実際に何をやっているのかよくわかりません。

私の Python の知識は、せいぜいまあまあで、基本的な何かを見逃している可能性が非常に高いです。正しい方向への任意のポインターは非常にありがたいです。

どのように解決するのですか?

と書くとどうなるか、考えてみるとよくわかると思います。

Parallel(n_jobs=8)(getHog(i) for i in allImages)

というように、この文脈では、より自然に表現することができます。

  1. を作成します。 Parallel インスタンスを作成します。 n_jobs=8
  2. リストを作成する [getHog(i) for i in allImages]
  3. にそのリストを渡します。 Parallel インスタンスに渡します。

何が問題なのか?リストが Parallel オブジェクトに渡されるまでに、すべての getHog(i) の呼び出しは既に返されたので、Parallelで実行するものは何も残っていないのです! すべての作業はすでにメインスレッドで順次行われたのです。

私たちが 実際に は、どの関数をどの引数で呼び出したいかを Python に伝えることです。 を実際に呼び出すことなく - 言い換えれば、私たちがしたいのは を遅らせる を実行させたいのです。

これは delayed は便利なことに、明確な構文で私たちを可能にします。もし私たちがPythonに、私たちが foo(2, g=3) を呼び出したい場合、単に次のように書けばよいのです。 delayed(foo)(2, g=3) . 返されるのはタプル (foo, [2], {g: 3}) を含む、タプルです。

  • への参照。 機能 への参照、例えば foo
  • すべて 引数 (短い "args") キーワードなし、例: t 2
  • 全て キーワード引数 (短い "kwargs"), 例. g=3

ということは Parallel(n_jobs=8)(delayed(getHog)(i) for i in allImages) と書くことで、次のようになります。

  1. A Parallel のインスタンスで n_jobs=8 が作成されます。

  2. リスト

     [delayed(getHog)(i) for i in allImages]
    
    

    が作成され、その評価は

     [(getHog, [img1], {}), (getHog, [img2], {}), ... ]
    
    
  3. そのリストは Parallel インスタンスに渡されます。

  4. Parallel インスタンスは8つのスレッドを作成し、リストのタプルをそれらに分配します。

  5. 最後に、これらのスレッドのそれぞれがタプルの実行を開始します。つまり、2番目と3番目の要素を引数としてアンパックした最初の要素を呼び出します。 tup[0](*tup[1], **tup[2]) を呼び出し、タプルを私たちが実際に意図した呼び出しに戻します。 getHog(img2) .