👻

Tensorflowを使ってみた

2022/09/18に公開

Tensorflow を使ってみる

気になってはいたけど、使ったことがないんです。ということで、初めて Tensorflow を使ってみましたので記録も兼ねてここに記載します。

使用したライブラリ

今回使用したライブラリは以下のとおりです。

pandas 1.2.3
numpy 1.20.2
tensorflow 2.10.0
scikit-learn 1.0.2
seaborn 0.11.2

タスクを定義

今回は分類タスクである Iris ことあやめの分類を行います。この分類タスクは調べればすぐに出てきますので詳細は割愛します。まずは、基本的な流れを学ぶために、とりあえず走らせることを目標とします。

兎にも角にもまずは import から

今回は次のライブラリをインポートします。

import seaborn as sns
import pandas as pd
import numpy as np
from tensorflow.keras.layers import Input, Dense, Activation
from tensorflow.keras.models import Model
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

詳細は次項以降に記載していますので、割愛します。

もし足りないライブラリがあれば pip install xxx でインストールしてください。

データセットの読み込み

Iris のデータセットは seaborn から取得します。どこから取ってきても良いので使いやすいものを利用すると良いでしょう。

_datasets = sns.load_dataset('iris')

実際のデータはこんな感じです。

データの加工

Tensorflow は目的変数に質的データを当てはめることができなようです。今回の分類タスクのような場合、1,2....といったデータではなく"setosa",..という文字列で分類されていますのでそのまま扱うことができません。

したがって、データを加工して量的なデータとする必要があります。このとき、利用するのが one-hot ベクトル化という手法です。

例えば、男と女などのカテゴリ分けをされた変数がある場合、男列と女列の 2 列を別途作成し、男なら男列を 1、女列を 0 といった形で割り当てます。

10 カテゴリあれば 10 列で割当を行い、該当する列が 1、それ以外が 0 となるような行列となるので one-hot と呼ぶようです。

実際の処理を見てみましょう。

# 目的変数を削除します。
_X = _datasets.drop(['species'], axis= 1)
# pandasのget_dummiesでone-hotベクトル化ができます。
# 今回、対象はspeciesです。prefixのonehotは列名の最初にonehotが挿入されます。
_y = pd.get_dummies(_datasets.species, prefix = "onehot")

それぞれのデータはこのようになります。

従属変数_X のデータ

one-hot ベクトル化された_y のデータ

さらにデータを訓練用とテスト用に分割します。今回は random_state は固定でテストサイズを全体の 20%としました。

_X_train, _X_test, _y_train, _y_test = train_test_split(_X, _y, test_size=0.20, random_state=39)

データのがうまく分割できたら、今度は機械学習の精度を上げるために標準化を行います。

_std_sc = StandardScaler()
_X_train = _std_sc.fit_transform(_X_train)
_X_test = _std_sc.transform(_X_test)

訓練用データは_X_train で、これには fit_transform を定義し、標準化されています。このデータを用いて、テストデータである_X_test が処理されています。

ここまでで、ひとまずひととおりのデータ加工が終了しました。

機械学習の定義

ここから Tensorflow のモデル定義になります。

_input_1 = Input(shape=(_X_train.shape[1],))
_l1 = Dense(100, activation='relu')(_input_1)
_l2 = Dense(50, activation='relu')(_l1)
_l3 = Dense(50, activation='relu')(_l2)
_output_1 = Dense(_y_train.shape[1], activation='softmax')(_l3)

_model = Model(inputs = _input_1, outputs = _output_1)
_model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])

最初に Input layer を定義します。このとき、shape には訓練データの次元が渡されます。今回の訓練データは萼の長さと幅、花弁の長さと幅の情報を持つ 4 次元データとなります。

その情報をもらって畳み込みを行います。最後の output では目的変数_y を定義する為必要な次元を定義します。ここでは one-hot ベクトル化されているので 3 次元のデータとなります。

最後の 2 行で、損失関数、最適化などを定義するとモデルの定義が完了します。

学習

どの機械学習もそうですが、この 1 行で訓練が完了します。

_history = _model.fit(_X_train, _y_train, batch_size=4, epochs=20, verbose=1, validation_split=0.20)

機械学習の結果を評価する。

機械学習の結果は evaluate で評価できます。今回は訓練データの学習結果がテスト結果を大きく上回るような過学習状態かどうかを見てみます。

_score = _model.evaluate(_X_test, _y_test, verbose=1)
_train_score = _model.evaluate(_X_train, _y_train, verbose =1)

結果は次のとおりでした。

テストが 0.96、訓練が 0.96 となっていたので、問題なしと言えるでしょう。

シーケンスをまとめる

今までの流れをまとめると次のようになります。

import seaborn as sns
import pandas as pd
import numpy as np
from tensorflow.keras.layers import Input, Dense, Activation
from tensorflow.keras.models import Model
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler


def tf_data_classification():
  _datasets = sns.load_dataset('iris')

  # データセットを_Xと_yに分けます。
  _X = _datasets.drop(['species'], axis= 1)

  # _yは質的データだったので、TFで扱えるような量的なデータへ変換します。
  # one-hot化とも呼びます。
  _y = pd.get_dummies(_datasets.species, prefix = "onehot")

  # numpyへデータ変換します。
  _X = _X.values
  _y = _y.values

  # train dataと test dataへ分けます。
  # test_size = 0.20 で20%をテストに回すことができます。
  _X_train, _X_test, _y_train, _y_test = train_test_split(_X, _y, test_size=0.20, random_state=39)

  # 標準化します。
  _std_sc = StandardScaler()
  _X_train = _std_sc.fit_transform(_X_train)
  _X_test = _std_sc.transform(_X_test)

  # 機械学習のモデルを定義します。
  _input_1 = Input(shape=(_X_train.shape[1],))
  _l1 = Dense(100, activation='relu')(_input_1)
  _l2 = Dense(50, activation='relu')(_l1)
  _l3 = Dense(50, activation='relu')(_l2)
  _output_1 = Dense(_y_train.shape[1], activation='softmax')(_l3)

  _model = Model(inputs = _input_1, outputs = _output_1)
  _model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])

  # 学習します
  _history = _model.fit(_X_train, _y_train, batch_size=4, epochs=20, verbose=1, validation_split=0.20)

  # 学習結果を確認します。
  _score = _model.evaluate(_X_test, _y_test, verbose=1)
  _train_score = _model.evaluate(_X_train, _y_train, verbose =1)
  print('-'*96)
  print("test accuracy: ", _score[1])
  print("train accuracy: ", _train_score[1])
tf_data_classification()

こちらはノートブック上でも動きますので、ぜひお試しあれ。バグなどがあればご連絡ください。

使ってみた

使ってみた感想は、すごく使いやすいと感じています。実際 Tensorflow は Keras と一緒に利用されているようなので、そちらも別途学んでいきたいですね。

Discussion