TensorflowでAutoEncoderをやってみた

AutoEncoder（自己符号化器）とは、機械学習において、ニューラルネットワークを使用した次元圧縮のためのアルゴリズム。（From [Wiki](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%BC%E3%83%88%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%80)）

今回はAutoEncoderを使って、画像の異常検出をやってみたいです。
使用する画像は[Workpilesさんのきゅうりの画像](https://github.com/workpiles/CUCUMBER-9/)（勝手に使って申し訳ないですけど…）

![687474703a2f2f776f726b70696c65732e636f6d2f776f726470726573732f77702d636f6e74656e742f75706c6f6164732f323031362f30322f637563756d6265725f636c617373696669636174696f6e2e6a7067.jpg](https://qiita-image-store.s3.amazonaws.com/0/144971/80668d3c-25f9-c04f-d647-55c98248632e.jpeg)
2L分類のきゅうり：正常
C分類のきゅうり：異常
にします。

####モデル
Input：32x32x3の画像
Encoder：畳み込み層+プーリング*3
　32x32x3　→　16x16x32　→　8x8x16 →　4x4x8
　つまり、抽出された特徴は128です。
Decoder：4x4x8の特徴から32x32x3画像へ復元

####ソースコード
[Github](https://github.com/onlyzs89/autoencoder/tree/master)に保存しました。

```python:encoder
W_conv1 = weight_variable([3, 3, DEPTH, 32])
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

W_conv2 = weight_variable([3, 3, 32, 16])
b_conv2 = bias_variable([16])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

W_conv3 = weight_variable([3, 3, 16, 8])
b_conv3 = bias_variable([8])
h_conv3 = tf.nn.relu(conv2d(h_pool2, W_conv3) + b_conv3)
h_pool3 = max_pool_2x2(h_conv3)
```

```python:decoder
de_W_conv3 = weight_variable([3, 3, 16, 8])
de_b_conv3 = bias_variable([16])
de_h_conv3 = tf.nn.relu(de_conv2d(x, de_W_conv3, [batch_size, WIDTH//4, HEIGHT//4, 16], [1,2,2,1]) + de_b_conv3)
    
de_W_conv2 = weight_variable([3, 3, 32, 16])
de_b_conv2 = bias_variable([32])
de_h_conv2 = tf.nn.relu(de_conv2d(de_h_conv3, de_W_conv2, [batch_size, WIDTH//2, HEIGHT//2, 32], [1,2,2,1]) + de_b_conv2)
    
de_W_conv1 = weight_variable([3, 3, 3, 32])
de_b_conv1 = bias_variable([3])
de_h_conv1 = tf.nn.relu(de_conv2d(de_h_conv2, de_W_conv1, [batch_size, WIDTH, HEIGHT, 3], [1,2,2,1]) + de_b_conv1)
```

####結果
Lossが0.003以下になると、学習を中止します。

きゅうりの分類が2L(正常)とC(異常)のデータ各50枚を使って検証してみました。
Lossが学習時Lossの95%信頼区間の1.2倍を超える場合は異常と認識します。

```
             precision    recall  f1-score   support

          0       0.74      0.78      0.76        50
          1       0.77      0.72      0.74        50

avg / total       0.75      0.75      0.75       100

[[39 11]
 [14 36]]
```

正解率は75%です。

最後に、生成した画像を見ましょう。
Origin: ![0.jpg](https://qiita-image-store.s3.amazonaws.com/0/144971/7d9dfe4c-311f-3d46-aef1-d56936e20d94.jpeg)![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/144971/6ea6f586-bd6a-62e6-f68f-3f9555ba13b0.jpeg)![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/144971/4682d15c-cc5b-bf8c-25d0-73804249b810.jpeg)![3.jpg](https://qiita-image-store.s3.amazonaws.com/0/144971/8c9b75ed-e4bc-8b99-0198-035a8803447b.jpeg)![4.jpg](https://qiita-image-store.s3.amazonaws.com/0/144971/18bb4d43-003b-b666-dfa9-9688e265cc17.jpeg)
Faked: ![0fake.jpg](https://qiita-image-store.s3.amazonaws.com/0/144971/0a3f6145-a36c-a096-3700-31a62cd76b82.jpeg)![1fake.jpg](https://qiita-image-store.s3.amazonaws.com/0/144971/9d73fcbe-2813-a7ee-3a7a-550583aeb424.jpeg)![2fake.jpg](https://qiita-image-store.s3.amazonaws.com/0/144971/ad8b2dfb-a680-3d65-cf99-95bcfc0a65de.jpeg)![3fake.jpg](https://qiita-image-store.s3.amazonaws.com/0/144971/af1110cc-9243-ddd3-4522-b9495eb26ba5.jpeg)![4fake.jpg](https://qiita-image-store.s3.amazonaws.com/0/144971/4989f6db-76f6-4830-dabc-dd12018a10be.jpeg)