2.1 オートエンコーダ

オートエンコーダの概要

オートエンコーダのネットワーク

画像としてMNIST の数字画像 28x28 pixel (チャネル数1, 白黒画像, 28x28x1 = 784)を使う。 エンコーダは、784次元の画像$x$ を200次元の潜在変数に変換し、デコーダはこれから 784次元の画像 $x'$ を生成する。 エンコーダもデコーダも全結合層を使用し、activationはエンコーダはReLU,デコーダはsigmoid を使う。 sigmoidを使うので復元画像 $x'$ の各画素値は [0.0, 1.0] になる。

元画像 $x$ の画素値は [0, 255] であるが、ライブラリ torchvision の入力画像は[0.0, 1.0] に正規化済みの画像である。$x$ と $x'$ の各画素値がともに [0.0, 1.0] であるから、誤差計算が可能となる。

データセットの作成

torchvision.transforms は画像変換に用いる。 transforms は Compose. を用いて数珠繋ぎにできる。

torchvision.transforms.functional モジュールは、画像変換を細かく定義するのに使う。

全ての transformation は PIL 画像, Tensor 画像、Tensor画像のbatchを受け付ける。 Tensor画像のフォーマットは(C, H, W) であり、そのbatch のフォーマットは (B, C, H, W)である。

torch.tensor.view は、引数で与えたshape にTensorのshapeを変更して返す。 -1の場合は他の引数から推測される。 x.view(-1)は一次元の Tensor を返す。

[自分へのメモ] MNIST のデータをダウンロードするきに 503 エラーがおきるようになったので注意。 そのため、自分でMNISTデータをダウンロードして展開しておく必要がある。

ネットワークの定義

オートエンコーダのネットワーク

オートエンコーダの損失関数

入力画像 $x$ と復元画像 $x'$ の画素値の誤差 (= 再構成誤差) をピクセル単位で計算する。

$\displaystyle J^{REC} = - \frac{1}{N} \sum_{i=1}^{N} (x_i \log y_i + (1 - x_i) \log (1 - y_i))$

$x_i$ は入力画像の各画素で、$y_i$はそれぞれに対応する出力画像の各画素である。

入力 $x$ に対する出力 $y$ を求める式は以下の通り。

$y = \mbox{sigmoid} ( \boldsymbol{W}_2 ~ \mbox{ReLU}(\boldsymbol{W}_1 \boldsymbol{x} + \boldsymbol{b}_1)) + \boldsymbol{b}_2)$

学習の実行

DataLoader は Dataset からデータとラベルをバッチサイズにまとめて返す。

画像の復元

test_dataloader からデータを取り出し、評価を行う。

[自分へのメモ] 元本のコードは1回のbatchデータである100個の画像データに対してエンコード&デコードして復元画像を作成しているが、結果としては1個しか表示していないようにみえる。 自分のコードに変更している。