ディープラーニングG検定の勉強中 その9(微分と関数値の近似、極大・極小)

書籍「最短コースでわかるディープラーニングの数学」の内容に沿って勉強しています。

今回は、まずは微分と関数値の近似についてです。

関数の直線について、2点(x, f(x))、(x+h, f(x+h))を結んだ関数の直線の傾きをグラフにすると、以下となります。

2-3-2-1.png

このとき、xに、x+hと微少の値を増やしたとき、f(x)の変化量との間には、以下の式が成り立ちます。

式1
2-4-3.png

例えば、f(x)=2 * x のとき、xが1でその増加量が、0.000000001のときには、
f(x)は、の増加量は0.000000002になるので、

2.000000002 ≅ 2 * 1.000000001 が成り立ちます。つまり、xの微量の増加によるf(x)の変化量は、hf '(x)と等しくなります。

接線についても、

2-3-2-2.png

dxがhと同様に微少の値が増加するときのf(x)の変化量は、f '(x)dxと等しくなり、式2が成立します。

式2
2-4-4.png

つまりは、式3が成立することになります。

式3
2-4-5.png

なお、上記の式から、f '(x)の値が0になるときには、f(x)の変化量も0となります。
そして、f '(x)=0となるxの地点(接線の傾き0)では、関数の形が山頂になっていたり、谷底になっていたりします。
関数の形が山頂のときには「極大」、谷底のときには「極小」といいます。

2-4-1.png

ただし、f '(x)=0のときに極大にも極小にもならない関数もあります。

2-4-2.png


なお、f '(x)=0のときに、極大または極小になるという原理は、ディープラーニングで用いられる「勾配降下法」に関連してくるとのことです。

ディープラーニングG検定の勉強中 その8(接線の方程式)

書籍「最短コースでわかるディープラーニングの数学」の内容に沿って勉強しています。

今回は、接線の方程式を求めますが、まずは直線の方程式から。


傾きがm、切片がbの直線の方程式は、以下の式となります。

式1
2-3-3-2.png

次に、点(p, q)を通る、傾きがm、切片がbの直線の方程式は、以下の式となります。
pはx座標の数値、qはy座標の数値なので、

2-3-3-3.png

このとき、bは以下のように置き換えることができます。

2-3-3-4.png

よって、求める方程式は以下となります。

式2
2-3-3-5.png


この式を元に、単なる直線ではなく、とある曲線の接点を通る接線の方程式にするには、
上記のp、q、mを以下のように置き換えて、

2-3-3-6.png

点(a, f(a))=接点 を通る方程式ができあがります。

式3
2-3-3-7.png


では、ここで、a=2のときの、接線の式を算出してみます。

関数のxに2を代入して、f(2) = 1
2-3-3-9.png

関数を微分して、xに2を代入して、f '(2) = 2
2-3-3-10.png

上記の値を接線の方程式に代入して、y = 2x - 3
2-3-3-11.png


それでは、関数と接線の方程式の直線をPythonを使ってグラフにしてみます。

--------------------
import matplotlib.pyplot as plt
import numpy as np

def main():
 x = np.arange(0, 3.1, 0.1)
 x2 = np.arange(0, 3.1, 0.1)

 y = np.arange(-2, 3, 0.1)
 y2 = np.arange(0, 3, 0.1)

 f = x**2 -2 * x + 1  #関数の曲線
 f2 = 2 * x2 - 3    #接線の直線

 y = f
 y2 = f2

 plt.plot(x, y)
 plt.plot(x2, y2)

 plt.grid(color='0.8')
 plt.show()

if __name__ == '__main__':
 main()

--------------------
出力結果

y = x^2 - 2x +1と、y = 2x - 3のグラフ
2-3-3-1.png

どうやら正解のようです。

ディープラーニングG検定の勉強中 その7(ディーワイディーエックス)

書籍「最短コースでわかるディープラーニングの数学」の内容に沿って勉強しています。

まずは、前回の微分の公式

公式1
2-3-1-7.png

に関数を当てはめて、接線の傾きを算出してみます。

関数1
2-3-1-9.png

公式1に関数1を当てはめて計算すると、

計算結果1
2-3-1-10.png

となります。

この計算結果には、以下の公式が当てはまります。

公式2
2-3-1-11.png

つまり、関数の指数の数をxの倍数にして、xの指数を1引くと、

計算結果2
2-3-1-12.png

計算結果1と同じ結果となります。

このことの証明はこちらのサイトで確認できます。

高校数学の美しい物語(べき関数(y=x^n)の微分公式の3通りの証明)


計算結果、f'(x)=2x - 2の「xを少しだけ増加したとき」をΔx、そのときの「f'(x)の増加量」をΔyとすると、

2-3-1-13.png

