ニューラルネットワークによるデータの分類を行う. ここでの分類は,データから,そのラベル(クラス名)を求めるもの. 分類のために,教師データを用いてニューラルネットワークの学習を行う.
このページでは,TensorFlow データセットの中の MNIST データセットを用いて,TensorFlow での学習を行うととも に,データの分類も行う.
データセットの利用条件は利用者で確認すること. このページの内容は, https://www.tensorflow.org/datasets/keras_example による.
【目次】
【サイト内の関連ページ】
【関連する外部ページ】
Google Colaboratory のページ:
次のリンクをクリックすると,Google Colaboratory のノートブックが開く. そして,Google アカウントでログインすると,Google Colaboratory のノートブック内のコード等を編集したり再実行したりができる.編集した場合でも,他の人に影響が出たりということはない.そして,編集後のものを,各自の Google ドライブ内に保存することもできる.
https://colab.research.google.com/drive/1QvEEivjsqTK3s1QV5yn-COo-HavIlO2U?usp=sharing
Windows での Python 3.10,関連パッケージ,Python 開発環境のインストール: 別ページ »で説明
【サイト内の関連ページ】
Python のまとめ: 別ページ »にまとめ
【関連する外部ページ】
Python の公式ページ: https://www.python.org/
Windows での TensorFlow,Keras のインストール: 別ページ »で説明
(このページで,Build Tools for Visual Studio 2022,NVIDIA ドライバ, NVIDIA CUDA ツールキット, NVIDIA cuDNNのインストールも説明している.)
コマンドプロンプトを管理者として実行: 別ページ »で説明
python -m pip install -U tensorflow_datasets
Windows での Graphviz のインストール: 別ページ »で説明
コマンドプロンプトを管理者として実行: 別ページ »で説明
python -m pip install -U numpy matplotlib seaborn scikit-learn pandas pydot
【Python の利用】
Python は,次のコマンドで起動できる.
Python 開発環境(Jupyter Qt Console, Jupyter ノートブック (Jupyter Notebook), Jupyter Lab, Nteract, Spyder, PyCharm, PyScripterなど)も便利である.
Python のまとめ: 別ページ »にまとめ
これ以降の操作は,jupyter qtconsole で行う.
jupyter qtconsole
from __future__ import absolute_import, division, print_function, unicode_literals import tensorflow as tf from tensorflow.keras import backend as K K.clear_session() import numpy as np import tensorflow_datasets as tfds %matplotlib inline import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') # Suppress Matplotlib warnings mnist, mnist_info = tfds.load('mnist', with_info = True, shuffle_files=True, as_supervised=True)
fig1 = tfds.show_examples(mnist['train'], mnist_info) fig2 = tfds.show_examples(mnist['test'], mnist_info)
print(mnist_info) print(mnist_info.features["label"].num_classes) print(mnist_info.features["label"].names)
ds_train: サイズ 28 × 28 の 60000枚の濃淡画像,60000枚の濃淡画像それぞれのラベル(0 から 9 のどれか)
ds_test: サイズ 28 × 28 の 60000枚の濃淡画像,60000枚の濃淡画像それぞれのラベル(0 から 9 のどれか)
ds_train, ds_test = mnist['train'], mnist['test']
次により,データセット ds_train, ds_test の先頭要素を確認.
次のプログラムでは,ds_train, ds_test の先頭要素が,i に得られる. i がタップルであること, そして,i は TensorFlow のテンソルが並んだタップルであることをを確認する.
実行結果からは,次を確認,i の長さは 2,そして,i の中身が 2つであることが分かる.
for i in ds_train.take(1): print(type(i)) for j in range(len(i)): print(type(i[j])) print(i[j].shape)
for i in ds_test.take(1): print(type(i)) for j in range(len(i)): print(type(i[j])) print(i[j].shape)
「tf.reshape(image, [-1])」では,テンソルをフラット化している.これは,表示を見やすくするため.
タップルの 0 番目は数値データ, タップルの 1 番目は分類結果のラベル(クラス名)である.
for image, label in ds_train.take(1): print(tf.reshape(image, [-1])) print(label)
for image, label in ds_test.take(1): print(tf.reshape(image, [-1])) print(label)
値は,もともと int で 0 から 255 の範囲であるのを, float32 で 0 から 1 の範囲になるように前処理を行う.そして, データセットのシャッフルとバッチも行う.
def normalize_img(image, label): """Normalizes images: `uint8` -> `float32`.""" return tf.cast(image, tf.float32) / 255., label SHUFFLE_BUFFER_SIZE = 100000 BATCH_SIZE=128 AUTOTUNE = tf.data.experimental.AUTOTUNE ds_train = ds_train.map(normalize_img, num_parallel_calls=AUTOTUNE) ds_train = ds_train.cache().shuffle(buffer_size=SHUFFLE_BUFFER_SIZE).batch(BATCH_SIZE).prefetch(buffer_size=AUTOTUNE)
値は,もともと int で 0 から 255 の範囲であるのを, float32 で 0 から 1 の範囲になるように前処理を行う.そして, データセットのバッチも行う.
ds_test = ds_test.map(normalize_img, num_parallel_calls=AUTOTUNE) ds_test = ds_test.cache().batch(BATCH_SIZE).prefetch(buffer_size=AUTOTUNE)
NUM_CLASSES = 10 m = tf.keras.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(units=64, activation='relu'), tf.keras.layers.Dropout(0.5), tf.keras.layers.Dense(units=NUM_CLASSES, activation='softmax') ]) m.summary()
L2 正則化を行いたいときは 「 tf.keras.layers.Dense(128, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(0.001)),」のようにする.
m.compile( optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), loss='sparse_categorical_crossentropy', metrics=['sparse_categorical_crossentropy', 'accuracy'] )
ニューラルネットワークの学習は fit メソッドにより行う. 教師データを使用する. 教師データを投入する.
EPOCHS = 20 history = m.fit(ds_train, validation_data=ds_test, verbose=2, epochs=EPOCHS)
ds_test を分類してみる.
print(m.predict(ds_test))
それぞれの数値の中で、一番大きいものはどれか?
m.predict(ds_test).argmax(axis=1)
ds_test 内にある正解のラベル(クラス名)を表示する(上の結果と比べるため)
for i in ds_test: print(i[1])
過学習や学習不足について確認.
import pandas as pd hist = pd.DataFrame(history.history) hist['epoch'] = history.epoch print(hist)
【外部ページへのリンク】 訓練の履歴の可視化については,https://keras.io/ja/visualization/
acc = history.history['accuracy'] val_acc = history.history['val_accuracy'] loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(1, len(acc) + 1) # "bo" は青いドット plt.plot(epochs, loss, 'bo', label='Training loss') # ”b" は青い実線 plt.plot(epochs, val_loss, 'b', label='Validation loss') plt.title('Training and validation loss') plt.xlabel('Epochs') plt.ylabel('Loss') plt.legend() plt.show()
acc = history.history['accuracy'] val_acc = history.history['val_accuracy'] loss = history.history['loss'] val_loss = history.history['val_loss'] plt.clf() # 図のクリア plt.plot(epochs, acc, 'bo', label='Training acc') plt.plot(epochs, val_acc, 'b', label='Validation acc') plt.title('Training and validation accuracy') plt.xlabel('Epochs') plt.ylabel('Accuracy') plt.legend() plt.show()