はじめに
- 今回の、学習画像、テスト画像、水増し画像の合計サイズは、
1.4GB程度です。 - これらの画像を、学習プログラム実施時に、読み込むとそれなりの時間が必要になります。
- また、別の環境で学習プログラムを実施する時も、転送時間が発生します。
- その他、画像サイズをリサイズしたり、カラーからグレーに変換する処理にも時間が必要になります。
- あらかじめ、リサイズ、グレー変換したデータセットを作成する事で、
50MB程度にすることが出来ました。 - ソース一式は ここ です。
ライブラリ
- 前回と同様、
NumpyPillowを使っています。
設定
- 以下の設定を追加しています。
-
DATASETS_PATHに、今回作成するデータセットが保存されます。 -
IMG_ROWSIMG_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_PATHCLASSESIMG_ROWSIMG_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 化したデータセットは、下記の様になりました。
- オリジナルの場合は、
traintestの合計 約148MBから3.2MBの pickleファイル - 水増し画像の場合は、
augmenttestの合計 約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
おわりに
- 学習プログラムから利用しやすい様に、画像データをリサイズ、グレースケールしたデータセットを作成しました。
- 複数のサイズ、水増し画像の数の変化などで、色々データセットを作り、ファイル名で切り替えながら利用が出来ます。
- 次回は、データセットを学習プログラムから読み込む部分を作成する予定です。
