はじめに
AIの領域では画像を識別する技術が象徴的で、初学者向けのテーマになったり、アルゴリズムの優劣を競う競技で使われることがよくあります。その課題の題材としてよく用いられる画像のデータセットの一つにCifar10があります。このデータはプログラムで扱いやすいように、複数の画像を一つのバイナリに纏めた状態で提供されています。以前の記事でも示してきてはいますが、昨今AIを簡単に利用できるサービスやツールが提供されており、AI利用者は必ずしもプログラムを書ける必要はなくなってきています。画像だけ集められれば良いという人にとってはこのCifar10は使いにくいかもしれません。今回は、Cifar10を画像データに展開する方法を示します。プログラムを書かない方のために、スクリプトも提供しますのでご安心ください。
では、始めましょう。
前提
CIFAR-10データのダウンロード
Cifar10のサイトからイメージデータをダウンロードしてきておいてください。
バージョンがPython, Matlab, binaryの3種類ありますが、Pythonのものをダウンロードしましょう。
CIFAR-10とCIFAR-100がありますが、どちらも扱うことができます。
Pythonの準備
データの解説
ダウンロードしてきたファイルを展開すると画像データとラベルのデータが入っています。なぜかcifar-10とcifar-100は違うファイル構成になっています。それぞれ次の通りです。
■cifar-10
1 2 3 4 5 6 7 8 9 10 |
$ tar xvfz cifar-10-python.tar.gz cifar-10-batches-py/ cifar-10-batches-py/data_batch_4 cifar-10-batches-py/readme.html cifar-10-batches-py/test_batch cifar-10-batches-py/data_batch_3 cifar-10-batches-py/batches.meta cifar-10-batches-py/data_batch_2 cifar-10-batches-py/data_batch_5 cifar-10-batches-py/data_batch_1 |
data_batch_<n> が画像データになります。
batches.metaがラベルデータになります。
■cifar-100
1 2 3 4 5 6 |
$ tar xvfz cifar-100-python.tar.gz cifar-100-python/ cifar-100-python/file.txt~ cifar-100-python/train cifar-100-python/test cifar-100-python/meta |
trainとtestが画像データです。metaがラベルデータです。
画像の展開
1 2 3 4 5 |
def unpickle(file): import pickle with open(file, 'rb') as fo: dict = pickle.load(fo, encoding='bytes') return dict |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
import numpy as np from PIL import Image import os, sys, argparse import pickle def unpickle(file): import pickle with open(file, 'rb') as fo: dict = pickle.load(fo, encoding='bytes') return dict def extract(datafile, labelfile, savedir): try: os.makedirs(savedir) except: pass if os.path.isfile(datafile) == False or os.path.isfile(labelfile) == False: print("invalid file error: data file:{}, label file:{}".format(datafile, labelfile)) sys.exit() # ラベルのロード。ラベル名しか使わない。 labels = unpickle(labelfile) if b"label_names" in labels: labels = unpickle(labelfile)[b"label_names"] else: labels = unpickle(labelfile)[b"coarse_label_names"] # イメージデータのロード。ファイル名、ラベル、データをそれぞれ取り出しておく。 images = unpickle(datafile) filenames = images[b"filenames"] if b"labels" in images: image_labels = images[b"labels"] else: image_labels = images[b"coarse_labels"] image_data = images[b"data"] # ファイル格納先のフォルダを作成 for i in labels: try: dir=os.path.join(savedir, i.decode('utf-8')) os.makedirs(dir) except: pass # イメージファイルの展開 for i,_ in enumerate(filenames): filename = filenames[i] image_label = image_labels[i] image = image_data[i] file_path = os.path.join(os.path.join(savedir, labels[image_label].decode('utf-8'), filename.decode('utf-8'))) reshaped_array = np.reshape(image, [3, 32, 32]).transpose(1,2,0) im = Image.fromarray(reshaped_array) with open(file_path, mode='wb') as out: im.save(out) print("Save image: {}".format(file_path)) if __name__ == '__main__': parser = argparse.ArgumentParser(description='cifar-10 converter') parser.add_argument('datafile', type=str, default=None, help="path to datafile") parser.add_argument('labelfile', type=str, default=None, help="path to labelfile") parser.add_argument('savedir', type=str, default=None, help="directory that the output images will be saved") args = parser.parse_args() extract(args.datafile, args.labelfile, args.savedir) |
1 |
$python3.6 extract.py cifar-10-batches-py/data_batch_1 cifar-10-batches-py/batches.meta cif10 |
このとおり。
まとめ
今回は、CIFAR10の画像を展開する方法を纏めました。プログラムがあまり得意でない方もこれを用いて画像を抽出し、AIサービスに入力することができるようになりますので、試しにTensorflowやAutoMLを使ってみるとよいのではないでしょうか。
コメント