はじめに
今回は「テンソルネットワークの入り口」の2回目として、実際に深層学習に応用した例を紹介したい。今回のソースコードはここにある。
深層学習への応用
Googleの出しているテンソルネットワークのフレームワークTensorNetworkと、深層学習フレームワークTensorFlowを用いて、画像分類を行う。データセットはFashion-MNISTである。訓練データ数は60000、テストデータ数は10000、画像サイズは28
28である。
テンソルネットワークを考える前のニューラルネットワークの構造は以下の通り(src/main_2.py)。
全結合層だけを用いた構成である。入力画像のサイズは
であり、これをベクトルに引き延ばした
次元ベクトルが入力となる。一番最初(3行目)の全結合層を式で書くと
![]()
となる。ここで、
は
次元ベクトル、
は
次元ベクトル、
は
行列、
は
次元ベクトルとなる。上式を成分で書くと
(1) ![]()
となる(アインシュタイン縮約記法を用いた)。図で示すと以下のようになる。

図7
さて、これをテンソルネットワークで表すため天下り的ではあるが以下のように書き換える。

図8
つまり、1階テンソル
を2階テンソル
に変更し、
を点線の矩形内に示した2つのテンソルの積(MPS)に置換する。式で書くと
(2) ![]()
となる。
の次元を
としたので、
を
の行列とすることができる。先の説明では、MPSに置き換える際に特異値分解を用いた。上の表式に現れる
は学習により決まる行列であるから特異値分解を適用することはできない。そこで、
も学習から決まるテンソルとみなす。以上を実現するコードが以下である(src/tensor_network_layer_for_mnist.py)。このコードはTensorNetworkの公式が公開しているサンプルプログラムからの流用である。
4行目のtensornetworkがテンソルネットワークのモジュールである。8行目から12行目までの変数名は式(2)周辺で用いた変数名と一致させている。20行目のself.a_varが
に、23行目のself.c_varが
に、26行目のself.baisが
に相当する。40行目から65行目までのコードが式(2)の計算に対応する。tensornetworkの使い方に関しては公式のチュートリアルを見てほしい。
最初に示した全結合層だけのネットワーク構造の中の最初の層だけを上のクラスのインスタンスで置き換える。
3行目がテンソルネットワークで置き換えた層である。それ以外の層は変えていない。さて、パラメータの保存に必要なメモリ量を第1層について計算してみる。式(1)の右辺の成分の総数
は、
であるから行列
の要素数が
、
の要素数が512となり、これらを足し合わせて
となる。一方、式(2)の右辺のパラメータの総数
は、
の次元を
とすると、
の成分数が
、
の成分数が
、
の成分数が
なのでこれらを足し合わせて
となる。
のときメモリ量を節約できることになる。この式を評価すると
であれば良いことになる。今回の計算では
とした。従って
となり大幅な削減を実現できる。以下に計算結果を示す。

図9
精度を維持しつつ(少し良くなっている)、ネットワーク容量を圧縮できた。
まとめ
今回は、テンソルネットワークを使うことで、精度を維持しつつニューラルネットワークのパラメータ数を大幅に減らすことができることを見た。全結合層以外へのテンソルネットワークの応用についても今後調べたい。