くずし字 MNIST データセット(Kuzushiji-MNIST データセット)のダウンロード,画像分類の学習,画像分類の実行
くずし字 MNIST データセット(Kuzushiji-MNIST データセット)を紹介する. 利用条件は利用者で確認すること.
【目次】
* くずし字 MNIST データセット(Kuzushiji-MNIST データセット)
くずし字 MNIST データセットは,公開されているデータセット(オープンデータ)である.
【文献】 CODH:Center for Open Data in the Humanities), KMNISTデータセット(機械学習用くずし字データセット), arXiv:1812.01718 [cs.CV], 2018.
【サイト内の関連ページ】
【関連する外部ページ】
- くずし字 MNIST データセットの公式ページ:
https://github.com/rois-codh/kmnist
Kuzushiji-MNIST, Kuzushiji-49, Kuzushiji-Kanji の 3種類が公開されている(オープンデータ).
前準備
Git のインストール
Git の URL: https://git-scm.com/
Python の準備(Windows,Ubuntu 上)
- Windows での Python 3.10,関連パッケージ,Python 開発環境のインストール(winget を使用しないインストール): 別ページ »で説明
- Ubuntu では,システム Pythonを使うことができる.Python3 開発用ファイル,pip, setuptools のインストール: 別ページ »で説明
【サイト内の関連ページ】
- Python のまとめ: 別ページ »にまとめ
- Google Colaboratory の使い方など: 別ページ »で説明
【関連する外部ページ】 Python の公式ページ: https://www.python.org/
Python 用 numpy,pandas,seaborn,matplotlib のインストール
- Windows の場合
Windows では,コマンドプロンプトを管理者として実行し, 次のコマンドを実行する.
python -m pip install -U numpy pandas seaborn matplotlib
- Ubuntu の場合
端末で,次のコマンドを実行
sudo apt -y update sudo apt -y install python3-numpy python3-pandas python3-seaborn python3-matplotlib
kmnist のダウンロード
Windows での手順を示す.Ubuntu でも同様の手順である.
- Windows で,コマンドプロンプトを管理者権限で起動する(例:Windowsキーを押し,「cmd」と入力し,「管理者として実行」を選択).
- ダウンロード用ディレクトリの準備
C: cd C:\ rmdir /s /q kmnist
- Kuzushiji-49 のダウンロード
Kuzushiji-MNIST, Kuzushiji-49, Kuzushiji-Kanji の 3種類をダウンロードできる.
下の実行例では,「2」,「1」を選び,Kuzushiji-49 をダウンロードしている.
cd C:\ git clone https://github.com/rois-codh/kmnist cd kmnist python download_data.py
- Kuzushiji-MNIST のダウンロード
Kuzushiji-MNIST, Kuzushiji-49, Kuzushiji-Kanji の 3種類をダウンロードできる.
下の実行例では,「1」,「2」を選び,Kuzushiji-49 をダウンロードしている.
cd C:\kmnist python download_data.py
くずし字 MNIST データセット(Kuzushiji-MNIST データセット)のダウンロード,画像分類の学習,画像分類の実行
Kuzushiji-49 の読み込み
import numpy as np
x_train = np.load("C:/data/kmnist/k49-train-imgs.npz")['arr_0']
y_train = np.load("C:/data/kmnist/k49-train-labels.npz")['arr_0']
x_test = np.load("C:/data/kmnist/k49-test-imgs.npz")['arr_0']
y_test = np.load("C:/data/kmnist/k49-test-labels.npz")['arr_0']
# 【x_train, x_test, y_train, y_test の numpy ndarray への変換と,値の範囲の調整(値の範囲が 0 ~ 255 であるのを,0 ~ 1 に調整)する】
print(type(x_train), x_train.shape, np.max(x_train), np.min(x_train))
print(type(x_test), x_test.shape, np.max(x_test), np.min(x_test))
print(type(y_train), y_train.shape, np.max(y_train), np.min(y_train))
print(type(y_test), y_test.shape, np.max(y_test), np.min(y_test))

%matplotlib inline
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore') # Suppress Matplotlib warnings
plt.imshow(x_train[0], cmap='gray')
plt.imshow(x_test[0], cmap='gray')

