Pythonでデータセットを作る方法とデータセットの中身を確認する方法(npy編)

2021年6月19日

今回は、拡張子が npy の場合のデータセットの作り方を説明します。

前回記事ではpickle編、前々回記事ではnpz編を紹介しました。

今回の記事は三部作の完結編になります。

データセットの作り方は色々ありますが、自分の使いやすいデータの保存方法を見つけてもらえればと思います。

前回の繰り返しになりますが、このページを始めて見に来た方のためにもう一度説明します。

今回ご紹介するデータセットは、画像とラベルがセットになったファイルです。

データセットは、Deep Learning で物体分類や物体検出の学習をさせる際や、主成分分析(PCA:Principal component analysis)、多様体学習の等尺性マッピング(Isomap:isometric mapping)を行う際に使用します。

Deep Learning では教師あり学習用のデータとして利用できます。

また、PCAやIsomap では教師なし学習用のデータとして利用できます。(この場合はラベルは無視)

何れにしても、大量の画像とラベルのデータをセットで保存しておくことができます。

ソースコード(npy編)

以下のソースコードを見てください。

# read_image_npy.py #  プログラム名
import cv2
import glob
import random
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
def read_image():
    # 設定パラメータ
    class_n = 2        # クラス数
    x = []             # 画像データ  : npy用
    y = []             # ラベルデータ: npy用
    # npyで保存
    outfile_npy = "./photo/" + str("224px_") + str(class_n) + ".npy"
    # path 以下の画像を読み込む
    def glob_files(path, label):
        files = glob.glob(path + "/*.jpg")  # pathにある画像を読み込む
        random.shuffle(files)               # ランダムに画像を読み込む
        # 各ファイルを処理
        num = 0
        for f in files:
            if num >= len(files): break
            num += 1
            # 画像ファイルを読む
            img = Image.open(f)         # Pillow(PIL)で画像読込み。色順番はRGB
            img = np.asarray(img)       # ndarray化
            img = cv2.resize(img, (224, 224), cv2.INTER_LANCZOS4)  # 画像サイズを224px × 224pxにする
            
            # npyで保存
            x.append(img)
            y.append(label)
    i = 0
    for i in range(class_n):
        glob_files("./photo/" + str(i), i)  # 各画像のフォルダーを読む
        print("file: " + str(i))
    ### ファイルへ保存 ###
    # npyで作成する場合
    np.save(outfile_npy, (x, y))
    print("npyを保存しました :" + outfile_npy, len(x))
if __name__ == '__main__':
    read_image()

ポイント

1.npy ファイルを保存する際は、np.save( ) を使用する

これは決まり事です。

ちなみに、npz、pickle との違いを以下にまとめます。

ファイルの拡張子使用するコード
npznp.savez( )
picklepickle.dump( )
npynp.save( )

npz と npy の違いは、save に z が付くか付かないかです。

npz と npy は共に NumPy のファイル保存の機能を使います。

NumPy を使うことで 画像の配列(ndarray)をそのまま保存することができます。

また、NumPy のファイル保存機能を使用するので pickle を import する必要もありません。

下記のコードを説明します。

np.save(outfile_npy, (x, y))

カッコの中の第一引数は、npy ファイルの保存先のパスを示しています。

また、第二引数の(x, y)は画像 x とラベル y のデータをセットでこの順番で保存することを示しています。

保存先のパスについて、ちょっとだけ深堀り説明します。

今回のパスは以下のように記載されています。

outfile_npy = “./photo/" + str(“224px_") + str(class_n) + “.npy"

パスの最後に、「 + “.npy" 」と拡張子を付けるように記載していますが、実はこれを記載しなくても自動的に 「 .npy 」の拡張子が付いたファイルが作成されます。

これは、NumPy のファイル保存機能を使った場合にできるもので、npz とnpy のファイルを作成する場合は、np.savez( ) か np.save( ) を使用しただけで拡張子が自動的に付与されます。

ただし、pickle ファイルを作成する場合は、パスの最後に「 + “.pickle" 」を付ける必要があります。

これを忘れると、pickle の拡張子が付いたファイルが作成されません。

2.画像をランダムに読み込む際は、random.shuffle( ) を使用する

前回記事でも書きましたが、データセット作成時にデータに偏りを持たせないために使用します。

データセットをDeep Learning の学習に使うのであれば必須です。

なおランダム化が必要なければ、ソースコードの先頭に # を付けてコメントアウトしてください。

コメントアウトすればこのソースコードは実行されません。

実行結果

詳細については、前回記事を参考にしてください。

上記ソースコードを実行すると以下のファイルが作成されます。

224px_2.npy

このファイルは、各画像に「0」というラベルと「1」というラベルが付いたデータになります。

次に、この npy ファイルの中身を確認してみます。

データセットの中身を確認する方法

以下のソースコードを見てください。

# image_plot_npy.py #  プログラム名
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 設定パラメータ
img_n = 9
### npy用 ###
### データセットをnpyで作成した場合 ###
photos = np.load('./photo/224px_2.npy', allow_pickle=True)
x = photos[0]
y = photos[1]
# 開始インデックス(idx = 0 一番最初の画像)
idx = 0
# 画像表示
plt.figure(figsize=(10, 10))
for i in range(img_n):
    plt.subplot(3, 3, i+1)    # 3行3列の1番目から9番目まで表示
    plt.axis('off')           # 画像にスケールを入れない
    plt.title(y[i + idx])     # タイトルにインデックスを表示
    plt.imshow(x[i + idx])    # 画像がカラー(RGB)の場合
    #plt.imshow(x[i + idx], cmap='gray')   # 画像がグレーの場合
plt.show()

ポイント

1.npy ファイルを読み込む際は、np.load( ) を使用する

np.load( ) のカッコの中を説明します。

第一引数は、npy ファイルが置かれているパスです。

第二引数は、npy ファイルとして保存されている pickleオブジェクトを読み込むかどうかを指定するものです。

この 「 allow_pickle = True 」を記載しないと npy ファイルを読み込めません。

2.ラベルデータと画像データを扱いやすくするため分離する

np.load( ) で読み込んだ npy ファイルを一旦 photos に代入します。

photos には (x, y) つまり(画像, ラベル)の順番でデータが保存されています。

photos [ 0 ] には画像データが入っているので、これを x に代入します。

photos [ 1 ] にはラベルデータが入っているので、これを y に代入します。

画像とラベルのデータを分離しておくことで、この後の処理がし易くなります。

3.画像表示は matplotlib の plt を使用する

おなじみの matplotlib を使用します。

ちなみに、グレー画像を表示させる場合は plt.imshow( ) のカッコの中に cmap = ’gray’ を追記すればOKです。

カラー画像(RGB)を表示させる場合は cmap は不要です。

表示結果

ラベル 0
ラベル 1

各画像にラベル 0 とラベル 1 がタイトルとして付与されていることが分かります。

npy ファイルに画像とラベルがセットで保存されていることが確認できました。

まとめ

  • npy ファイルを保存する際は、np.save( ) を使用する
  • npz とnpy のファイルを作成する場合は、np.savez( ) か np.save( ) を使用しただけで拡張子が自動的に付与される
  • 画像をランダムに読み込む際は、random.shuffle( ) を使用する
  • npy ファイルを読み込む際は、np.load( ) を使用しカッコ内に「 allow_pickle = True 」を記載する
  • ラベルデータと画像データを扱いやすくするため分離する
  • 画像表示は matplotlib の plt を使用する
  • グレー画像なら plt.imshow( ) のカッコ内に cmap=’gray’ を追記する