JavaScript の Generator

JavaScript でも Generator が書けるということを最近知った。 備忘録として。

  • function * で定義された関数(Generator 関数)は、Generator オブジェクトを返す。
  • Generator#next() を実行すると、Generator 関数の先頭から最初の yield まで実行される。
  • さらに Generator#next() を実行すると、前回実行された yield からその次の yield までが実行される。 以下繰り返し。


  • Generator は、for-of で反復できる。


  • yield *と書くと、反復可能なオブジェクトの要素を1つずつ返すようになる。

広告を非表示にする

心身の不調

ここ最近、少しおかしくなっていた気がする。

今週に入った頃から、なぜか強い怒りを溜め込むことがしばしばあった。 普段はさして気にも留めないであろう些細なことに対しても非常に過敏になり、突発的に胸の奥が沸き立つような感覚に陥って無意識に歯を食い縛ることが多々あった。

特に今朝は酷かった。 うまく形容できないのだが、会社に行く途中からずっと胸を抉られるような強い不快感に襲われていた。 あるいは、灼熱の火球が胸の奥深くで燻り、じわじわと精神力を奪われるような感覚とでも言うべきか。 ひょっとしたら脳が勝手に極度の緊張(興奮)状態に陥ったのかも知れない。 なんとも大げさな表現になってしまうが、そうとしか言いようがないので仕方ない。

会社に着いてしばらくすると頭痛や寒気などの症状まで現れ、いよいよ仕事どころではなくなった。 本格的にまずいと思い、やむなく会社を早退した。

帰宅後すぐに横になり、そのままひとしきり眠った。 夢も見ず、かなり深い眠りの底に落ちた。

今はいくぶん回復し、胸の内にあった火球のような燻りも落ち着いたような気がする。

休息と睡眠が心身のバグを取ってくれたのだろうか。

つづく

広告を非表示にする

双曲線正接関数とその微分

双曲線正接ハイパボリックタンジェント関数

前回のシグモイド関数に続き、ニューラルネットワークの活性化関数でよく用いられる双曲線正接関数のお話です。

双曲線正接関数の定義を 式  (1) に示します。

 
\begin{align}
\displaystyle
\tanh (x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} \tag{1}
\end{align}

ちなみにこの双曲線正接関数は、三角関数正接  \tan (x) の定義(式  (2))とよく似ているので、このような名前になっています。

 
\begin{align}
\displaystyle
\tan (\theta) = \frac{e^{i \theta} - e^{-i\theta}}{i \left( e^{i \theta} + e^{-i \theta} \right) } \tag{2}
\end{align}

余談ですが、式  (2) は、高校で教わった定義  \tan (\theta) = \frac{\sin (\theta)}{ \cos (\theta)} とはずいぶん雰囲気が違います。 中身は同じはずなのに、なぜか得体の知れない複素数  i が紛れ込んでおり、実に奇妙です。

大学の微分の授業で「テイラー展開」を学んだ際に、 \tan (\theta ) を 式  (2) の形で記述できることを教わった覚えがありますが、当時の僕は(今もだけど)こんな式を見ても何物なのかまったく想像がつきませんでした(今もだけど)。

そこで、本題に入る前にちょっと横道に逸れて、オイラーの公式  e^{i \theta} = \cos ( \theta ) + i \sin (\theta) を出発点にして、 \tan (\theta) = \frac{e^{i \theta} - e^{-i\theta}}{i \left( e^{i \theta} + e^{-i \theta} \right) } を導出してみましょう。

導出:  \tan (\theta) = \frac{e^{i \theta} - e^{-i\theta}}{i \left( e^{i \theta} + e^{-i \theta} \right) }

 
\begin{align}
\displaystyle
e^{i \theta} &= \cos ( \theta ) + i \sin (\theta) \tag{3}
\end{align}

 (3) \theta に、改めて  -\theta を代入すると以下を得ます。
 
\begin{align}
\displaystyle
e^{-i \theta} &= \underbrace{ \cos (- \theta) }_{\cos (\theta ) } + i \underbrace{ \sin (- \theta) }_{- \sin (\theta)} \\
 &= \cos (\theta) - i \sin (\theta ) \tag{4}
\end{align}

 (3), 式  (4) から、 \cos (\theta) \sin (\theta ) をそれぞれ求めます。
 
\begin{align}
\require{cancel}
\displaystyle
e^{i \theta} + e^{-i \theta}  &= \cos ( \theta ) + i \sin (\theta) +  \cos (\theta) - i \sin (\theta ) \\
&= \cos ( \theta ) + \cos ( \theta ) + \cancel{ i \sin (\theta) - i \sin (\theta)} \\
&= 2 \cos ( \theta ) \tag{5} \\
\cos(\theta) &= \frac{e^{i \theta} + e^{-i \theta}}{2} \tag{6} \\
e^{i \theta} - e^{-i \theta}  &= \cos ( \theta ) + i \sin (\theta) - \left(  \cos (\theta) - i \sin (\theta ) \right) \\
 &= \cancel{ \cos ( \theta ) -  \cos (\theta)} + i \sin (\theta) + i \sin (\theta ) \\
 &= 2i \sin(\theta) \tag{7} \\
