※記事内に商品プロモーションを含むことがあります。
はじめに
ChainerのVariableクラスを使った自動微分に関する記事である。前回記事の補足として、backwardメソッドを使用するときの注意点と、chainer.grad
関数を使った自動微分の計算について述べる。
backwardメソッドを使用する度に勾配が加算されるため、2回以上使用するときは、勾配を除去する必要がある。また、chainer.grad
関数を使うと、任意のVariable変数間の勾配を計算できる。
前回記事:Chainerの自動微分で勾配を求める
環境
ソフトウェア | バージョン |
---|---|
Spyder | 3.3.3 |
Python | 3.7.3 |
NumPy | 1.16.2 |
Chainer | 6.3.0 |
以下では、各ライブラリを以下のようにインポートしていることを前提とする。
|
|
backwardメソッドの注意点
chainer.Variable
のbackward
を使うと自動微分が計算される。ただし、Chainerの仕様上、backward
を実行するたびに、変数の勾配が加算されてしまう。そのため、2回以上backward
を実行すると、望ましい結果が得られなくなる。
例:
$y = 2x$の勾配を計算する。$x=1$に対する勾配は2であるが、2度backward
を実行すると、誤った勾配が出力される。
|
|
さらにy.backward()
を実行するたびにx
の勾配は2ずつ増えていく。すなわち、勾配が蓄積され続けている。
2回以上backward
を実行しても正しい勾配を得るためには、以下のようにbackward
を実行する度にcleargrad
で勾配を削除してやる必要がある。
|
|
chainer.gradによる勾配計算
chainer.grad
関数を使うと、任意のVariable変数間の勾配を計算できる。主な引数を以下に示す。
|
|
引数の説明は以下の通り。
outputs: (tuple or list of Variable)
逆誤差伝搬の起点となる、出力の変数。
inputs: (tuple or list of Variable)
勾配を計算する入力側の変数。
set_grad: bool
True
の場合、inputs
の変数のgrad
に勾配が格納される。
デフォルトはFalse
。
retain_grad: bool
True
の場合、中間変数のgrad
に勾配が格納される。
デフォルトはFalse
。
chainer.grad
関数では、必要最小限の計算パスのみを対象として勾配が計算される。
なお、backward
と異なり、chainer.grad
を何度実行しても勾配は蓄積されず、同じ結果が得られる。
例:以下の計算グラフを考える。
実行結果1~5では、全て以下の変数を使用している。
|
|
実行結果1: zに対するx0の勾配を計算する。
|
|
実行結果2: zに対するx0, x1の勾配を計算する。
|
|
実行結果3: yに対するx0の勾配を計算する。
|
|
実行結果4: gradに勾配を残す
|
|
実行結果5: 中間変数yに勾配を残す
|
|