深層学習の畳み込み層の処理は「畳み込み」じゃなかった件
畳み込み層の処理は厳密には畳み込みではなかったのか・・・
畳み込み層
数学で言うところの畳み込み
畳み込みの定義
2次元の畳み込みは次のように定義されています。
離散値の場合は行列で表現できて
となります。
畳み込み層の処理と比較
(1)と(3)は非常に似てますが、(1)では、(3)ではとなっていて、添え字が違うことに気付きます。
実は(1)の処理は相互相関(cross-correlation)と呼ばれていて畳み込みとは別物です。
相互相関
相互相関と畳み込みの相違点
まずは相互相関と畳み込みの違いを見ます。
以後、簡単のために1次元実数値連続関数を扱います。
1次元実数値連続関数の畳み込み
1次元実数値連続関数の相互相関
((5)の関数が実数値でない場合はの代わりに複素共役を取る必要がある。)
交換律
畳み込みの重要な性質の一つとして交換律があります。
ここでとすると
\begin{align}
(f*g)(a) &= \int_{-\infty}^{\infty} g(a-x)f(x)dx\\
&= \int_{\infty}^{-\infty} g(x')f(a-x')d(a-x')\\
&= \int_{\infty}^{-\infty} g(x')f(a-x')d(-x')\\
&=\int_{-\infty}^{\infty} f(a-x')g(x')dx' = (g*f)(a)
\end{align}
つまり、
と言う交換律が成り立つことがわかります。
しかし、(5)の相互相関の形では交換律は満たしません。
フーリエ変換
畳み込みのフーリエ変換がそれぞれの関数のフーリエ変換の積になってるは有名な定理で、工学などでもよく応用されます。
\begin{align}
F[f*g] &= \int_{-\infty}^{\infty}\left(\int_{-\infty}^{\infty} g(a-x)f(x)dx\right)e^{-ika}da\\
&= \int_{-\infty}^{\infty}\int_{-\infty}^{\infty} g(a')f(x)e^{-ik(a'+x)}dxda'\\
&=\int_{-\infty}^{\infty}f(x)e^{-ikx}dx \int_{-\infty}^{\infty}f(a')e^{-ika'}da' \\
&= F[f] F[g]
\end{align}
式変形の二行目ではとした。
これを相互相関でやると
\begin{align}
F[f\star g] &= \int_{-\infty}^{\infty}\left(\int_{-\infty}^{\infty} g(a+x)f(x)dx\right)e^{-ika}da\\
&= \int_{-\infty}^{\infty}\int_{-\infty}^{\infty} g(a')f(x)e^{-ik(a'-x)}dxda'\\
&=\int_{-\infty}^{\infty}f(x)e^{+ikx}dx \int_{-\infty}^{\infty}f(a')e^{-ika'}da' \\
&= F^{*}[f] F[g]
\end{align}
ここではとした。
フーリエ変換の複素共役を取ったものとフーリエ変換に積になっています。(クロススペクトルと言う。)
非常に似た形をしてますが性質の相違点はいくつかあるようです。
相互相関の意味
相互相関の意味ですが、座標aでの二つの関数の類似度を表しています。似てるほど相互相関は大きくなります。
例えば、ノイズに混ざった二つの信号があった場合に相互相関を使ってそれが同じ信号かどうか判断できます。
(参考: https://qiita.com/inoory/items/3ea2d447f6f1e8c40ffa)
また、相互相関の性質を利用してフィルターなのども出来ます。
import numpy as np import matplotlib.pyplot as plt sig = np.repeat([0., 1., 1., 0., 1., 0., 0., 1.], 128) sig_noise = sig + np.random.randn(len(sig)) corr = np.correlate(sig_noise, np.ones(128), mode='same') / 128 clock = np.arange(64, len(sig), 128) fig, (ax_orig, ax_noise, ax_corr) = plt.subplots(3, 1, sharex=True) ax_orig.plot(sig) ax_orig.plot(clock, sig[clock], 'ro') ax_orig.set_title('Original signal') ax_noise.plot(sig_noise) ax_noise.set_title('Signal with noise') ax_corr.plot(corr) ax_corr.plot(clock, corr[clock], 'ro') ax_corr.axhline(0.5, ls=':') ax_corr.set_title('Cross-correlated with rectangular pulse') ax_orig.margins(0, 0.1) fig.tight_layout() fig.show()
出力
畳み込み層に「畳み込み」を適応するとどうなるのか?
畳み込み層に「畳み込み」を適応するとどうなるのか?
結論から言うと何も問題ないです。ニューラルネットワークの層で相互相関と畳み込みの相違点は関係ありません。
ただカーネルの上下左右を反転して学習してるだけです。(このカーネルをフリップカーネルと言います。)
図2の様にインプットのラベルを−1から始めてカーネルを反転すると畳み込みの式と一致してることがわかると思います。
終わりに
な ぜ Convolutional と 名 付 け た し。
まあ、ただの名前だし、数学の用語が誤用されることはよくあることなのであまり気にしても仕方ないね。
notebookはここに置いときますね。
github.com
ツイッターやっているのでフォローお願いします!
↓今すぐフォローすべきキラキラ アカウント
じゃあの。