読者です 読者をやめる 読者になる 読者になる

"機械学習","信号解析","ディープラーニング"の勉強

"機械学習","信号解析","ディープラーニング"について、それぞれ勉強しながらブログにまとめていきます。テーマは気分によってバラバラかもしれません。

TensorFlowを始める前に知っておくべきテンソルのこと

ディープラーニング 数学

 

TensorFlowとは

Googleが開発したライブラリ

TensorFlowとはGoogleが開発し、オープンソースとして公開したニューラルネットを記述するライブラリです。社内でも実際の業務に運用されており、研究から開発まで同じツールを使うことで業務を一本化しています。人工知能の最先端を行くGoogleが実際の業務に用いているということで、公開されてから爆発的に利用人口が増加しています。

 

実際にはニューラルネットワークを記述するのに特化しているというわけではなく、データ処理全般に用いることのできる仕様となっており、カバーする範囲はかなり広いです。

 

Tensorとは

Tensorとは多次元配列のこと

TensorFlowではデータをTensorとして扱い、そのFlowを制御して処理を実現させます。処理の流れを記述するのはプログラミングではアタリマエのことで、その文法自体は慣れの問題ですから良いとして、Tensorとはなんでしょうか。

 

簡単に言ってしまえば多次元配列のことです。

 

例えばベクトルデータ\bf xn個あれば、これらを下記のように並べて行列のように見ることができますね。

 

\bf X = (x_1,x_2,x_3,...,x_n)

 

f:id:s0sem0y:20161201210858p:plain

 

これは一次元配列であるベクトルを並べて、二次元配列である行列を作ったということです。

そして同じくして、このような二次元配列データXが複数あるならば、これらを並べて三次元配列を作ることができます。しかしベクトルを並べて行列にするような数式は書くことができましたが、行列を並べる数式というのは書くことができませんね。図でイメージを示すと以下のようになっています。

 

f:id:s0sem0y:20161201211428p:plain

 

当然、三次元配列を並べて四次元配列を作ることもできるわけですが、これは数式は愚か図で示すことももはやできません。イメージはなんとなくつくでしょう。

 

こういう概念をまとめて取り扱えるようにしたのがTensor(テンソル)ということだと理解しておけばいいでしょう。

 

Tensorの名前を与える

まず、二次元配列は一次元配列を並べて作ることができたのを見ました。

これらそれぞれにテンソルの名を与えましょう。

 

ベクトルを今後は1階のテンソルと呼ぶことにします。

そして行列を2階のテンソルと呼ぶことにしましょう。

当然三次元配列は3階のテンソルと呼ぶことができます。

 

ところで元をたどると、ベクトルというのはスカラー値を並べたものですから、こいつもテンソルとして扱ってしまったほうが便利です。

 

そこでスカラーのことは0階のテンソルと呼ぶことにします。

 

これで、○階のテンソルと言えば、それがどのようなデータの形をしているかが簡単に想像できるようになりました。

 

数式に落としこむ

しかし、三次元まではデータの形をそれなりに想像することができますが、それ以上はデータの形がどんなふうかなんてのは議論できません。私達は三次元空間までしか把握できないためです。

 

そこでこれらをもっと扱いやすくするために以下のように記述することにしましょう。

 

●0階テンソル

x

 

0階テンソル(スカラー)は単に何らかの値xに過ぎません。

ですからこれでいいでしょう。

 

●1階テンソル

x_i

 

1階テンソルは元々はベクトルです。何番目の成分かを指定するiを導入すれば、この1階テンソルを一般的に記述できます。

 

●2階テンソル

x_{ij}

 

2階テンソルは元々は行列です。行と列を指定するi,jがあれば2階テンソルのすべてを把握することができるはずです。これは元々は1階テンソルを並べたものですから、j個目の1階テンソルのi番目の成分だと考えることもできます。

 

●3階テンソル

x_{ijk}

 

同様に3階テンソルならば、データの形で言うならば「行と列と高さ」に相当する3つのインデックスを与えればいいでしょう。こちらも、k個目の2階テンソルのi,j成分ということになります。

 

●4階テンソル

x_{ijkl}

 

