HELLO CYBERNETICS

深層学習、機械学習、強化学習、信号処理、制御工学、量子計算などをテーマに扱っていきます

複素ニューラルネットワークっていうのが有るらしい

 

 

follow us in feedly

https://cdn.blog.st-hatena.com/images/theme/og-image-1500.png

 

複素数

複素数の積

複素数は実数x,yと虚数iを用いて

 

z = x + iy

 

と表せます。一つ単純な複素数の見方としては、複素数1つで2次元を表現できるということです。2つの複素数「z_1 = x_1 + iy_1」と z_2 = x_2 + iy_2の足し算は

 

z_1+z_2 = (x_1+x_2)+i(y_1+y_2)

 

と、実数と虚数が独立して計算されます。この点において、複素数は実数だけを扱うより豊かな表現になっていますが、これだけならば実数を2つ準備してベクトルとして扱うのと何ら大差ありません。

 

ベクトル{\bf x} = (x_1,y_1){\bf y}=(x_2,y_2)の和と比較すれば

 

{\bf x + y}  =  (x_1 + x_2 , y_1 + y_2)

 

であり、実数を第一成分、虚数を第二成分と対応させることで全く同等のものとして見ることができてしまいます。

 

ところが、掛け算に関して、複素数はその顕著な特性を見せます。

 

虚数ii^2=1が定義であり、普通に文字だと思って計算をしてやれば

 

z_1z_2 = (x_1x_2-y_1y_2) + i(x_1y_2 + x_2y_1)

 

となります。実数成分と虚数成分で全く形が変わっています。これがどれくらい特殊なのかを、こ仮にベクトル{\bf x} = (x_1,y_1){\bf y}=(x_2,y_2)の要素ごとの積と比較すれば

 

{\bf x} * {\bf y} = (x_1x_2,y_1y_2)

 

となっており、違いがよく分かるでしょう。

 

複素数の極形式

複素数は二次元のベクトルと和に関しては全く同等の性質を持っています。

したがって、足し算や引き算をする上では、単に二次元平面上での点を考えて、ベクトルと同じように矢印を考えてやればいいということになります。

 

一方で積に関しては明らかに異なったルールを持っていました。この複素数のルールは極形式を持って表現すると非常に分かりやすくなります。

 

極形式とは、原点からの距離と、横軸からの角度を使って点を指定する方法です。以下の図のようにrは原点からの距離であり、\thetaは実数の軸からの角度を表しています。

 

距離と角度を指定すれば平面上で点は1つに定まるため、実軸xと虚軸yを使う代わりに、こちらを使ってみようということです。

 

f:id:s0sem0y:20170715145737p:plain

 

実軸方向は「サイン・コサイン・タンジェント」を唱えれば

 

x = \cos\theta

y = \sin\theta

 

ですので、それぞれ代入してあげれば

 

z = x + iy = r\cos\theta + i rsin\theta = r(\cos\theta + i\sin\theta)

 

となります。

 

そうすると、複素数に対する「積」というのが非常に明解に分かるようになります。

複素数に対して、実数αを掛けてやると、単にr \mapsto αrとなり、点が原点から遠ざかって(あるいは近づいて)いきます。

 

f:id:s0sem0y:20170715150713p:plain

 

 

一方で虚数iを掛けると

 

z = r(-\sin\theta + i\cos\theta)

 

となり、虚軸と実軸に対してsincosが入れ替わってしまいました。しかも実軸の方には負符号のおまけ付きです。これは平面上で90度回転に相当します。

 

f:id:s0sem0y:20170715150957p:plain

 

つまり複素数の積というのは回転、拡大・縮小を自然と扱うことができる非常に便利な性質を持ち合わせているのです。これがオイラーの公式\exp(i\theta) = \cos\theta + i\sin\thetaを使えば非常に単純明快で、複素数z

 

z = r\exp(i\theta)

 

と書けるようになります。世界一美しいと称されるかの有名な式

 

e^{iπ} = -1

 

はこの複素数の持つ極形式を考えると、一目瞭然というわけです。(にしても、人間が発見してきた「負の数-1」と「ネイピア数e」と「円周率π」と「虚数i」が一挙に現れてしまうなんて誠に不思議ですね。)

 

 

複素ニューラルネットワーク

複素ニューラルネットワークの可能性

普通のニューラルネットワークは、実数のベクトル\bf xに実数の行列\bf Wを掛けて

 

\bf y = Wx

 

という線形変換を行い、シグモイド関数やReLU関数などの非線形変換を施すことを繰り返すことによって構成されます。

 

もしも、入力ベクトルや出力ベクトル、あるいは重み行列の成分に複素数を許せばもっと豊かな表現力が得られるのではないかと考えることができます。

 

この場合、ベクトルや行列の各成分に2次元の値が格納されているようなものであり、そして、その積に関する計算が、複素数ならではの特殊なものとなっており、拡大・縮小・回転を自在に操る能力を有しているというわけです。

 

