LoginSignup
1
2

More than 1 year has passed since last update.

PyTorchの自動微分を用いて関数の接線を描画してみた

Last updated at Posted at 2021-04-04

この記事では、fastbookのサンプルコード04_mnist_basics.ipynbをベースに自分の実験を入れながら、次のように関数の接線を表示するコードを書いてみました。
image.png

モジュールのインポート

plot_function()tensor()など、一部fastbookのツール関数を使っている関係で、サンプルコードに従って、次のようにfast.ai提供のモジュールをインポートしています。(plot_function()を自作すれば、普通にnumpy matplotlib torchでOKです)

!pip install -Uqq fastbook
import fastbook
fastbook.setup_book()

from fastai.vision.all import *
from fastbook import *

接線の方程式を求める

まず、接線の方程式を求める必要があります。関数を$f(x)$とし、$x=x_0$での微分値を$a$とし、$y_0 = f(x_0)$として、接線の方程式を$y=ax+b$とすれば、その接線は$(x_0,y_0)$を通るので

\begin{align}
y_0 &= a x_0 + b\\
\therefore\ y &= y_0 + a(x - x_0) = a x + y_0 - a x_0\\
b &= y_0 - a x_0
\end{align}

となります。次のコードは、この結果に基づいて接線の方程式を求める関数です。

def tangent_line(f, x0:Tensor):
  y0 = f(x0)
  y0.backward()
  with torch.no_grad():
    a = x0.grad.clone()
    b = y0 - a*x0
  x0.grad.zero_()
  return lambda x : a*x + b

x0.grad.zero_()は、テンソル変数の微分値をゼロクリアするためのコードで、このtangent_line関数を単独にコールし引数$x_0$が使いまわさいれていると、関数tangent_lineをコールする都度微分値(grad)が累積されるためです。また、a = x0.grad.clone()とするのは、そうしないとax_0.gradが同じメモリをシェアするらしく、x0.grad.zero_()をコールした時点でaが参照する値がクリアされるためです。

接線を描画する

次のコードは、与えられた関数f(x)の指定されたx座標xでの接線を描画する関数です。

def plot_tangent_line(f, x, x_range=1.):
  xt = tensor(x).requires_grad_()
  tf = tangent_line(f, xt)
  with torch.no_grad():
    x_r = np.array( [x - x_range, x + x_range] )
    plot_function(f, 'x', 'f(x)', min=x_r[0], max=x_r[1])
    plt.scatter(xt, f(xt), color='red')
    plt.plot(x_r,tf(x_r))
    plt.show()

tfは接線の方程式で、x_rはx座標の描画範囲[x-x_range, x+x_range]です。また、tensorplot_functionはfast.aiが提供する関数です。そして、接線はplt.plot(x_r,tf(x_r))で描画しています。具体的には、(x_r[0],tf(x_r[0]))(x_r[1],tf(x_r[1]))の2点を結ぶ直線になります。

たとえば、$f(x)=0.78x^2+sin(x)$の$x=-0.75$での接線を描画するには次のようにします。

def f(x): return 0.78*x**2 + torch.sin(x)
plot_tangent_line(f, -.75)

次の図はこれを実行した結果です。
image.png

関連記事

fast.aiで作るハンドメイドの超簡単な手書き数字判別器
fastbookのサンプルコード(02_production.ipynb)をGoogle Colabで試してみた Part 1
PyTorchの自動微分を用いて2変数関数の接平面を描画してみた

fast.ai公式ページ

Practical Deep Learning for Coders
Lesson 3 - Deep Learning for Coders (2020)
Lesson 4 - Deep Learning for Coders (2020)

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2