---
title: [DL Hacks]CelebAをNumPyで保存してみた
tags:  #deep learning  
author: [Deep Learning JP](https://www.docswell.com/user/DeepLearning2023)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/2EVL9LQGJQ.jpg?width=480
description: 2018/09/10 Deep Learning JP:  http://deeplearning.jp/hacks/
published: September 11, 18
canonical: https://www.docswell.com/s/DeepLearning2023/5NRGQG-dl-hackscelebanumpy
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/2EVL9LQGJQ.jpg)

CelebAをNumPyで保存してみた
CelebAデータセットの202599枚のjpeg画像と40の属性を
NumPy配列に変換し1枚のファイルに保存してみました
2018/9/10 DLHacks LT
植木孝一郎


# Page. 2

![Page Image](https://bcdn.docswell.com/page/57GXZXNDEL.jpg)

CelebFaces Attributes (CelebA) Dataset
香港中文大学（マルチメディア研究室）の大規模な顔属性のデータセット
http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html
178x218ピクセル、202599枚のjpeg画像（RGB）
ファイルサイズ合計 1.743GB
論文
https://arxiv.org/abs/1411.7766


# Page. 3

![Page Image](https://bcdn.docswell.com/page/4EQ8L8QXJP.jpg)

顔の属性
list_attr_celeba.csv
000001.jpg -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 -1 -1 -1 以下略（1と-1の2値、40属性）
・・・
202599.jpg -1 1 1 -1 -1 -1 -1 -1 -1 1 -1 -1 -1 -1 -1 以下略
属性は全部で40 （正値は1、負値は-1)
1 : 5_o_Clock_Shadow
2 : Arched_Eyebrows
3 : Attractive
（無精髭）
（アーチ型の眉）
（魅力的）
...
40: Young （若い）
論文には顔属性の識別手法と精度も書かれてます


# Page. 4

![Page Image](https://bcdn.docswell.com/page/KJ42D2N2E1.jpg)

画像ファイルの読み込み
DeepLearningで画像を学習するためには、Pillow(PIL)やOpenCVなどで画像
を読み込みNumPy配列に変換する必要があります。
ファイル名は000001から始まり規則的なのでリスト作成・画像読み込みなどは
簡単にできます。
また顔属性ラベルの list_attr_celeba.csvは numpy.loadtxt()で読み込めます。
問題は処理時間で・・・
Core i7 メモリ32GB（スワップメモリ64GB）のPCでHDD上の202599枚の画像
を読み込み、NumPy配列に変換すると1929.6秒（約32分）かかりました。
時間をかけデータセットを読み込んだのだから、そのまま保存して活用したい！


# Page. 5

![Page Image](https://bcdn.docswell.com/page/LE1MZM5K7G.jpg)

保存するNumPy配列
保存するNumPy配列は178x218ピクセルのRGB画像 202599枚をtrain_x とし
print(train_x.shape)
(202599, 218, 178, 3)
データ型は numpy.uint8
（8ビット符号なし整数）で保存します
CSVの属性値（-1，1）を（0，1）に変えた2値の40属性、202599行のNumPy配列をtrain_ｙとし
print(train_ｙ.shape)
(202599, 40)
ｔrain_xとtrain_ｙを1枚のファイルに保存します。
train_xとtrain_ｙのメモリ使用量は
sys.getsizeof(train_x)
23584954932 (23.584GB)
sys.getsizeof(train_y)
8104072 (8.1MB)
CelebA 202599枚jpegファイルサイズの合計は 1.743GBでしたので、NumPy配列にすることで13.5倍の容量になります。
※この容量だとPCのメモリ、スワップメモリに注意してないとエラーやフリーズします!
（Linuxなら free -m で確認）


# Page. 6

![Page Image](https://bcdn.docswell.com/page/GEW3935PE2.jpg)

pickle VS numpy.savez
PythonでNumPy配列をbinary保存するため
●
Pickle
●
numpy.savez（非圧縮、複数）
●
numpy.savez_compressed（圧縮、複数）
を使って比較しました。
HDD上にファイルを保存する時間、保存したファイルを読み込む時間、保存した
ファイルサイズを計測しました。


# Page. 7

![Page Image](https://bcdn.docswell.com/page/47ZV9VN6E3.jpg)

pickleでsaveとload
#保存（python3.4以上）
#LT説明用の簡略コード
import pickle
train_xy = train_x,train_y
with open(&quot;save_filename&quot;, &#039;wb&#039;) as f:
pickle.dump(train_xy , f ,protocol=4) # ← protocolが小さいとメモリエラーになる
#読み込み
import pickle
with open(&quot;save_filename&quot;, &#039;rb&#039;) as ｆ:
train_xy = pickle.load（f）
train_x = train_xy[0]
train_y = train_xy[1]
print(train_x.shape)
(202599, 218, 178, 3)
print(train_y.shape)
(202599, 40)


# Page. 8

![Page Image](https://bcdn.docswell.com/page/YJ65K58L7V.jpg)

numpy.savez()で非圧縮保存とload
#保存
import numpy as np
np.savez(&quot;save_filename&quot;, train_x=train_x, train_y=train_y)
#読み込み
import numpy as np
with np.load(&quot;save_filename.npz&quot;) as data:
train_x = data[train_x]
train_y = data[train_y]
print(train_x.shape)
(202599, 218, 178, 3)
print(train_y.shape)
(202599, 40)


# Page. 9

![Page Image](https://bcdn.docswell.com/page/GJ5YPY9MJ4.jpg)

numpy.savez_compressed()で圧縮保存とload
#保存
import numpy as np
np.savez_compressed(&quot;save_filename&quot;, train_x=train_x, train_y=train_y)
#読み込み
import numpy as np
with np.load(&quot;save_filename.npz&quot;) as data:
train_x = data[train_x]
train_y = data[train_y]
print(train_x.shape)
(202599, 218, 178, 3)
print(train_y.shape)
(202599, 40)


# Page. 10

![Page Image](https://bcdn.docswell.com/page/9E2G6G2RER.jpg)

ファイル保存の比較
保存（sec） 読み込み（sec） 作成ファイルサイズ
pickle
np.savez
np.savez_compressed
247.522
102.856
553.789
153.720
107.335
114.486
23593058963 (23.593GB)
23593059354 (23.593GB)
15798570036 (15.798GB)
元の2つのNumPy配列の使用メモリサイズは合計で 2359305900 (23.593GB)
時間計測は5回平均
時間がかかる作成保存は最初の1回だけなので、
私はファイルサイズが小さい np.savez_compressedを使ってます。


# Page. 11

![Page Image](https://bcdn.docswell.com/page/D7YV9VY57M.jpg)

NumPyで検索・抽出
属性ラベルも一緒に保存したので、CelebAから画像の検索・抽出を行ってみました。
検索するため train_yを転置します。
print(train_y.shape) (202599, 40)
yt = train_y.transpose()
print(yt.shape) (40, 202599)
検索は np.where() を使います
※各値は正負（1,0）の2値
Eyeglasses（メガネ yt[15]）、Wearing_Earrings(イヤリング着用 yt[34])、
Wearing_Necklace(ネックレス着用 yt[37]）、Young（若い yt[39])の
Male(男性でなく女性は yt[20]==0) で条件（and）検索します。


# Page. 12

![Page Image](https://bcdn.docswell.com/page/VENMLMP4J8.jpg)

NumPyの検索と抽出
index = np.where((yt[15] == 1) &amp; (yt[34] == 1) &amp; (yt[37] == 1)
&amp; (yt[39] == 1) &amp; (yt[20] == 0))
print(len(index[0]))
64
条件に合致するインデックス64件を抽出しました。
print(index[0])
[672 7016 7413 8059 ...]
抽出したインデックスから該当画像データは
train_x[672], train_x[7016]...などです。
train_x[672]
train_x[7016]


# Page. 13

![Page Image](https://bcdn.docswell.com/page/Y79N4N3473.jpg)

［参考］CelebA 顔属性値（正負の2値）
5_o_Clock_Shadow
Arched_Eyebrows
Attractive
Bags_Under_Eyes
Bald
Bangs
Big_Lips
Big_Nose
Black_Hair
Blond_Hair
Blurry
Brown_Hair
Bushy_Eyebrows
Chubby
Double_Chin
Eyeglasses
Goatee
Gray_Hair
Heavy_Makeup
High_Cheekbones
Male
Mouth_Slightly_Open
Mustache
Narrow_Eyes
No_Beard
Oval_Face
Pale_Skin
Pointy_Nose
Receding_Hairline
Rosy_Cheeks
Sideburns
Smiling
Straight_Hair
Wavy_Hair
Wearing_Earrings
Wearing_Hat
Wearing_Lipstick
Wearing_Necklace
Wearing_Necktie
Young