Kuzushiji-MNIST の読み込み
- 読み込み
import numpy as np x_train = np.load("C:/data/kmnist/kmnist-train-imgs.npz")['arr_0'] y_train = np.load("C:/data/kmnist/kmnist-train-labels.npz")['arr_0'] x_test = np.load("C:/data/kmnist/kmnist-test-imgs.npz")['arr_0'] y_test = np.load("C:/data/kmnist/kmnist-test-labels.npz")['arr_0'] # 【x_train, x_test, y_train, y_test の numpy ndarray への変換と,値の範囲の調整(値の範囲が 0 ~ 255 であるのを,0 ~ 1 に調整)する】 print(type(x_train), x_train.shape, np.max(x_train), np.min(x_train)) print(type(x_test), x_test.shape, np.max(x_test), np.min(x_test)) print(type(y_train), y_train.shape, np.max(y_train), np.min(y_train)) print(type(y_test), y_test.shape, np.max(y_test), np.min(y_test))
- 確認表示
%matplotlib inline import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') # Suppress Matplotlib warnings plt.imshow(x_train[0], cmap='gray') plt.imshow(x_test[0], cmap='gray')
ディープラーニングの実行
Kuzushiji-MNIST を用いる.
- パッケージのインポート,TensorFlow のバージョン確認など
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 from tensorflow.keras.preprocessing import image %matplotlib inline import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') # Suppress Matplotlib warnings
- x_train, x_test, y_train, y_test の numpy ndarray への変換と,値の範囲の調整(値の範囲が 0 〜 255 であるのを,0 〜 1 に調整)
x_train = x_train.astype("float32") / 255.0 x_test = x_test.astype("float32") / 255.0 print(type(x_train), x_train.shape, np.max(x_train), np.min(x_train)) print(type(x_test), x_test.shape, np.max(x_test), np.min(x_test)) print(type(y_train), y_train.shape, np.max(y_train), np.min(y_train)) print(type(y_test), y_test.shape, np.max(y_test), np.min(y_test))
- データの確認表示
class_names = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] plt.style.use('default') plt.figure(figsize=(10,10)) for i in range(25): plt.subplot(5,5,i+1) plt.xticks([]) plt.yticks([]) plt.grid(False) plt.imshow(x_train[i], cmap=plt.cm.binary) plt.xlabel(class_names[y_train[i]]) plt.show()
- ニューラルネットワークの作成と確認とコンパイル
2層のニューラルネットワークを作成
1層目:ユニット数は 128
2層目:ユニット数は 10
ADAM を使う場合のプログラム例
NUM_CLASSES = 10 m = tf.keras.Sequential() m.add(tf.keras.layers.Flatten(input_shape=(28, 28))) m.add(tf.keras.layers.Dense(units=128, activation='relu')) m.add(tf.keras.layers.Dropout(rate=0.5)) m.add(tf.keras.layers.Dense(units=NUM_CLASSES, activation='softmax')) m.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), loss='sparse_categorical_crossentropy', metrics=['accuracy'])
SGD を使う場合のプログラム例
m = tf.keras.Sequential() m.add(tf.keras.layers.Flatten(input_shape=(28, 28))) m.add(tf.keras.layers.Dense(units=128, activation='relu')) m.add(tf.keras.layers.BatchNormalization()) m.add(tf.keras.layers.Dropout(rate=0.5)) m.add(tf.keras.layers.Dense(units=10, activation='softmax')) m.compile(optimizer=tf.keras.optimizers.SGD(lr=0.01, momentum=0.9, nesterov=True), loss='sparse_categorical_crossentropy', metrics=['accuracy'])
- ニューラルネットワークの確認表示
print(m.summary())
- ニューラルネットワークの学習を行う
EPOCHS = 50 history = m.fit(x_train, y_train, validation_data=(x_test, y_test), verbose=2, epochs=EPOCHS)
- ニューラルネットワークを使い,分類を行う.
* 訓練(学習)などで乱数が使われるので,下図と違う値になる.
predictions = m.predict(x_test) print(predictions[0])
- 正解表示
テスト画像 0 番の正解を表示
print(y_test[0])
- 訓練の履歴の可視化
【関連する外部ページ】 訓練の履歴の可視化については,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()
- 学習時と検証時の,損失の違い