Kerasでとりあえず動かしてみるディープラーニング#6

#はじめに
GPUが載ってないPCでディープラーニングをやってみたい、という人向けです。
オートエンコーダでの画像のノイズ除去をやってみます。
「TensorFlow開発入門」の「CAEを使ったノイズ除去」のソースを元にしています。
（正規化をしていない等以外は、殆どそのままです）

#事前準備
ColaboratoryでハードウェアアクセラレータにGPUを選択します。
Colaboratoryの使い方については過去の投稿も参考にしてください。
https://qiita.com/norikawamura/items/637c92545e222f16c535

#オートエンコーダとは
encoder-decoderとも言うようです。
JPEGやGIFのような画像の圧縮、展開と同様で、
一度データ量を減らしておいてから、元データと同様のデータに戻す処理です。
次元削減などにも使えるようです。

よくある学習方法としては、教師用の画像に対し、何らかの処理を行った画像を学習用データとして使用する、といった形になるかと思います。
例えば、自動着色であれば、元のカラー画像を白黒画像に変換してそれを学習データにする、今回の様にノイズ除去であれば
教師画像にノイズを入れた画像を作成してそれを学習データにする、となるかと思います。


#MNISTのデータを取得する

```Python
import keras
mnist = keras.datasets.mnist

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
```

# 損失グラフ表示の関数
毎回貼り付けてますが、前回までのものと同じです。

```Python
import matplotlib.pyplot as plt
#損失関数グラフ
def plotHistory(history):
    # 損失関数のグラフの軸ラベルを設定
    plt.xlabel('time step')
    plt.ylabel('loss')
    # グラフ縦軸の範囲を0以上と定める
    plt.ylim(0, max(np.r_[history.history['val_loss'], history.history['loss']]))
    # 損失関数の時間変化を描画
    val_loss, = plt.plot(history.history['val_loss'], c='#56B4E9')
    loss, = plt.plot(history.history['loss'], c='#E69F00')
    # グラフの凡例（はんれい）を追加
    plt.legend([loss, val_loss], ['loss', 'val_loss'])
    # 描画したグラフを表示
    plt.show()
```

# ノイズ生成の関数を定義し、ノイズ入り画像を作成する
「TensorFlow開発入門」では画像を0～1に正規化していますが、正規化せずに0～255の値で扱っています。

```Python
X_train = train_images.reshape(-1,28,28,1)
X_test  = test_images.reshape(-1,28,28,1)

import numpy as np
def make_gaussian_noise_data(data_x):
    gaussian_data_x = data_x + np.random.normal(loc=0, scale=100, size=data_x.shape)
    gaussian_data_x = np.clip(gaussian_data_x, 0, 255)
    return gaussian_data_x

X_train_gauss = make_gaussian_noise_data(X_train)
X_test_gauss = make_gaussian_noise_data(X_test)
```


# データの中身を見てみる

```Python
import matplotlib.pyplot as plt
plt.imshow(X_train[0].reshape(28,28), cmap='gray')
plt.colorbar()
```

元画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93459/ffc464d2-8f93-5c47-ef2f-25e5728795e8.png)


```Python
import matplotlib.pyplot as plt
plt.imshow(X_train_gauss[0].reshape(28,28), cmap='gray')
plt.colorbar()
```

ノイズ入り
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93459/608d927f-7dc8-1321-91a6-b42181ef1c0e.png)

# オートエンコーダを定義する

```Python
from keras.models import Sequential
from keras.layers import Dense, Dropout, BatchNormalization
from keras.optimizers import Adam
from keras.callbacks import EarlyStopping
from keras.layers import Conv2D, Flatten, Reshape, LeakyReLU, MaxPooling2D, ELU
from keras.layers.convolutional import UpSampling2D

# encoderを定義
model_enc = Sequential()
model_enc.add(Conv2D(32, 3, input_shape=(28,28,1), padding='same', activation='relu'))
model_enc.add(MaxPooling2D())
model_enc.add(Conv2D(32, 3, padding='same', activation='relu'))
model_enc.add(MaxPooling2D())
model_enc.add(Flatten())
print('encoder')
model_enc.summary()

# decoderを定義
model_dec = Sequential()
model_dec.add(Dense(32*7*7, input_shape=(7*7*32,)))
model_dec.add(Reshape((7,7,32,)))

model_dec.add(Conv2D(32, 3, padding='same', activation='relu'))
model_dec.add(UpSampling2D((2, 2)))

model_dec.add(Conv2D(32, 3, padding='same', activation='relu'))
model_dec.add(UpSampling2D((2, 2)))

model_dec.add(Conv2D(1, 3, padding='same'))
print('decoder')
model_dec.summary()

#　autoencoderを定義
model_auto = Sequential([model_enc, model_dec])
print('autoencoder')
model_auto.summary()
model_auto.compile(optimizer='adadelta', loss='mse', metrics=['accuracy'])

```

# 学習実行

```Python
early_stopping = EarlyStopping(monitor='val_loss', mode='min', patience=10)
plotHistory(
    model_auto.fit(
         X_train_gauss.reshape(-1,28,28,1)
        ,train_images.reshape(-1,28,28,1)
        ,epochs=100
        ,validation_split=0.1
        ,batch_size=1000
        ,verbose=2
        ,callbacks=[early_stopping]
    )
)
model_auto.save('noise_reduction1num2.h5')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93459/a816e668-fa15-df11-32ca-a0cc02689307.png)


# ノイズ除去処理実行

```Python
X_pred = model_auto.predict(X_test_gauss)
```

上からノイズ入り画像、除去処理後画像、元の教師画像
先頭の１０個ずつを表示しています。

```Python
import matplotlib.pyplot as plt
n = 10
plt.figure(figsize=(20, 2))
for i in range(n):
    ax = plt.subplot(1, n, i+1)
    plt.imshow(X_test_gauss[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93459/5fca8b6d-bdf6-6565-cb27-25e7a9b592a4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93459/9f0a643c-cb05-1ab1-7116-b044598b6f92.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93459/499ed9a7-7fc0-5b07-1a8a-30839e901d5a.png)

#次回予定
　未定です。