KerasでFReLUを使ってみる

#はじめに
「tf.kerasでFReLUを実装」の記事を書かれている方がいらっしゃったので、それを使ってみようと思います。
https://qiita.com/rabbitcaptain/items/26304b5a5e401db5bae2

#MNISTの判定をやってみる
FReLU()とそれから呼ばれるmax_unit()は上記の記事のをそのまま使います。（もし試す場合は最初に実行してください）
Functionalモデルで実装されてるようなので、Functionalモデルで作成します。

```Python
from tensorflow.keras.layers import Input, Activation
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D
from tensorflow.keras.layers import Dense, Dropout, BatchNormalization
from tensorflow.keras.optimizers import Adam

def createModel():
  main_input = Input(shape=(28,28,1,), name='main_input')
  x = Conv2D(32, kernel_size=(3, 3), padding='same')(main_input)
  x = FReLU(x)
  x = Conv2D(32, kernel_size=(3, 3), padding='same')(x)
  x = FReLU(x)

  x = MaxPooling2D()(x)

  x = Conv2D(32, kernel_size=(3, 3), padding='same')(x)
  x = FReLU(x)
  x = Conv2D(32, kernel_size=(3, 3), padding='same')(x)
  x = FReLU(x)

  x = MaxPooling2D()(x)

  x = Conv2D(32, kernel_size=(3, 3), padding='same')(x)
  x = FReLU(x)
  x = Conv2D(32, kernel_size=(3, 3), padding='same')(x)
  x = FReLU(x)

  x = GlobalAveragePooling2D()(x)
  x = Dense(units=10, activation='softmax')(x)

  return Model(inputs=[main_input], outputs=[x])
```

MNISTのデータをロードして加工します。

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

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

import numpy as np
train_images_norm = (train_images / 255.0).astype(np.float16)
test_images_norm = (test_images / 255.0).astype(np.float16)

train_images_norm_rs = train_images_norm.reshape(-1, 28, 28, 1)
test_images_norm_rs  = test_images_norm.reshape(-1, 28, 28, 1)

train_labels_ct = keras.utils.to_categorical(train_labels, 10)
test_labels_ct = keras.utils.to_categorical(test_labels, 10)

```

今回も「Ｒａｓｐｂｅｒｒｙ　Ｐｉではじめる機械学習　基礎からディープラーニングまで」に載っていた学習結果の表示用関数を使います。

```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()
```

モデルの作成及びコンパイル後、学習を実行します。

```Python
from tensorflow.keras.callbacks import EarlyStopping

model = createModel()
# モデルのコンパイル
model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=0.0001), metrics=['accuracy'])
model.summary()
# モデルの学習
early_stopping = EarlyStopping(monitor='val_loss', mode='min', patience=30)

plotHistory(
  model.fit(
    train_images_norm_rs
    ,train_labels_ct
    ,epochs=500
    ,validation_split=0.1
    ,batch_size=1000
    ,verbose=2
    ,callbacks=[early_stopping]
  ) 
)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93459/f50c0388-4270-9eb8-2b36-5e0707e764c9.png)

判定を行ってみます。

```Python
result_pred = model.predict(test_images_norm_rs, verbose=0)

result = np.argmax(result_pred, axis=1)
 
print('ターゲット')
print(test_labels)
print('ディープラーニングによる予測')
print(result)

# データ数をtotalに格納
total = len(test_images_norm_rs)
# ターゲット（正解）と予測が一致した数をsuccessに格納
success = sum(result==test_labels)

# 正解率をパーセント表示
print('正解率')
print(100.0*success/total)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93459/99629e52-5abb-85fb-0441-ae69c7d0800a.png)

#結果

適当に作ったモデルでしたが、99%の正解率となりました。