\sin(\theta ) &= \frac{e^{i \theta} - e^{-i \theta}}{2i} \tag{8}
\end{align}

あとは、上の式  (6), 式  (8) を高校で習った定義  \tan (\theta) = \frac{\sin (\theta)}{ \cos (\theta)} に代入すればおしまい。
 
\begin{align}
\require{cancel}
\displaystyle
\tan (\theta ) &= \frac{\sin (\theta ) }{ \cos (\theta)} \\
&= \frac{e^{i \theta} - e^{-i \theta}}{\cancel{2}i} \! \cdot \! \frac{\cancel{2}}{e^{i \theta} + e^{-i \theta }} \\
&= \frac{e^{i \theta} - e^{-i\theta}}{i \left( e^{i \theta} + e^{-i \theta} \right) } \tag{9}
\end{align}

めでたし。

で、ここまでは前置き。 今日のテーマは双曲線正接関数を微分することです。

本編と 1ミリも関係ない三角関数の話でこの記事の半分以上を浪費してしまいました。

双曲線正接関数の微分

前回のシグモイド関数よりも素性のよい関数なので、商の微分公式  \left( \frac{f}{g} \right)' = \frac{f' \cdot g - f\cdot g'}{g^2} を使うだけで導関数を求められます。

 
\begin{align}
\require{cancel}
\displaystyle
\tanh' (x) &= \left( \frac{e^x - e^{-x}}{e^x + e^{-x}} \right)' \\
&= \frac{ \left( e^x - e^{-x} \right)' \cdot \left(  e^x + e^{-x} \right) - \left( e^x - e^{-x} \right) \cdot \left(  e^x + e^{-x} \right)'  }{\left( e^x + e^{-x} \right)^2} \\
&= \frac{ \left( e^x + e^{-x} \right) \cdot \left(  e^x + e^{-x} \right) - \left( e^x - e^{-x} \right) \cdot \left(  e^x - e^{-x} \right)  }{\left( e^x + e^{-x} \right)^2} \\
&= \frac{ \left[ \left( e^x \right)^2 + 2 e^{x} e^{-x} + \left(e^{-x} \right)^2 \right]  - \left[ \left( e^x \right)^2 - 2e^{x}e^{-x} + \left( e^{-x} \right)^2  \right] }{\left( e^x + e^{-x} \right)^2} \\
&= \frac{  \left( e^x \right)^2 + 2 \cancel{ e^{x} e^{-x} } + \left(e^{-x} \right)^2  -  \left( e^x \right)^2 + 2 \cancel{ e^{x}e^{-x}} - \left( e^{-x} \right)^2   }{\left( e^x + e^{-x} \right)^2} \\
&= \frac{ 2 + 2 +  \cancel{ \left( e^x \right)^2 - \left( e^x \right)^2 } + \cancel{ \left( e^{-x} \right)^2 -\left( e^{-x} \right)^2 }  }{\left( e^x + e^{-x} \right)^2} \\
&= \frac{ 4 }{\left( e^x + e^{-x} \right)^2} \tag{10}
\end{align}

以上。 簡単でした。

シグモイド関数とその微分

シグモイド関数

今日は、こんな関数について考えます。

 
\begin{align}
\displaystyle
\sigma (x) &= \frac{1}{1 + e^{-x}} \tag{1}
\end{align}

機械学習の分野では、しばしばニューラルネットワークの活性化関数などに利用されています。 その手の古典的な参考書では必ず言及されるほど有名な関数です。

このシグモイド関数微分すると、ふしぎなことに導関数が以下のような再帰っぽい形になります。

 
\begin{align}
\displaystyle
\sigma'(x) = \sigma(x) \left(  1- \sigma(x) \right) \tag{2}
\end{align}

というわけで今回は、このシグモイド関数をだらだら微分してみようと思います。 何番煎じだろうか。

てきとう導出

Step 1

 (1) をそのまままるごと微分するのは骨が折れるので、いったん計算しやすい関数に分解します。

 
\begin{align}
\displaystyle
\sigma &= f(t) = t^{-1} \tag{3} \\
t &= g(u) = 1 + e^{u} \tag{4} \\
u &= h(x) = -x \tag{5}
\end{align}

すなわち  \sigma (x) を、 f(t),\, g(u),\, h(x) による合成関数  \sigma = f(\,g(\,h(x))) とみなします。

ちなみに、順番に代入してけば、ちゃんと元の  \sigma (x) に戻ります。
 
