はじめに
- 今回の、学習画像、テスト画像、水増し画像の合計サイズは、
1.4GB
程度です。 - これらの画像を、学習プログラム実施時に、読み込むとそれなりの時間が必要になります。
- また、別の環境で学習プログラムを実施する時も、転送時間が発生します。
- その他、画像サイズをリサイズしたり、カラーからグレーに変換する処理にも時間が必要になります。
- あらかじめ、リサイズ、グレー変換したデータセットを作成する事で、
50MB
程度にすることが出来ました。 - ソース一式は ここ です。
ライブラリ
- 前回と同様、
Numpy
Pillow
を使っています。
設定
- 以下の設定を追加しています。
-
DATASETS_PATH
に、今回作成するデータセットが保存されます。 -
IMG_ROWS
IMG_COLS
は、画像サイズのリサイズです。今回は、28 x 28
のサイズへリサイズします。 - 画像サイズは、後工程の学習モデルでも参照されます。
config.py
DATASETS_PATH = os.path.join(DATA_PATH, 'datasets')
IMG_ROWS, IMG_COLS = 28, 28
ファイル一覧の作成
- 学習画像、テスト画像、水増し画像のファイル一覧を作成します。
- query には、
CLASSES
が順次与えられます。 -
augment
引数は、水増し画像の利用可否のフラグです。 - 前回、水増し画像は、
query
毎に6000
作成しました。足りない場合は、エラーにしています。
def make_filesets(augment):
"""ファイルセットの作成."""
filesets = {'train': dict(), 'test': dict(), 'augment': dict()}
for query in CLASSES:
train_path = os.path.join(TRAIN_PATH, query)
test_path = os.path.join(TEST_PATH, query)
augment_path = os.path.join(AUGMENT_PATH, query)
if not os.path.isdir(train_path):
print('no train path: {}'.format(train_path))
return None
if not os.path.isdir(test_path):
print('no test path: {}'.format(test_path))
return None
if not os.path.isdir(augment_path):
print('no augment path: {}'.format(augment_path))
return None
train_files = glob.glob(os.path.join(train_path, '*.jpeg'))
train_files.sort()
filesets['train'][query] = train_files
test_files = glob.glob(os.path.join(test_path, '*.jpeg'))
test_files.sort()
filesets['test'][query] = test_files
augment_files = glob.glob(os.path.join(augment_path, '*.jpeg'))
random.shuffle(augment_files)
filesets['augment'][query] = augment_files
if augment and len(augment_files) < AUGMENT_NUM:
print('less augment num: {}, path: {}'.format(len(augment_files), augment_path))
return None
return filesets
画像の読み込みの関数
- ファイルのフルパスを元に画像を処理します。
- 設定ファイルに従い、リサイズされます。
- もともと、OpenCV Haar Cascades では、リサイズを行わずに保存していました。後工程でリサイズする方が、様々なサイズで試すのに便利ですね。
-
LANCZOS
は、時間はかかるが、品質良くリサイズしてくれます。デフォルトは、NEAREST
ですね。品質より、速さ優先です。 - その後、グレースケールに変換し、さらに
uint8
に変換します。
def read_image(filename):
"""画像の読み込み、リサイズ、グレー変換."""
image = Image.open(filename)
image = image.resize((IMG_ROWS, IMG_COLS), Image.LANCZOS)
image = image.convert('L')
image = np.array(image, dtype=np.uint8)
return image
データセットの作成
- 学習画像、学習ラベル、テスト画像、テストラベルの配列を準備します。
def make_datasets(augment, filesets):
"""データセットの作成."""
train_images = []
train_labels = []
test_images = []
test_labels = []
- query には、
CLASSES
が順次与えられます。 - num には、ラベル が順次与えられます。
- 例えば、
CLASSES
の 最初は、安倍乙
ラベルは0
と言う感じです。 -
augment
で水増し画像を利用するか判断します。利用する場合は、AUGMENT_NUM
に記載の数のみtrain_files
に設定します。 - 各画像の読み込みには、
tqdm
も合わせて利用しています。処理経過が表示され、分かりやすいですね。 -
read_image
に画像のファイルパスを与えて、リサイズ、グレースケール化した画像を読み込みます。 - 同時にラベルも付与します。
for num, query in enumerate(CLASSES):
print('create dataset: {}'.format(query))
if augment:
train_files = filesets['augment'][query][:AUGMENT_NUM]
else:
train_files = filesets['train'][query]
test_files = filesets['test'][query]
for train_file in tqdm.tqdm(train_files, desc='create train', leave=False):
train_images.append(read_image(train_file))
train_labels.append(num)
for test_file in tqdm.tqdm(test_files, desc='create test', leave=False):
test_images.append(read_image(test_file))
test_labels.append(num)
- 学習画像、学習ラベル、テスト画像、テストラベルをデータセットとしてまとめます。
-
DATASET_PATH
CLASSES
IMG_ROWS
IMG_COLS
水増し画像の利用有無を元にデータセットのファイル名を決めます。
datasets = ((np.array(train_images), (np.array(train_labels))), (np.array(test_images), (np.array(test_labels))))
datasets_path = os.path.join(DATASETS_PATH, ','.join(CLASSES))
os.makedirs(datasets_path, exist_ok=True)
train_num = AUGMENT_NUM if augment else 0
datasets_file = os.path.join(datasets_path, '{}x{}-{}.pickle'.format(IMG_ROWS, IMG_COLS, train_num))
with open(datasets_file, 'wb') as fout:
pickle.dump(datasets, fout)
print('save datasets: {}'.format(datasets_file))
- 水増し画像の利用有無は、下記のオプションで切り替えています。
$ python save_datasets.py
$ python save_datasets.py --augment
- pickle 化したデータセットは、下記の様になりました。
- オリジナルの場合は、
train
test
の合計 約148MB
から3.2MB
の pickleファイル - 水増し画像の場合は、
augment
test
の合計 約1433MB
から46MB
の pickleファイル
$ du -d1 -h .
115M ./train
33M ./test
51M ./datasets
1.4G ./augment
$ ls
3.2M 12 15 23:22 28x28-0.pickle
46M 12 15 22:24 28x28-6000.pickle
おわりに
- 学習プログラムから利用しやすい様に、画像データをリサイズ、グレースケールしたデータセットを作成しました。
- 複数のサイズ、水増し画像の数の変化などで、色々データセットを作り、ファイル名で切り替えながら利用が出来ます。
- 次回は、データセットを学習プログラムから読み込む部分を作成する予定です。