リバースモード自動微分のステップバイステップの例


27

この質問がここに属するかどうかはわかりませんが、最適化における勾配法と密接に関連しています。これはここではトピックのようです。とにかく、他のコミュニティがこのトピックについてより良い専門知識を持っていると思うなら、気軽に移行してください。

要するに、私は逆モード自動微分の段階的な例を探しています。トピックに関する文献はそれほど多くなく、既存の実装(TensorFlowのようなもの)は、その背後にある理論を知らずに理解するのは困難です。したがって、私たち何を渡し、どのように処理、計算グラフから何を取り出すかを誰かが詳細に示すことができれば、非常に感謝しています。

私が最も苦労しているいくつかの質問:

  • -なぜそれらが必要なのですか?
  • 逆微分ルール -前方微分を行う方法を知っていますが、どのように後方に進みますか?たとえば、このセクションの例では、をどのように知ることがますか?w2¯=w3¯w1
  • 我々はして作業を行うだけで、シンボルの実際を介して、またはパス値は?たとえば、同じ例では、と記号または値はありますか?wiwi¯

「Scikit-Learn&TensorFlowを使用したハンズオン機械学習」付録Dには、非常に良い説明があります。私はそれをお勧めします。
アグスティンバラチナ

回答:


37

式あり、導関数およびを見つけたいとします。リバースモードADは、このタスクを2つの部分、つまりフォワードパスとリバースパスに分割します。z=x1x2+sin(x1)dzdx1dzdx2

フォワードパス

最初に、複雑な式をプリミティブな式のセット、つまり最大で1つの関数呼び出しで構成される式に分解します。一貫性を保つために、入力変数と出力変数の名前も変更しますが、必須ではありません。

w1=x1
w2=x2
w3=w1w2
w4=sin(w1)
w5=w3+w4
z=w5

この表現の利点は、個別の式ごとの差別化ルールが既知であることです。たとえば、導関数はであるため、ます。この事実は、以下の逆パスで使用します。sincosdw4dw1=cos(w1)

基本的に、フォワードパスはこれらの各式を評価し、結果を保存することで構成されます。たとえば、入力はおよびです。それから私達にあります:x1=2x2=3

w1=x1=2
w2=x2=3
w3=w1w2=6
w4=sin(w1) =0.9
w5=w3+w4=6.9
z=w5=6.9

リバースパス

これが魔法の始まりであり、連鎖ルールで始まります。基本的な形では、チェーンルールは、変数がに依存し、次にがに依存する場合、次のようになります。t(u(v))uv

dtdv=dtdududv

または、いくつかのパス/変数を介して依存する場合、たとえば:tvui

u1=f(v)
u2=g(v)
t=h(u1,u2)

次に(ここで証明を参照):

dtdv=idtduiduidv

我々が持っている場合表現グラフの点で、最終のノードと入力ノード、およびから経路に中間ノードを経由(すなわち、我々は誘導体見つけることができます) aszwizwiwpz=g(wp)wp=f(wi)dzdwi

dzdwi=pparents(i)dzdwpdwpdwi

つまり、中間変数または入力変数に対する出力変数導関数を計算するには、その親の導関数とプリミティブ式導関数を計算する式を知るだけでです。zwiwp=f(wi)

リバースパスは末尾(つまり)から始まり、すべての依存関係に逆伝播します。ここにあります(「シード」の表現):dzdz

dzdz=1

それは「変化として読み取ることができるでまったく同じ変化の結果非常に明白です、」。zz

次に、であることがます。z=w5

dzdw5=1

w5直線的に依存と、そうと。チェーンルールを使用すると、次のことがわかります。w3w4dw5dw3=1dw5dw4=1

dzdw3=dzdw5dw5dw3=1×1=1
dzdw4=dzdw5dw5dw4=1×1=1

定義および偏導関数のルールから、ます。したがって:w3=w1w2dw3dw2=w1

dzdw2=dzdw3dw3dw2=1×w1=w1

これは、フォワードパスで既に知っているように、次のとおりです。

dzdw2=w1=2

最後に、および介して寄与します。ここでも、偏微分のルールから、およびます。したがって:w1zw3w4dw3dw1=w2dw4dw1=cos(w1)

dzdw1=dzdw3dw3dw1+dzdw4dw4dw1=w2+cos(w1)

繰り返しますが、既知の入力が与えられると、それを計算できます。

dzdw1=w2+cos(w1)=3+cos(2) =2.58

以来とのためだけの別名ですと、私たちは答えを得ます:w1w2x1x2

dzdx1=2.58
dzdx2=2

以上です!


この説明はスカラー入力、つまり数値のみに関するものですが、実際にはベクトルや行列などの多次元配列にも適用できます。このようなオブジェクトで式を区別する際に留意すべき2つのこと:

  1. 導関数は、入力または出力よりもはるかに高い次元を持ちます。たとえば、ベクトルwrtの導関数は行列であり、行列wrtの導関数は4次元配列(テンソルと呼ばれることもあります)です。多くの場合、そのような導関数は非常にまばらです。
  2. 出力配列の各コンポーネントは、入力配列の1つ以上のコンポーネントの独立した関数です。例えば、でとが両方ともベクトルの場合、はに依存せず、サブセットのみに依存します。特に、これは、導関数を見つけることは、がどのように依存するかを追跡することになります。y=f(x)xyyiyjxkdyidxjyixj

自動差別化の力は、条件やループなどのプログラミング言語からの複雑な構造を処理できることです。ただし、必要なのが代数式であり、シンボリック表現を操作するのに十分なフレームワークがある場合は、完全なシンボリック式を構築できます。実際、この例では、式を生成し、必要な入力に対してこの導関数を計算できます。dzdw1=w2+cos(w1)=x2+cos(x1)


1
非常に便利な質問/回答。ありがとう。ちょっとした批判:あなたは説明せずに木構造の上を移動するようです(それはあなたが両親などについて話し始めるときです)
MadHatter

1
また、なぜ種が必要なのかを明確にするのに害はありません。
MadHatter

@MadHatter、コメントありがとう。グラフ構造を強調するために、いくつかの段落(親を参照する段落)を言い換えることを試みました。この名前自体は私の意見では誤解を招くかもしれませんが、テキストにも「シード」を追加しました。ADではシードは常に固定式です-、選択または生成できるものではありません。dzdz=1
-ffriend

ありがとう!複数の「シード」を設定する必要がある場合、通常は1と0を選択することに気付きました。理由を知りたいのですが。つまり、差分wrt自体の「商」を使用するため、「1」は少なくとも直感的に正当化されます。しかし、0はどうでしょうか。また、2つ以上の種子を選択する必要がある場合はどうなりますか?
MadHatter

1
私の知る限り、複数のシードはフォワードモードADでのみ使用されます。この場合、区別したい入力変数のシードを1に設定し、他のすべての入力変数のシードを0に設定して、出力値に寄与しないようにします。リバースモードでは、シードを出力変数に設定します。通常、出力変数は1つしかありません。いくつかの出力変数でリバースモードのADパイプラインを構築し、1以外のすべてを0に設定して、フォワードモードと同じ効果を得ることができると思いますが、このオプションを調査したことはありません。
ffriend
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.