\begin{align}
\displaystyle
\sigma &= t^{-1} = \frac{1}{ \underbrace{t}_{g(u)}} = \frac{1}{ \underbrace{g(u)}_{1+e^{u}}} \\
 &= \frac{1}{1+e^{\underbrace{u}_{h(x)}}} = \frac{1}{1+e^{\underbrace{h(x)}_{-x}}}  \\
 &= \frac{1}{1+e^{-x}} \tag{6}
\end{align}

Step 2

次に、さきほどの  f(t),\, g(u), \, h(x) それぞれについて導関数を計算します。

それぞれ十分にかんたんな形まで分解されているので、計算に窮することはないと思います。
 
\begin{align}
\require{cancel}
\displaystyle
f'(t) &= \left( t^{-1} \right)' \\
&= -t^{-2} \tag{7} \\
g'(u)& = \left( \cancel{1} + e^{u} \right)' \\
&= e^{u} \tag{8} \\
h'(x) &=  (-x)'  \\
&= -1  \tag{9}
\end{align}

Step 3

あとは合成関数の微分公式より  
\displaystyle
\begin{align}
\sigma'(x) &= f'(t) \cdot g'(u) \cdot h'(x) 
\end{align}
となるため*1シグモイド関数  \sigma(x)導関数は以下のように計算できます。 途中式をなるべく省かずに書きました。

 
\displaystyle
\require{cancel}
\begin{align}
\sigma'(x) &=  \underbrace{f'(t)}_{-t^{-2}} \cdot \underbrace{ g'(u) }_{e^{u}}  \cdot \underbrace{ h'(x) }_{-1} \\
&= - \! \! \left. \underbrace{t}_{1 + e^{-x}} \right. \! \! ^{-2}  \cdot  \underbrace{ e^{u} }_{e^{-x}}  \cdot  \left( -1 \right) \\
&= \cancel{-} \left( 1 + e^{-x} \right)^{-2} \cdot e^{-x} \cdot ( \cancel{-1} ) \\
&= \frac{e^{-x}}{ \left( 1 + e^{-x} \right)^2} \\
&= \frac{e^{-x}}{ \left( 1 + e^{-x} \right) \left( 1 + e^{-x} \right) } \\
&= \frac{e^{-x}}{ 1 + e^{-x} } \cdot \underbrace{ \frac{1}{ 1 + e^{-x} } }_{\sigma (x)} \\
&= \frac{e^{-x}}{ 1 + e^{-x} } \cdot \sigma(x) \\
&= \frac{e^{-x} + (1 - 1)}{1 + e^{-x}} \cdot \sigma(x) \\
&= \frac{\left( e^{-x} + 1 \right) - 1}{1 + e^{-x}} \cdot \sigma(x) \\
&= \Bigl( \underbrace{ \frac{e^{-x} + 1 }{1 + e^{-x}} }_{1} - \underbrace{ \frac{ 1}{1 + e^{-x}} }_{\sigma(x)} \Bigr) \sigma(x) \\
&= (1 - \sigma(x) ) \sigma(x) \tag{10}
\end{align}

以上。

*1:合成関数の微分公式より  
\begin{align}
\frac{\mathrm{d} \sigma}{\mathrm{d}x} = \frac{\mathrm{d} \sigma}{\mathrm{d} t} \! \cdot \! \underbrace{ \frac{\mathrm{d} t}{\mathrm{d} x} }_{ \frac{\mathrm{d} t}{\mathrm{d} u}  \cdot  \frac{\mathrm{d} u}{\mathrm{d} x}  } = \frac{\mathrm{d} \sigma}{\mathrm{d} t} \! \cdot \!  \frac{\mathrm{d} t}{\mathrm{d} u}  \! \cdot \!  \frac{\mathrm{d} u}{\mathrm{d} x} 
\end{align}

合成関数の微分

なにかに使えるかも知れないので、あらためて復習してみる。

合成関数の微分

1変数関数の場合

 y = f(t),\, t=g(x)から成る合成関数  y = f(g(x))微分:

 \begin{align}
\displaystyle 
\dfrac{\,\mathrm{d} y\,}{\mathrm{d} x} = \dfrac{\,\mathrm{d} y\,}{\mathrm{d} t} \! \cdot \! \dfrac{\,\mathrm{d} t\,}{\mathrm{d} x}
\end{align}


かなり適当な導出:*1
Step 0
関数  y = f(x)微分の定義を、以下に示します。
 
\begin{align}
\displaystyle \frac{\mathrm{d}y}{\mathrm{d}x} = \lim_{\Delta x \rightarrow 0} \frac{f(x + \Delta x) - f(x)}{\Delta x}
\end{align}

Step 1
改めて  y = f(t),\, t=g(x)から成る合成関数の微分を考えましょう。 まず微分の定義より、以下を得ます。
 