4階テンソルになると、添字にデータの形としての意味を与えることはできません(行とか列とか高さとかなんて概念は3次元までのお話です)。しかしそれは私達の理解を助けるために便宜的に用いてきた表現であって、ここまでこれば添字がもう1つ増えればl番目の3階テンソルのi,j,k成分を指定できると納得するはずです。

 

 

結局D階のテンソルならばD個の添字を持っておけば表現できるということです。

 

これはプログラマーには大変都合がいいですね。

日頃から

 

a[2][5][6]

 

などと3次元配列の要素にアクセスする文章を書いているはずです。

数学的に厳密話しはともかくとして、TensorFlowを使おうと思った時理解しておくのは、上述の通り、テンソルは多次元配列であるということで十分でしょう。

 

データとテンソル

グレースケール画像は2階テンソル

グレースケールの画像は2階のテンソルとして表現することができます。

28×28のピクセルならば一枚の画像が

 

x_{ij}   (i,j=1,...,28)

 

などとなるわけです。(言語によっては0〜27でしょう)。各i,jに何らかの値が入っており、その値がそのピクセルの黒さを指定していることになります。

 

RGB画像は3階テンソル

RGBの画像は3階のテンソルとして表現することができます。

28×28のカラー画像は

 

x_{ijk} (i,j=1,...,28) (k=1,2,3)

 

となっており、kの値が赤と緑と青の指定の役割を担います。

 

x_{12,18,1}

 

は12行18列のピクセルの赤色の濃さを表しているという形です。

 

インデックスは人間が決めていい

もちろん同じソフトウェアで解析をする限り、添字の順番は統一されている方が便利ですが、本人が認識していばどうでもいいはずです。

 

x_{ijk}

 

iが色を指定していても何も問題ありません。

順番は自由に付けてもいいのと同じように、添字に対する意味も何でもいいはずです。

 

例えばグレースケール画像x_{ij}に対して空間フィルタfを30個準備しておいて、空間フィルタに対して添字kを与え、f_kなどと表しておきましょう。

 

グレースケール画像x_{ij}に対して各フィルタf_kを通ったあとの画像は

 

y_{ijk}=f_k(x_{ij})

 

と表すことができ、二階のテンソル(画像)をフィルタの個数分だけ並べた三階テンソルy_{ijk}が獲得されます。もちろん個人が認識していれば添字の順番はy_{kij}でもいいでしょう。(普通は最後に付け足したほうが分かりやすいですが)

結局ここではkが何個目のフィルタかを指定するインデックスになっているというわけです。

 

これは畳み込みニューラルネットを扱う上では標準的な考え方になっています。

 

他にも、複数のセンサーcから信号が入ってくるとしたならば添字tでサンプリングタイムを指定し、s_{ct}などと二階のテンソルでデータを扱うことができます。

 

あるセンサーの信号を時間周波数解析したならば、各周波数fの情報が得られるので1つのセンサーの信号はs_{tf}などと二階のテンソルで表されることになり、更に複数のセンサーがあるならば、センサーのインデックスcを使ってs_{ctf}と3階のテンソルとしてまとめておくことができるでしょう。(この際の添字の順番は、どのような順序で考えたかだけの話で本質的には意味はありません。)

 

このような形で複数の電極からの信号を時間周波数解析で3階テンソルにしておき、適切な情報を抽出する研究が脳波解析では盛んです。

 

 

注意点

n階テンソルをn次元配列であると考えると良いというお話ですが、これは世の中に一般的に認知されているように思います。その結果1つ注意すべき点が出てきています。

 

普通データの次元を考えた時には次元とは、要するにデータの要素数のことを指します。

 

例えば(床面積、築年数、階数)が格納された物件のデータの次元は3次元だと言えます。しかし、これはベクトルデータ(すなわち1階のテンソル)ですから、時折データが1次元配列だと表現されるわけです。

 

画像の場合28×28のピクセルで表現されたグレースケールのデータというのは784次元であって、この各ピクセルの値が画像を特徴付けていると言えますが、これは2次元配列だと表現されることになります。

 

次元という言葉が出てきた時に、それがテンソルの階数(配列の次元)を言っているのか、データの要素数のことを言っているのかは注意が必要です。

 

そんなことはわかってるよ!ということであれば心配はありません。