通常、拡大や縮小、回転というのは行列によって操作することができます。しかし複素数では複素数という値それ1つでそれらをこなしてしまうのです。そしてそんな強力な複素数を更にベクトルに格納して行列積を考えていくとなれば、一体どれほどの表現力を有することができるのか楽しみになってきます。

 

複素ニューラルネットワークの実際

ところで、ベクトルの成分1つ1つが複素数であるというならば、D次元のベクトルには2D個の値が格納されていることになります。

 

ともなれば、複素数を使うこととニューラルネットワークの次元を2倍に増やすのと何が違うのか?という疑問も生まれてきます。実はその答えは既に話したとおり、積の特殊な性質にあります。

 

もしもニューラルネットワークの次元を単に二倍に増やしたならば、それらはあくまで同列に扱われ、何ら関係性の無いものとして学習が開始されます(もしも関連性があるとしたならば、学習の中で上手く重み付けをして見つけていくことになる)。

 

一方で複素数を利用した場合には、実数と虚数が1つずつペアになり、必ず関係性を持った状態で変換が行われていきます。その関係性は拡大・縮小・回転であり、これらは単に次元を2倍に増やすよりも、むしろ自由度を制限していることになります。

 

 

複素ニューラルネットの応用価値

自由度を制限していると思うと、「なんだ、じゃあ次元を2倍にした方が良いじゃないか!」と思うかもしれません。そんなことは断じてありません(もしそう思うならディープラーニング病である)。

 

むしろデータに対する事前知識が有るならば、本来それらを積極的に使ったほうが良いのです。大抵の場合、事前知識を上手く数式に落としこんだり、あるいは正しさの保証をすることができなかったりするため、仕方なく複雑なモデルで学習による力任せな解決を測ることになります。

 

複素ニューラルネットが有用性を示すために必要な、データに対する事前知識とは、「データが波形であること」です。例えば音声、例えば光、例えば脳波など、振幅と位相によって何らかの物理的な意味を持つものは、複素数で表現すると大変都合が良いのです。

 

単なる一次元信号を複素数で表現することを決めれば、大きさrと角度\theta(すなわち振幅と位相)を考慮することができるというわけです。これは大変素晴らしい(というかフーリエ変換を知っている人は式を思い出してください)。

 

 

他にも振幅と位相という物理的な意味を見出だせない場合でも可能性はあります。虚軸と実軸はいつでも直交していることに注目してください。和に関して必ず別々の扱いがされているのです。

 

内在的に、別々に独立して意味を持ちうるデータがあったとすれば、それらは最終的に虚軸と実軸にそれぞれ振り分けられるように、上手くニューラルネットが重み付けをしてくれる可能性もあります。

 

ただし、これに関しては確かに普通のニューラルネットでもできることです。ただし、ニューラルネットの各成分の対に、意図的に直交性を常に要求し続けるなど至難の業です(確実に損失関数がグチャグチャになるでしょう)。もちろんデータが本質的に直交分解されるべきであるならば、学習によってそれが獲得される可能性はありますが、そこに至るまでの時間は大きく変わってくるだろうと予想できます。

 

活性化

複素数zが格納されたベクトル{\bf z} = (z_1,z_2,...)に対して活性化関数を作用させる方法が2通り考えられます。実数同様に、要素ごとに活性化を行うのは良いのですが、複素数の場合、1つの成分がz_k = x_k + iy_kと実部と虚部に関する2つの値を有しているため、問題となるわけです。

 

まずは虚軸と実軸に対して別々に活性化を行う方法です。この場合、虚軸と実軸に対して個別にスケール変換が行われることになります。

 

f:id:s0sem0y:20170715155531p:plain

 

数式上では

 

f(z_k) = f(x_k) + if(y_k)

 

となります。

 

もう1つが、極形式における大きさrに対してのみ作用させる方法です。

 

f:id:s0sem0y:20170715155729p:plain

 

数式上は

 

f(z_k) = f(r) \exp\theta

 

とする方法です。

 

 

両者の決定的な違いは、活性化関数が位相\thetaに変化をもたらすのか否か、という点と、極形式での活性化関数の引数rが「負にならない」という点です。

 

複素数の正負を決めているのは、極形式では位相の方であって、rは常に正です。したがってReLUなどの活性化関数は単なる恒等変換のように振る舞うことになります。

 

最後に

まだ複素ニューラルネットワークは私自身、手を付け始めたばかりです。記事上に不正確な表現も有るかもしれませんが、お許しを…。

 

複素ニューラルネットに関する論文

[1602.09046] On Complex Valued Convolutional Neural Networks

[1705.09792] Deep Complex Networks

[1511.06351] Learning Representations Using Complex-Valued Nets

 

 

 

複素ニューラルネットワーク(第2版) 2016年 06 月号 [雑誌]

複素ニューラルネットワーク(第2版) 2016年 06 月号 [雑誌]