AutoKerasを試してみた

機械学習業界では、時代はまさに『AutoML』と言えるような状況ですが、あのKerasにもAutoML対応のフレームワークが出たようです。

※以前からあるようですが、最近新しくなったようです。

# AutoKerasとは
[AutoKeras](https://autokeras.com/)とは、テキサスA&M大学のDATA Labで開発された、AutoML対応のKerasモジュールになります。
誰もが機械学習にアクセスできることが目標とのことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/8e236926-e2bb-bbe5-fc1d-0b1b54483524.png)

# 条件
AutoKerasを動かすための条件は以下のようになっています。

- Python 3.5以上
- TensorFlow 2.1.0以上

以前はPyTorchを呼んでいたらしいのですが、今はTensorFlowベースとなっています。

# インストール
AutoKerasのインストールは簡単で、pip一発で終了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130771/238d5638-18be-f198-99b8-d8b8992087d5.png)

# サンプル
お馴染みのMNISTを実装してみると、以下のようなコードになります。

```python
from tensorflow.keras.datasets import mnist

import autokeras as ak

# Prepare the dataset.
(x_train, y_train), (x_test, y_test) = mnist.load_data()
print(x_train.shape)  # (60000, 28, 28)
print(y_train.shape)  # (60000,)
print(y_train[:3])  # array([7, 2, 1], dtype=uint8)

# Initialize the ImageClassifier.
clf = ak.ImageClassifier(max_trials=3)
# Search for the best model.
clf.fit(x_train, y_train, epochs=10)
# Evaluate on the testing data.
print('Accuracy: {accuracy}'.format(accuracy=clf.evaluate(x_test, y_test)))
```

モデルの作成が「ImageClassifier()」という関数だけで終了してしまいます。
これだけでレイヤーの調整やはおぱーパラメータまでいい感じにしてくれるなんて、信じがたいものがあります。

# 識別機
組み込みの識別機には、以下の6種類が用意されています。

- ImageClassifier（画像分類）
- ImageRegressor （画像回帰）
- TextClassifier （テキスト分類）
- TextRegressor （テキスト回帰）
- StructuredDataClassifier （構造化データ分類）
- StructuredDataRegressor （構造化データ回帰）

[画像, テキスト, 構造化データ]×[分類, 回帰]といった感じです。
なお、汎用的な識別機（AutoModel）も用意されています。

引数として「max_trials」が用意されており、これがモデルの試行回数となります。
多ければ多いほどいろいろなパターンを試せるのですが、当然のことながら激しく時間がかかります。

## 関数＆パラメータ
主な関数として、お馴染みの

- fit()
- predict()
- evaluate()

が用意されています。
「fit()」時に、モデルの試行を行うとともに、指定したエポック数（EarlyStoppingあり）で学習を繰り返します。

また、モデルの試行が終わったところで、結果を以下のように表示します。

```text
Trial complete
Trial summary
|-Trial ID: 7721ba2b2344499c8cc23920528e1976
|-Score: 0.04051450350758387
|-Best step: 0
Hyperparameters:
|-classification_head_1/dropout_rate: 0.5
|-classification_head_1/spatial_reduction_1/reduction_type: flatten
|-dense_block_1/dropout_rate: 0
|-dense_block_1/num_layers: 1
|-dense_block_1/units_0: 128
|-dense_block_1/use_batchnorm: False
|-image_block_1/augment: False
|-image_block_1/block_type: vanilla
|-image_block_1/conv_block_1/dropout_rate: 0.25
|-image_block_1/conv_block_1/filters_0_0: 32
|-image_block_1/conv_block_1/filters_0_1: 64
|-image_block_1/conv_block_1/kernel_size: 3
|-image_block_1/conv_block_1/max_pooling: True
|-image_block_1/conv_block_1/num_blocks: 1
|-image_block_1/conv_block_1/num_layers: 2
|-image_block_1/conv_block_1/separable: False
|-image_block_1/normalize: True
|-optimizer: adam
```

さらに、その見つけた最適モデルをアウトプットできるように

- export_model()

という関数も用意されています。
戻りの型がtf.keras.Modelなので、いろいろ使いまわせます。

前述の出力を、export_model()で取得してsummary()で表示すると、以下のようになります。

```text
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 28, 28, 1)]       0         
_________________________________________________________________
normalization (Normalization (None, 28, 28, 1)         3         
_________________________________________________________________
conv2d (Conv2D)              (None, 26, 26, 32)        320       
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 24, 24, 64)        18496     
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 12, 12, 64)        0         
_________________________________________________________________
dropout (Dropout)            (None, 12, 12, 64)        0         
_________________________________________________________________
flatten (Flatten)            (None, 9216)              0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 9216)              0         
_________________________________________________________________
dense (Dense)                (None, 10)                92170     
_________________________________________________________________
classification_head_1 (Softm (None, 10)                0         
=================================================================
Total params: 110,989
Trainable params: 110,986
Non-trainable params: 3
```

# 評価
試行を3回だけで精度を出力してい見たところ、

- loss：0.03652096562991127
- accuracy：0.9892

となりました。

ごくごく一般的なKerasのモデル（[こちら](https://qiita.com/fukuit/items/b3fa460577a0ea139c88)を参考にしました）で試してみた時が

- loss：0.03358279774157436
- accuracy：0.9906

でしたので、ほぼ近い精度が自動的に出せていることになりました。

それ以外のデータ（構造化データとか）で試そうとしたのですが、GPUメモリが足らない等でうまく動かないことがありました．．．

# まとめ
条件は限られるかもしれませんが、簡単に機械学習が試せるのはすごくいいです。
ただ、激しく遅いので、パワフルなハードウェアが欲しくなります。

# おまけ
CUDA 10.1では動くのですが、10.2ではうまく動きませんでした。