jqy 提供的 flickr 数据里[4],label 只有 51K
,而自己做的数据[5] label 有 3.7M
(当时不懂事,存了 float64)。但后来做 nuswide[6] 时即使以 int8 存,还是比 jqy 提供的数据大。应该是用了位压缩。
packbits, unpackbits
对二进制数据(只有 0/1),如 label、BoW 形式的 text,numpy 可以用 packbits 压缩,这样存就是 59K
= 3.7 * 1024 / 64,接近了。这样有点麻烦的地方在于:以后读出来,要用 unpackbits 还原先,但 jqy 给的 .mat 数据不用的,直接读出来就行。
savemat
scipy.io.savemat 有个参数是 do_compression
,设为 True 之后存成 .mat,就是 51K
。推荐。
Code
import os
import numpy as np
import scipy.io as sio
# 换成 uint8 先
L = np.load("labels.npy").astype(np.uint8)
# 1. 用 (un)packbits
L_c = np.packbits(L, axis=1) # 压缩
print(L_c.dtype)
np.save("labels.pack.npy", L_c)
L_r = np.unpackbits(L_c, axis=1) # 复原
print("diff:", np.not_equal(L, L_r).sum())
# 2. savemat 时 do_compression
sio.savemat("labels.compress.mat", {"labels": L}, do_compression=True)