データセット「EMNIST」について説明。81万枚〜7万枚の手書きアルファベットおよび数字の「画像+ラベル」データが無料でダウンロードでき、画像認識などのディープラーニングに利用できる。PyPIパッケージ、TensorFlow、PyTorchにおける利用コードも紹介。
EMNISTデータセット(以下、EMNIST)は、
といった手書き文字の画像データセットである(図1)。
EMNISTは、MNISTの拡張版(an Extension of MNIST to handwritten letters)として、NIST Special Database 19から抽出&加工して作られたサブセットである。主に画像認識を目的としたディープラーニング/機械学習の研究や初心者向けチュートリアルで使われることが意識されている。そのため、MNISTは「0」〜「9」という10種類の手書き数字データセットとなっているが、EMNISTはそれを拡張して、10種類の手書き数字+26種類の手書きアルファベット文字(大文字/小文字)のデータセットとなっている。
EMNISTには、下記6つのデータ種別が用意されている。
クラス分類の62は、「数字の10文字」+「アルファベット大文字の26文字」+「アルファベット小文字の26文字」を合計した数である。ByClassのラベル(=正解を示す教師データ)の値は、図1のように数字、アルファベット大文字、小文字の順に0スタートで付番されている。
ただし、アルファベットには大文字と小文字が非常に似ている文字がいくつかある。例えば大文字の「O」と小文字の「o」は見分けがつきにくいだろう。このような文字は、
の15文字がある。これらのアルファベットの小文字を、同じアルファベットの大文字の分類にまとめたのがByMergeとBalancedである(図2)。
よってクラス分類の47(=62文字−15文字)は、「数字の10文字」+「アルファベット大文字の26文字」+「アルファベット小文字の11文字(※上記の15文字は大文字にまとめられている)」を合計した数となる。ByMerge/Balancedのラベルも数字アルファベット順に0スタートで付番されている。
ByMergeとBalancedの違いは、各分類におけるデータ数のバランスを調整して一致させたかどうかである。通常、各分類とも同じ数のデータで訓練する方がよいと考えられるので、Balancedの方がよりよい選択肢だろう。つまりEMNISTを使って手書きアルファベット&数字の分類が行える機械学習モデルを作りたい場合、「EMNIST Balanced」が最も良い選択肢となるだろう。
次にLettersは、クラス分類が26個となっており、これはアルファベットの文字数と同じである。このことから分かるように、アルファベットの大文字小文字を区別しないで、数字を省いてアルファベット文字のみを学習したい場合に使える。なお、他のデータ種別とは異なり、Lettersのみはアルファベット順に1スタートで付番されていることに注意が必要だ(図3)。例えばラベル1は「A」を意味する。ラベル0は存在しない。
最後にクラス分類の10は、「数字の10文字」のことである。DigitsとMNISTが存在し、どちらも各分類におけるデータ数のバランスが調整されている。Digits/MNISTのラベルは数字順に0スタートで付番されている(図4)。例えばラベル0は「0」を意味する。
EMNIST Digits/MNISTは、手書き数字のみを学習したい場合に使えるが、手書き数字だけであれば元々のMNISTデータセットを使えばよいので、現実的にこれらのデータ種別を活用することはほとんどないだろう。DigitsとMNISTの違いは、EMNIST MNISTはMNISTデータセットと同じ7万枚(=訓練データ用が6万枚、テストデータ用が1万枚)というデータセットで構成されていることだ。これにより、MNISTと全く同じコード内容、条件で機械学習が行えるようになっている。
バランス調整の内容を含めて各データ種別の概要が、データセットの配布元の論文にきれいにまとめられているので、参考までに図5に引用しておこう。図自体の説明は割愛する。
各画像のフォーマットは(MNISTと同じく)、
となっている(※「フィールド」=データを画像化する場合には「ピクセル」に対応する。RGBで作るグレースケールでは、0が黒で、255が白となり逆なので注意してほしい)。
このデータセットは、基本的に自由に使用できる(※ライセンスは指定されていない。厳密には公式ページを確認してほしい)。公式ページによると「下記のように論文を引用してください」と記載されている。
引用情報を以下にまとめておく。
実際にEMNISTを使うには、PyPIパッケージやTensorFlow/PyTorchといった各ライブラリが提供する機能を利用することをお勧めする。というのも、EMNISTの公式ページからダウンロード可能なファイルは、.jpgのような一般的な画像ファイルではなく、独自のフォーマットを持つ単一(=複数の画像データがひとまとめになった形式)の画像データセットだからである(※ファイルフォーマットの仕様は、MNIST公式ページの「FILE FORMATS FOR THE MNIST DATABASE」および「THE IDX FILE FORMAT」を確認してほしい)。
ライブラリを使わない場合、この画像フォーマットを読み込むためのリーダーをプログラムとして作る必要がある。プログラムの作成は難しくはないが、多くの人が使うものなので、主要な機械学習&ディープラーニングのライブラリでは基本機能としてEMNISTをロードする機能が含まれている。よってそのロード機能を活用して、ムダな作業を減らすことを本稿ではお勧めする。
それぞれのライブラリで「どのようなコードを書くとEMNISTが使えるか」の典型的なコードを簡単に示しておく(※コードの詳細は解説しない)。基本的に各ライブラリは、EMNISTデータセットを自動的にダウンロードして使いやすい形にロードしてくれる機能を提供している。
非公式と思われるが、「emnist」というPyPIパッケージが存在する。特に、NumPy配列でデータセットを取得できる点が便利だ。
# !pip install emnist # ライブラリ「emnist」をインストール
import emnist
(X_train, y_train) = emnist.extract_training_samples('balanced')
# byclass/bymerge/balanced/letters/digits/mnistを指定可能
使い方は簡単で、リスト1のようにemnistモジュールのextract_training_samples()関数やextract_test_samples()関数を呼び出すだけである。それぞれの関数の引数には、6つのデータ種別(byclass/bymerge/balanced/letters/digits/mnist)を指定できる。
# !pip install tensorflow tensorflow-datasets # ライブラリ「TensorFlow」と「TensorFlow Datasets」をインストール
import tensorflow_datasets as tfds
emnist_train = tfds.load(name='emnist/balanced', split='train')
# 'emnist/byclass'(デフォルト)、 'emnist/bymerge'、 'emnist/balanced'、 'emnist/letters'、 'emnist/digits'、 'emnist/mnist' が指定できる
TensorFlow/Kerasでは、TensorFlow Datasetsのemnistデータセットを使えばよい。これは、tensorflow_datasetsモジュール(=tfds)のtfds.load()関数から利用できる。その関数のsplit引数で、6つのデータ種別(byclass/bymerge/balanced/letters/digits/mnist)を指定できる。
注意点として、元々のEMNISTデータセットでは画像の行列が逆になっており、そのまま画像化すると文字が横に寝た状態になることである。これを回避して人間が見やすいように画像を表示するためには、例えばtf.transpose()関数やNumPyのtranspose()関数を呼び出すなど、いったん行列の転置(transpose)を行う必要がある。
# !pip install torch torchvision # ライブラリ「PyTorch」をインストール
import torch
import torchvision
emnist_data = torchvision.datasets.EMNIST(
'./EMNIST',
split='balanced', # byclass/bymerge/balanced/letters/digits/mnist
train=True, download=True, transform=torchvision.transforms.ToTensor())
data_loader = torch.utils.data.DataLoader(emnist_data, batch_size=4, shuffle=True)
PyTorchでは、torchvision.datasets.EMNISTクラスのコンストラクター(厳密には__init__関数)でデータセットのオブジェクトを生成してデータをダウンロードし、torch.utils.data.DataLoaderクラスのコンストラクターでデータローダーのオブジェクトを生成してデータをロードすればよい。そのEMNISTクラスにおけるコンストラクターの第2引数splitで、6つのデータ種別(byclass/bymerge/balanced/letters/digits/mnist)を指定できる。
注意点として、先ほどのTensorFlow Datasetsと同様に、画像の行列が逆になっていることが挙げられる。画像を正確な向きで表示するためには、例えばtranspose()関数を使うなどして、いったん行列の転置(transpose)を行う必要がある。
Copyright© Digital Advantage Corp. All Rights Reserved.