\begin{align}
\displaystyle 
\dfrac{\,\mathrm{d} y\,}{\mathrm{d} x} = \lim_{\Delta x \rightarrow 0} \dfrac{ f( g(x + \Delta x)) - f(g(x)) }{ \Delta x}
\end{align}

Step 2
次に  g(x + \Delta x) = g(x) + \Delta t と置き、さらに  \Delta t について解きます*2
 \begin{align}
\Delta t = g(x + \Delta x) - g(x)
\end{align}

極限を取ると
 
\begin{align}
\displaystyle
\lim_{\Delta x \rightarrow 0} \Delta t = \lim_{\Delta x \rightarrow 0} \bigl[ g(x + \underbrace{\Delta x}_{0}) - g(x) \bigr] = 0
\end{align}
すなわち、 \Delta x \rightarrow 0 のとき  \Delta t \rightarrow 0 となります。

Step 3
さらに  g(x) = t と置き、以下のように式変形を行うことにより  \frac{\,\mathrm{d} y\,}{\mathrm{d} x} = \frac{\,\mathrm{d} y\,}{\mathrm{d} t} \! \cdot \! \frac{\,\mathrm{d} t\,}{\mathrm{d} x} を得ます。
 
\begin{align}
\displaystyle 
\dfrac{\,\mathrm{d} y\,}{\mathrm{d} x} &= \lim_{\Delta x \rightarrow 0} \dfrac{ f( \overbrace{g(x + \Delta x)}^{ g(x) + \Delta t}) - f(g(x)) }{ \Delta x} \! \cdot \! \underbrace{ \dfrac{\, \Delta t \,}{\Delta t} }_{1} \\
 &= \lim_{\Delta x \rightarrow 0 \\ (\Delta t \rightarrow 0)} \dfrac{ f( \overbrace{g(x)}^{t} + \Delta t)) - f(\overbrace{g(x)}^{t}) }{ \Delta t} \! \cdot \! \dfrac{\,\Delta t\,}{\Delta x}\\
&=  \lim_{\Delta x \rightarrow 0 \\ (\Delta t \rightarrow 0)} \dfrac{ f( t + \Delta t)) - f(t) }{ \Delta t} \! \cdot \! \dfrac{\overbrace{\, \Delta t \,}^{g(x + \Delta x) - g(x)}}{\Delta x}\\
&= \underbrace{ \lim_{\Delta t \rightarrow 0} \dfrac{ f( t + \Delta t)) - f(t) }{ \Delta t} }_{\frac{\mathrm{d}y}{\mathrm{d}t}} \! \cdot \! \underbrace{ \lim_{\Delta x \rightarrow 0} \dfrac{g(x + \Delta x) - g(x)}{\Delta x} }_{\frac{\mathrm{d}t}{\mathrm{d}x}}
\end{align}

多変数関数の場合

 z = f(t_1,\, \cdots ,\, t_n),\, t_i =  g_i (x_1,\, \cdots ,\, x_m) から成る合成関数  z偏微分:

 
\begin{align}
\displaystyle
\dfrac{\partial z}{\partial x_{k}} &= \dfrac{\partial f }{\partial t_{1}} \! \cdot \! \dfrac{\partial t_{1}}{\partial x_{k}} + \cdots + \dfrac{\partial f }{\partial t_{n}} \! \cdot \! \dfrac{\partial t_{n}}{\partial x_{k}} \\
&= \sum_{i = 1}^{n}\dfrac{\partial f }{\partial t_{i}} \! \cdot \! \dfrac{\partial t_{i}}{\partial x_{k}}
\end{align}

*1:この導出は、厳密には不正確です。 g(x) が定数関数の場合、常に  \Delta t = 0 となるため、計算の途中でゼロ割りが発生してしまうためです。

*2:単に移項しただけです。

広告を非表示にする

このお仕事をやっててよかった

先日、お客様から高い評価をいただきました∩( ・ω・)∩

色々おこられることも多いですが、僕の作ったプラグラムがお客様に喜んでいただけると、このお仕事をやっててよかったな…と思うのです(´▽`*)

高校時代の友人と

今日(というか昨日)は高校時代の友人と長電話をしました。

 

僕は寂しがり屋な割に友達が少ないので、たまにこういう機会があると嬉しくて仕方ないのです。

 

彼とまともに話すのは、かれこれ7年ぶり。懐かしい思いもありましたが、それ以上に、彼が公私ともにそれなりに責任のあるポジションに就いていたことが驚きでした。

 

責任あるポジションに就けば、それだけ苦労も増えるでしょう。にも関わらず、彼はいきいきと自分の有りようを語るのです。

 

他愛のない会話でしたが、それは上司の言葉よりも心に沁み込むようでした。

広告を非表示にする