Tensorflow2に改めて入門1(アヤメデータセットでシンプルなモデル作成)
TensorFlow2系の書き方を体系的にまとめたものがあまりなかったので入門記事としてまとめようと思います。 とりあえず動いてかつ機械学習の流れを掴めるというようなゆるい内容です。 基本的にはColab上で動くように想定しています。 Done is better than perfectを目指しているので、とりあえずアップして適宜直していくスタイルでいければと思っています。
環境
Google Colaboratory(通常版)
何をするか
アヤメの花のデータセットを使って3値分類をやります.
データセットのロード
まずはデータセットを作ります.
import numpy as np import pandas as pd import tensorflow as tf from tensorflow.keras import layers from tensorflow.keras.utils import to_categorical from sklearn.model_selection import train_test_split from sklearn.datasets import load_iris #sklearnのirisデータをロード iris = load_iris() #irisデータの特徴量とラベルを結合 iris_data = np.concatenate((iris.data, iris.target[:, np.newaxis]), axis=1) #ラベル名にyを追加 iris.feature_names.append("y") #アヤメのデータフレームを作成 dataframe = pd.DataFrame(iris_data, columns=iris.feature_names) dataframe.head()
訓練データ、評価データ、テストデータ、に分けます。
train, test = train_test_split(dataframe, test_size=0.2) train, val = train_test_split(train, test_size=0.2) print(f"訓練データ数:{len(train)}") print(f"テストデータ数:{len(test)}") print(f"評価データ数:{len(val)}")
出力:
訓練データ数:96 テストデータ数:30 評価データ数:24
tf.data.Datasetに変換する
tf.dataはデータをモデルの読み込みやすい形に変換できます。 これによって、学習を効率的に進めることができます。
df_to_dataset
関数を定義しdfからdatasetに変換します。
内部でデータを分割し、特徴量とラベルに変えています。
def df_to_dataset(dataframe, shuffle=True, batch_size=32): dataframe = dataframe.copy() labels = dataframe.pop("y") labels = to_categorical(labels) ds = tf.data.Dataset.from_tensor_slices((dataframe, labels)) if shuffle: ds = ds.shuffle(buffer_size=len(dataframe)) ds = ds.batch(batch_size) return ds
これらをそれぞれ、訓練データ、評価データ、テストデータ、に適用します。
batch_size = 5 train_ds = df_to_dataset(train, batch_size=batch_size) val_ds = df_to_dataset(val, shuffle=False, batch_size=batch_size) test_ds = df_to_dataset(test, shuffle=False, batch_size=batch_size)
takeメソッドを使ってbatchを確認してみます。 サンプル数5のミニバッチになっており、tf.Tensorに変換されています。
for feature_batch, label_batch in train_ds.take(1): print('A batch of ages:\n', feature_batch) print('A batch of targets\n:', label_batch )
A batch of ages: tf.Tensor( [[7.4 2.8 6.1 1.9] [5.7 3. 4.2 1.2] [6.1 3. 4.9 1.8] [5.1 2.5 3. 1.1] [6.7 3.1 4.4 1.4]], shape=(5, 4), dtype=float64) A batch of targets: : tf.Tensor( [[0. 0. 1.] [0. 1. 0.] [0. 0. 1.] [0. 1. 0.] [0. 1. 0.]], shape=(5, 3), dtype=float32)
モデル作成
モデルとして全結合3層ニューラルネットを作成します。 また、モデルに対してcompileを使って最適化手法と損失、評価指標を設定します。 そして、最後にfitでモデルを学習させます。
model = tf.keras.Sequential([ layers.Dense(128, activation='relu', input_shape=(4,)), layers.Dense(128, activation='relu'), layers.Dense(3, activation="softmax") ]) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(train_ds, validation_data=val_ds, epochs=5)
Epoch 1/7 20/20 [==============================] - 1s 7ms/step - loss: 1.0765 - accuracy: 0.4688 - val_loss: 0.8818 - val_accuracy: 0.7500 Epoch 2/7 20/20 [==============================] - 0s 2ms/step - loss: 0.8072 - accuracy: 0.7708 - val_loss: 0.7610 - val_accuracy: 0.5833 Epoch 3/7 20/20 [==============================] - 0s 2ms/step - loss: 0.6388 - accuracy: 0.7917 - val_loss: 0.5299 - val_accuracy: 0.9583 Epoch 4/7 20/20 [==============================] - 0s 2ms/step - loss: 0.4845 - accuracy: 0.8750 - val_loss: 0.4420 - val_accuracy: 0.8750 Epoch 5/7 20/20 [==============================] - 0s 2ms/step - loss: 0.4037 - accuracy: 0.8958 - val_loss: 0.3936 - val_accuracy: 0.9167 Epoch 6/7 20/20 [==============================] - 0s 3ms/step - loss: 0.3526 - accuracy: 0.9375 - val_loss: 0.3335 - val_accuracy: 0.8750 Epoch 7/7 20/20 [==============================] - 0s 2ms/step - loss: 0.3129 - accuracy: 0.9479 - val_loss: 0.3135 - val_accuracy: 0.9583
評価
テストデータで評価指標を確認してみます。 テストデータでもしっかりと予測できています。
loss, accuracy = model.evaluate(test_ds) print("Accuracy", accuracy)
6/6 [==============================] - 0s 2ms/step - loss: 0.0979 - accuracy: 1.0000 Accuracy 1.0
参考文献
カスタム訓練:ウォークスルー | TensorFlow Core
TensorFlowで使えるデータセット機能が強かった話 - Qiita
第2回 ニューラルネットワーク最速入門 ― 仕組み理解×初実装(中編):TensorFlow 2+Keras(tf.keras)入門 - @IT