機械学習・自然言語処理の勉強メモ

学んだことのメモやまとめ

TheanoでStacked Autoencoder

前回の続編で、今回はStacked Autoencoder(積層自己符号化器)
kento1109.hatenablog.com

このdocumantationを整理する。
Stacked Denoising Autoencoders (SdA) — DeepLearning 0.1 documentation

今回もStacked Autoencoderに関する基本知識は、「MLP 深層学習」を参考とした。

Stacked Autoencoder

その名前の通り、単層ネットワークのAutoencoderを積み重ねたもの。
下記のような多層ネットワーク
f:id:kento1109:20171201181145p:plain
の各層を単層ネットワークに分割し、上位層から順番にAutoencoderによる学習を行う。
f:id:kento1109:20171201181121p:plain
この学習により各層の重みとバイアスが得られる。
これらを元に出力層を含む層を1層以上追加し(その重みはランダムに初期化)、学習を行う。
f:id:kento1109:20171201155903p:plain
また、学習したネットワークを「特徴抽出器」として利用し、SVMなどの一般的な機械学習手法に用いることも可能である。
上記の場合、z^{(3)}を特徴量として用いる。)

次に実際にコードを読んでいく。
(今回も特に新しいことは無いので短めにまとめる。)

ポイントとしては、

  • pretuningStacked Autoencoder
  • finetuning(教師あり学習)

を一つの関数(test_stacked_autoencoder)で行っているとこ

SdA

Stacked Denoising Autoencoderのメインクラス

for i in xrange(self.n_layers):
    if i == 0:
        input_size = n_ins
    else:
        input_size = hidden_layers_sizes[i - 1]
    if i == 0:
        layer_input = self.x
    else:
        layer_input = self.hidden_layer[-1].output

    hidden_layer = HiddenLayer(rng=numpy_rng,
                               input=layer_input,
                               n_in=input_size,
                               n_out=hidden_layers_sizes[i],
                               activation=T.nnet.sigmoid)
    self.hidden_layers.append(hidden_layer)
    self.params.extend(hidden_layer.params)        

の繰り返し処理で積み上げる隠れ層モデルを繰り返し構築する。
隠れ層のクラスは変わらないが、層ごとに入出力が異なる点を意識する。
具体的には、繰り返し処理の最初の条件分岐の箇所。
まず、input_size(入力サイズ)

  • 入力層ー隠れ層:756(28×28)
  • それ以外:1000

次に、layer_input(入力値)

  • 入力層ー隠れ層:self.x
  • それ以外:self.hidden_layer[-1].output

self.hidden_layer.outputは、

output = activation(T.dot(input, self.W) + self.b)

と定義されている。

同様に

    autoencoder_layer = DenoisingAutoencoder(numpy_rng=numpy_rng,
                                             theano_rng=theano_rng,
                                             input=layer_input,
                                             n_visible=input_size,
                                             n_hidden=hidden_layers_sizes[i],
                                             W=hidden_layer.W,
                                             bhid=hidden_layer.b)
    self.autoencoder_layers.append(autoencoder_layer)

で繰り返しDenoisingAutoencoderモデルを構築。
重み、バイアスは隠れ層のものを共有する。
その繰り返し処理の後に、

self.log_layer = LogisticRegression(
                    input=self.hidden_layers[-1].output,
                    n_in=hidden_layers_sizes[-1],
                    n_out=n_outs)
self.params.extend(self.log_layer.params)

で教師あり学習によるロジスティック回帰を行うためのモデルを構築する。
test_stacked_autoencoder関数では、Stacked Denoising Autoencoder及びロジスティック識別による出力層を定義した後、事前学習を行う。
次に事前学習を行う関数を定義する。
呼び出す関数は、pretraining_fuunction
なかでは、積み重ねた隠れ層の数(3)だけ、勾配法による学習関数を作成する。

pretrain_functions = []
for autoencoder in self.autoencoder_layers:
    cost, updates = autoencoder.get_cost_updates(corruption_level, learning_rate)
    fn = theano.function(
        inputs=[
            index,
            theano.Param(corruption_level, default=0.2),
            theano.Param(learning_rate, default=0.1)
        ],
        outputs=cost,
        updates=updates,
        givens={
            self.x: train_set_x[batch_begin:batch_end]
        }
    )
    pretrain_functions.append(fn)

return pretrain_functions

戻り値pretrain_functionsには、[fn, fn, fn]が入っている。
次に事前学習のエポック数分、学習を行う。

for i in xrange(sda.n_layers):
    for epoch in xrange(pretraining_epochs):
        c = []
        for batch_index in xrange(n_train_batches):
            c.append(pretraining_functions[i](index=batch_index,
                                              corruption=corruption_levels[i],
                                              lr=pretrain_lr))

以上でpretrainingが完了
pretrainingの出力のみが必要な場合、最後の隠れ層のoutputの値を取り出す。

fine-tuningの部分は、普通のMLPなので割愛する。