mxnet record 打包 Array
Preface
这个打包设计得有些笨重(也可能是自己还没发现),每次要操作record的时候总想避开那些API,主要是Header那段,感觉鸡肋,还有默认的有损压缩((⊙﹏⊙)b)。。。也不知道是不是仅针对uint8类型的。总之两次用API都不想考虑,但没有其他的打包array的方式了。
实际上write_idx和read_idx配合就已经能够完成很多任务了,就是(TM)不接收array类型,这次和它干到底。
Example
import mxnet as mx
import numpy as np
import cPickle as cpk
m= np.random.uniform(-10,10,(3,4,5))
n= np.random.uniform(-10,10,(3,4,5))
rec = mx.recordio.MXIndexedRecordIO('test.idx','test.rec','w')
rec.write_idx(0,cpk.dumps(m))
rec.write_idx(1,cpk.dumps(n))
rec.close()
rec = mx.recordio.MXIndexedRecordIO('test.idx','test.rec','r')
m_r = cpk.loads(rec.read_idx(0))
n_r = cpk.loads(rec.read_idx(1))
rec.close()
m-m_r
n-n_r
mission succeed 😃
21 Jul, 2017 记
提升的方案
cPickle
方案的一个明显劣势就是对输入类型的要求过低,神马都能序列化,导致生成的数据量较大,最近到了几乎无法忍受的地步。又开始希望从numpy
本身着手。
一个可行方案是np.dumps/np.loads
(现在才想到,(⊙﹏⊙)b)
Experiment
做些对比看看两者的存储效率情况吧。
import numpy as np
import cPickle as cpk
mm=np.random.randint(-1,10,(4,5,6))
ss=mm.dumps()
re_mm=np.loads(ss)
np.sum(np.abs(re_mm-mm))
# 0
len(ss)
# 616
len(cpk.dumps(mm))
# 2054
三倍以上的优势!并且这种方案也不需要考虑维数问题。