と表記できますが、これをさらに簡略化すると、以下の表記となります。

2-3-1-14.png

そして、この式の読み方は、「ディーワイディーエックス」となります。


この微分の公式での上記の関数1の計算をPythonのソースにすると、以下となります。

参考サイト
Qiita(微分や微分方程式をPythonで理解する)

--------------------
import sympy as sym
sym.init_printing(use_unicode=True)

a, b, c, x, y = sym.symbols("a b c x y")

# 関数
expr = x ** 2 - 2 * x + 1

# 関数を微分
#sym.Derivative(expr)

# 微分とその結果の出力 出力結果:2x - 2
#sym.Derivative(expr).doit()

# 微分の実施、微分の式とその計算結果の出力
sym.Eq(sym.Derivative(expr), sym.diff(expr))

--------------------
出力結果
2-3-1-15.png


微分の計算と出力が1行だけ! Pythonの数学モジュールはすごいですね~

アズールレーン クロスウェーブをプレイ中 その2

PS4版の3D艦船アクションゲームをプレイしています。


ようやく第1章の4ヶ国合同演習に取り掛かったところで、
模擬戦に出てみて、

20190910-1.jpg

完全勝利したり、

デーデデーデーデ↓ーデ↑ーデー(違
20190910-2.jpg

他国のKAN-SENが挨拶したりして、

20190910-3.jpg

合同演習が今まさに始まろうとしています。

……でも、何て言うか、ちょっと会話シーンが長いかな~
PSVITAの聖魔導物語の序章を思い出しましたよ…

でもまあ、それ込みで楽しむのもまた一興というところでしょうか。

声優さんの声も可愛いし、ここはニヤニヤしながら各KAN-SENの会話を楽しみ尽くすとしましょう。

と言う感じで、

20190910-4.jpg

ストーリーが先に進みそうな予感を得つつ、プレイを続けていきます。









最近聴いた曲











HI! VEVO(とか) Vol.167

DJ Snake & Zhu - No More (Lyric Video)


静かなテンションですが、聴き入ります。





クラシック曲を忘れない Vol.67

くるみ割り人形より、「金平糖の踊り」


チャイコフスキー作曲。短いVerはこちら










ニコニコ動画のリンク


きりたん動画




レーション、いつか食べてみたい




パケットを(あまり)殺さない動画をようやく見つけた(プレイは03:20ごろから)。
うまいプレイはこちら




面白かった(語彙力



梨のチューハイ大好き

ディープラーニングG検定の勉強中 その6(微分)

書籍「最短コースでわかるディープラーニングの数学」の内容に沿って今回も進めていきます。

2-3-1 微分の定義

とある曲線のある点(座標)を通る線、しかもその点だけが触れている線のことを接線と言います。

曲線と、曲線の1点のみに接した線(接線)
2-3-1-4.png

そして、曲線には、接線が触れている点(接点)を中心に拡大を続けると、ほぼ直線と同じになる、という特徴があります。

曲線とそれを拡大した図の説明サイト
Sci-pursuit(微分とは何か? - 中学生でも分かる微分のイメージ)

では、実際の直線と、拡大すると限りなく直線に近付く曲線との違いは何か。
それは、直線にはその線上に常に同じ傾きしかないのに対し、曲線には、その接点ごとに違う傾きを持つ直線(接線)が存在するということです。

曲線と、接点の場所ごとに異なる傾きを持つ接線
2-3-1-1.png

そして、曲線上のある接点ごとの傾きを数値として表したものが「微分」です。


それで、接点ごとの接線の傾きが微分……なのはいいとして、だから、それが何?

と私も思ってしまうのですが、例えば、
x軸を時間、y軸を距離としたときに、
距離/時間で速度が算出されるのですが、この速度が上記の「傾き」に相当します。

つまり、とある事象(車のレース)において、一定時間(x秒)ごとに車が進んだ距離(yメートル)と、その比としての速度がその都度算出されるのなら、その車のレース中の挙動について、速度の観点から分析できるようになるわけです。

そして、グラフでは、とある地点での速度を、傾きを持った直線で表すのです。
ちなみに、速度の場合なら、接線の傾きが大きければ大きいほど、速いことになります(同じ時間でも、より長い距離を走るほうが速い)。


なお、2つの点(始点:x1, y1)、(終点:x2, y2)を通る直線の傾きaは、この式で算出され、

2-3-1-5.png

その直線をグラフで表すと、以下のようになりますが、

始点(5, 15) 終点(15, 35)を通る直線(y = 2x + 5) 傾き2 切片5
2-3-1-6.png

単なる直線だけではなく、曲線のとある接点を通過する接線の傾きを一般式で表すと以下のようになります。

2-3-1-7.png

2つの点を結ぶ直線の傾きという考えは同じで、始点:(x1, y1) 終点:(x2, y2)に当てはめるなら、
始点:(x, f(x)) 終点:(x+h, f(x+h)) となります。

つまり、f(x)はyを意味し、hはx2 - x1を意味しているわけです。


ところで、なぜ傾きの算出にはこの式1があるのに、

式1
2-3-1-5.png

なぜわざわざ別の一般式
式2
2-3-1-7.png

があるのかと思われるかもしれません。この違いは、
式1だと、必ずしも接線にはならない場合があるのに対し、

2-3-1-8.png

式2、つまり微分を計算するための式では

2-3-1-4.png

必ず接線になる傾きが算出される、というところにあるのです。

必ず接線が算出される理由は、式2の極限(lim h→0)にあります。
hは、つまりはxの長さ(x2-x1)なのですが、hを限りなく0に近づける(h→0)ということは、
接点に限りなく近いことを意味するのです。
そして、接点のみを通過する直線は、すなわち接線になるし、
接点を中心にグラフを拡大していくと、それは限りなく接線そのものとなるのです。


というわけで、以下pythonで、2点間を通る直線を描画するグラフのソースと微分の式による二次曲線と接線のグラフを描画するソースとなります。

参考サイト
Qiita([python]算数・数学①~関数と方程式~)
GGE清須電脳倶楽部(05.04 微分)

1.連立一次方程式で2点間を通る直線を描画する
--------------------
import numpy as np
import matplotlib.pyplot as plt
from sympy import Symbol,solve

# Figureを設定
fig = plt.figure()

# Axesを追加
ax = fig.add_subplot(111)

# x軸の目盛設定
ax.set_xticks([-10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50])

# y軸の目盛設定
ax.set_yticks([-10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50])

x1 = 5 # 始点x
y1 = 15 # 始点y
x2 = 15 # 終点x
y2 = 35 # 終点y

#直線の傾き
a = (y2 - y1)/(x2 - x1)   # yの長さをxの長さで割ると傾きが求められる
print("直線の傾きa= " + str(a))

#2点の座標から、直線の式とグラフを求める
a1 = Symbol("a1")
b1 = Symbol("b1")
ex1 = x1*a1 + b1 - y1  # 始点(x1, y1)
ex2 = x2*a1 + b1 - y2  # 終点(x2, y2)
ans = solve((ex1,ex2))
print("傾き=" + str(ans[a1]),"切片=" + str(ans[b1])) # 2点を通る一次直線の式 y = a1 * x + b1

plt.plot(x1,y1,marker="x",color="red") # 始点
plt.plot(x2,y2,marker="x",color="red") # 終点

y = ans[a1] * x + ans[b1]
print("y = " + str(ans[a1]) + "x + " + str(ans[b1]))

#グラフの描画
x = np.arange(0,20) # xの取る数値の範囲
plt.plot(x,y)  # 直線の描画
plt.plot(x1,y1,marker="x",color="red") # 始点の描画
plt.plot(x2,y2,marker="x",color="red") # 終点の描画
plt.grid()
--------------------
出力結果
直線の傾きa= 2.0
傾き=2 切片=5
y = 2x + 5

グラフ
2-3-1-6.png



2.微分の式による、様々なxの値での接線の描写
--------------------
import numpy as np
import matplotlib.pylab as plt

def numerical_diff(f, x):  #傾きを求める
 h = 1e-4 # 0.0001
 return (f(x+h) - f(x-h)) / (2*h)

def function_1(x):    #曲線を求める
 return 0.01*x**2 + 0.1*x

def tangent_line(f, x):  #接線を求める
 d = numerical_diff(f, x)
 print("接線の傾き= " + str(d))
 y = f(x) - d*x
 return lambda t: d*t + y

x = np.arange(-40.0, 40.0, 0.1)  #点描でxが値を取る範囲
y = function_1(x)
plt.xlabel("x")
plt.ylabel("f(x)")

tf = tangent_line(function_1, 5)  #x=5の接線
tf2 = tangent_line(function_1, 0)
tf3 = tangent_line(function_1, -5)
tf4 = tangent_line(function_1, 10)
y2 = tf(x)
y3 = tf2(x)
y4 = tf3(x)
y5 = tf4(x)
plt.plot(x, y) #曲線の描写
plt.plot(x, y2) #接線 x=5 の描写
plt.plot(x, y3)
plt.plot(x, y4)
plt.plot(x, y5)
plt.show()

--------------------
出力結果
接線の傾き= 0.1999999999990898
接線の傾き= 0.1
接線の傾き= -1.3877787807814457e-13
接線の傾き= 0.2999999999986347

グラフ
2-3-1-1.png


進捗状況
最短コースで分かるディープラーニングの数学
54/328ページ まで読了(16.5%)

試験まであと62日