はじめに
今や登場当初の状態で使われることはなくなった自己符号化器(オートエンコーダ)ですが、確率的なモデルとして今も生き続けています。今回はそんな自己符号化器の動作の中身を見てみたいと思います。
自己符号化器
簡単な紹介
自己符号化器は特徴抽出(あるいは次元圧縮)をニューラルネットワークで行います。
以下の記事でも述べている通り、主成分分析と関係が深く、ニューラルネットを利用することで非線形や多層化への拡張が容易となっています。
事前学習(特徴抽出)
自己符号化器で特徴抽出を行う場合は、入力に対して以下のようなニューラルネットの出力を考え
を求めることで、出力自体が入力と同等になるようなニューラルネットを構築します。
その後
のみを取り出すことで、入力自体を復元することのできる表現が作り出すことができます。
その後、このニューラルネットを特徴抽出器として用いるか、あるいは、同様の処理を繰り返して層を更に追加した積層自己符号化器にしたり、層を追加して教師あり学習を行うことで分類器を構築したりできます。
層を追加して教師あり学習(ファインチューニングという)を行うと、自己符号化器を構築した際の表現は一般には失われます。なぜなら、あくまで分類を行うために都合の良い学習を行うのが目的で、が必ずしも分類に最適な表現とは限らないためです。
中間表現の変化
生データ
生データは4次元(Irisデータ)のベクトルです。
可視化ができないので、便宜的に第1成分と第2成分のみをクラスごとに色分けしてプロットします。
もともとある程度クラスごとに別れてはいますが、これを直接分類するのはまだ難しいかもしれません。(ただ、本来は4次元のデータであるため、違う成分(軸)から見たら、もっとはっきり別れて見えるかもしれない)
事前学習による符号化
以下の式に従い符号化を行います。
は4次元を2次元に変換する行列で、[\bf tex:W']が2次元を4次元に変換する行列です。上記のニューラルネットの出力がを再現できるということは、中間層における4次元から2次元への変換(次元圧縮)では、復元出来るだけの十分な情報を保持したまま次元を圧縮したということになります。
試しに学習させてみると二次元の中間表現
は以下のようにプロットされました。
データが持ちうる本来の情報のみを残した場合、生データよりもはっきりと分類に有利な様子がわかります。このように次元圧縮はデータの可視化に非常に役立つ技術です。
ファインチューニングによって変化した中間表現
事前学習によって獲得した以下の自己符号化器
に対して、新たに2次元から3次元への変換を行う行列を準備して分類のためのソフトマックス層を追加します。
この状態で教師あり学習を行うと、のすべてが学習によって更新されます。従って、中間表現の方も変化をきたします(事前学習で得られたパラメータは初期値という扱い)。ファインチューニング後の中間表現は以下のようになっていました。
分類を行うために必要最小限の配置になっています。学習を続けていった場合は、もしかしたらほぼ直線上に並ぶようなことになるかもしれません(分類できさえすればいい)。
ファインチューニングで中間表現が変わりすぎることを防ぐ
事前学習により得られた自己符号化器自体に意味がある場合があります。
いくら分類が目的だとしても、事前学習のパラメータが完全に破壊され、過学習という結末に陥る可能性もあります。事前学習のパラメータに意味がありそうだと思えるならば、なるべくパラメータを破壊しない範囲で、分類をうまくできるように学習を進めたいところです。
そのような場合、事前学習で用いた自乗誤差損失を、ファインチューニングの際にも反映させるという方法を取ることができます。
簡単にネットワーク構造を図示すると以下のような形。
自己符号化器を雑音除去自己符号化器に変えたり、更に多層化してすることで性能のアップをはかることができます。またバッチ正規化などを導入することで更に過学習を防ぐことが可能になるでしょう。
これらをゴリゴリに応用したものが「ladder network」だと言えます。
全結合型のいわば普通であるにも関わらず(様々な工夫はありますが)、畳み込みニューラルネットよりも画像認識で一時期高い性能を持った構造です。
後に畳み込みニューラルネットに同様の構造が入れられ拡張が図られました。
事前学習の初期値を生かしたままファインチューニング(Chainer)
まずは下記の構成で自己符号化器を学習させます。
そしてそのネットワーク重みを初期値に、分類のための層を追加して学習させるという手順です。
以下に実験的にIrisデータで試したものを載せます。(GPUないので、この程度のデータを扱うのが精一杯。MnistやCiferができたら面白いんだろうな。)
上記のコードをスクロールして一番下にある3つの図について
一番上の図が生データ
真ん中の図が事前学習(5000epoch)の中間表現
一番下の図がファインチューニング(10000epoch)の中間表現
事前学習だけでも十分に良い表現を獲得できています。
教師なし学習において、分類の過学習などありません(なぜなら、答えを知らないから)
ただ再構成可能なようにしたら、偶然良い表現が見つかっているだけです。従って、これが上手く役立ちそうならば、この表現を維持するように再構成誤差を損失関数に含むことで、過学習を抑制するようなことが期待できます(再構成誤差を、雑音除去符号化器で得れば更に効果は大きいと思われる)。
学習の条件
150個のデータのうち75個を事前学習→150個全てプロット
事前学習と同様の75個のデータでファインチューニング→150個プロット
としているので、学習に用いてない残り半分のデータも、中間表現の中で適切に配置できている様子がわかります。
TensorFlowの方も
一番下までスクロールして
上の図が生データ
下の図がファインチューニング後のデータです。
TensorFlowはDefine and Runなので、あとから層の追加はできません。
従って、事前学習無しで最初から以下の構成で学習しました。
学習中に、中間表現から再構成が可能なように学習を進めることになりますが、事前学習ありならば、すでに再構成可能な重みから学習がスタートしますが、今回はでたらめなところからスタートするため、中間表現の見栄えはあまりよくありません。
それでもこの程度のデータに対する分類ならば、正解率にそれほど差がでるということもありません。また、事前学習に当てた時間をすべてファインチューニングの方に費やせば良いという考え方もできます。(実際、事前学習はさほど使われない。ただ何かしら意味があると私は思っています)
自己符号化器の発展
中間表現をいじる
においてを使うのが符号化器(エンコーダ)で、を使うのが復号化器(デコーダ)となります。今回は中間表現を獲得するエンコーダに着目しましたが、逆に適当な中間表現からデータを生み出すデコーダの方も利用価値が高いです。
というデコーダを考えた時、これは当然からもともとのデータを復元できるように学習されているはずですから、がちょっとだけ変わった場合も、と性質の近い何かしらのデータが得られることが期待できます。
表現学習へ
今回は、特に何も意識せずなる中間表現を獲得しましたが、に何らかの意味を予め与えることで面白いことができるかもしれません。
特に、エンコーダによってデータの分散と平均を表現し、分散と平均からデータを復元するデコーダを学習により構築することでVAE(Variational AutoEncoder)と呼ばれる優れたモデルが考案されています。
ココらへんからデコーダやエンコーダに対して生成モデル(簡単に言えばデータを作ることのできるモデル)が発展していきました。GANなどもその類。
時系列に対応できるLSTMや、高階テンソルの局所的な情報を扱えるCNNが深層学習の2大巨塔みたいになっていますが、深層学習の始まりとなった自己符号化器も忘れてないで。