今日、Caffeというナウいニューラルネット実装を読んでいたら次の行で???となりました。

https://github.com/BVLC/caffe/blob/v0.9/src/caffe/layers/bnll_layer.cu#L20

数式で書くと(logは自然対数)

\[f(x)=\begin{cases} x+\log(1+e^{-x}) & \text{if}\,x > 0, \\ \log(1+e^x) & \text{otherwise}. \end{cases}\]

もっとオシャレに書くと

\[f(x)=\max(0, x)+\log(1+e^{-\vert x\vert}).\]

これが数値計算的なテクニックなのか、近似も含んでるのか、僕が知らないactivation関数なのかパッと見判断つかなかったのですが、微分してみたら両方シグモイド関数になりました(で、よく見たらすぐ下に導関数の実装も書いてあった)。 まず滑らかなのかこれ、というところでちょっと驚く。

さて、シグモイドを導関数に持つのは、softplusと呼ばれる関数です(これも忘れててしばらく考えてた)。

\[\text{softplus}(x)=\log(1+e^x).\]

これはRectified linear Unit (ReLU) とかpositive partと呼ばれる式 $\max(0, x)$ と似た性質を持っていて、かつ滑らかで勾配が(厳密には)消えない関数としてニューラルネット界隈で時々使われます。 つまり上の式はsoftplus関数なのでした。

実際、softplus関数にlogsumexpでやるような大きなexpの追い出しをやると $x>0$ における最初の式が導出できます。

\[\log(1+e^x)=\log(e^x(e^{-x}+1))=x+\log(1+e^{-x}).\]

当たり前ですが頑張ればもとの(オシャレな方の)式からsoftplusを導出することもできます。positive partとnegative partが出てきてちょっと面白い(個人の感想です)。

\[\begin{align*} \max(0, x)+\log(1+e^{-\vert x\vert}) &=\log(e^{\max(0, x)}(1+e^{-\vert x\vert}))\\ &=\log(e^{\max(0, x)}+e^{\max(0, x)-\vert x\vert})\\ &=\log(e^{\max(0, x)}+e^{\min(0, x)})\\ &=\log(1+e^x). \end{align*}\]

気づいてしまえばそうなんですが、最初softplus関数のことが頭になかったので、しばらく考えてしまいました。 数値計算テクむずい。

さて、するとこの式はReLUとsoftplus関数の差を表す式ということになります。

\[\text{softplus}(x)-\max(0, x)=\log(1+e^{-\vert x\vert}).\]

右辺の関数 $\log(1+e^{-\vert x\vert})$ をプロットしてみると次のようになります。

Softplus(x) - ReLU(x)

式から明らかですが、僕のぱっと見の想像と違ってSoftplusとReLUの差は左右対称な形をしていました。