「喰う・書く・逃げる」に棲む処

 動物に関するデータ分析者のブログです

TensorFlowの自動微分の基礎をまとめてみる

TensorFlowの自動微分の基礎について自分なりにまとめてみました。

自動微分の正確な挙動を解説したわけではなく、「こんな感じの挙動なのではないか?」という私の考察を記しているだけなので、参考程度にしていただけると助かります。

TensoeFlowの公式ドキュメントによるとこんな感じで書くと自動微分になるようです。自動微分(Automatic Differentiation)といっていますが、要は普通に微分してくれるだけです。

import tensorflow.compat.v2 as tf

#要素が1の2×2配列を生成
#[[1. 1.]
# [1. 1.]]
x = tf.ones((2, 2))

with tf.GradientTape() as t:
  t.watch(x)
  # どの変数で微分するのか明示している(ここでは変数X)

 #[[1. 1.]
 # [1. 1.]]
 #の要素をすべて足し合わせる(つまりy = 4)
  y = tf.reduce_sum(x)
 #上の配列の要素がXとすると
 # Y = 4×X
 # みたいになっている
 
 # Z = Y^2
 #をする。
  z = tf.multiply(y, y)

# 元の入力テンソル x に対する z の微分
dz_dx = t.gradient(z, x)
# 要はdz/dy × dy/dxをしている。

コメントアウトで簡単に解説していますが、本文中でも解説します(間違えて理解していたらごめんなさい)。

1. 自動微分のクラスGradientTape()tインスタンスに格納

with tf.GradientTape() as t:

2. watch()メソッドでどの変数について微分するか明示

 t.watch(x)

ここでは変数Xx微分すると明示しています。明示しておかないと微分の結果が`None'となってしまいます。

x = tf.Variable(tf.ones((2, 2)))

として、xを生成しておいても微分できます。

3. 数式の生成

以下のコードで配列Xの中身をすべて足し合わせています。

  y = tf.reduce_sum(x)

要素(x)がすべて1で、要素数が4つの配列なので

 y = 4 x

という数式になっていると思ってよいと思います(この場合は...)。

次に以下のコードで

 z = y^2

という数式が出来上がります。

z = tf.multiply(y, y)

これらの数式がt(テープ: Tape)の中に記録されていきます(たぶん...)。

4.微分の実行

gradient(数式, 変数)メソッドで微分を実行します。数式の部分は上で生成した数式(ここではz)、変数の部分は何について微分するか明示したものを入れてあげます(ここではx)。

dz_dx = t.gradient(z, x)
 \frac{dz}{dy} = 2y \\ \frac{dy}{dx} = 4

なので

 \frac{dz}{dx} = \frac{dz}{dy} \times \frac{dy}{dx} = 2 \times 4 = 8

と数式が微分されます。

それと同時にxの要素を代入した値も同時に計算されます。なので、dz_dxには

#[[8. 8.]
# [8. 8.]]

が格納されます。

微分の注意点として、インスタンスtに対してメソッドgradient()は一回しか呼び出せないということです。

つまり、連続して

dz_dx = t.gradient(z, x)
dz_dy = t.gradient(z, y) # <- yはxを入れ子にしている変数なので微分できる

とすると

RuntimeError: A non-persistent GradientTape can only be used to compute one set of gradients (or jacobians)

というエラーが返されます。

偏微分などをしたい場合は、初めに

with tf.GradientTape() as t:
  with tf.GradientTape() as t2:

として、

dz_dx = t.gradient(z, x)
dz_dy = t2.gradient(z, y)

としてあげればよいみたいです。

自動?

数値計算のためにコードを書いたら必然的にそれが数式と同様の意味を持つと思います。この”自動”の意味は、数値計算コード(数式)から微分されたコード(数式)を生成して数値計算をしてくれるということなのでしょうか?

確かに、自動微分、便利ですね。

参考ページ

www.tensorflow.org

blog.shikoan.com

stackoverflow.com