MXNET笔记(二)准备数据

MXNET并不直接读入图像,而是读入其自定义的一种格式。为了生成这种格式,需要利用/mxnet/tools/im2rec.py工具来对数据库图像进行处理而生成。我现在手头没有现成的数据库可以使用,而现在一般的数据库又太大了,所以我把Rec格式的MNIST数据库还原成图像文件。

#利用mxnet提供的代码下载MNIST数据库
import numpy as np
import os
import urllib
import gzip
import struct
def download_data(url, force_download=True): 
    fname = url.split("/")[-1]
    if force_download or not os.path.exists(fname):
        urllib.urlretrieve(url, fname)
    return fname

def read_data(label_url, image_url):
    with gzip.open(download_data(label_url)) as flbl:
        magic, num = struct.unpack(">II", flbl.read(8))
        label = np.fromstring(flbl.read(), dtype=np.int8)
    with gzip.open(download_data(image_url), 'rb') as fimg:
        magic, num, rows, cols = struct.unpack(">IIII", fimg.read(16))
        image = np.fromstring(fimg.read(), dtype=np.uint8).reshape(len(label), rows, cols)
    return (label, image)

path='http://yann.lecun.com/exdb/mnist/'
(train_lbl, train_img) = read_data(
    path+'train-labels-idx1-ubyte.gz', path+'train-images-idx3-ubyte.gz')
(val_lbl, val_img) = read_data(
    path+'t10k-labels-idx1-ubyte.gz', path+'t10k-images-idx3-ubyte.gz')
#---------------------------------------------------------------------------------------------#
#保存图像需要
import imageio
#记录每一类样本的数目,并将其作为文件名
file_count = [0]*10
#总共60000个样本,循环保存
for i in range(0,60000):
    #如果文件名不存在,创建
    if not os.path.exists(str(train_lbl[i])):
        os.makedirs(str(train_lbl[i]))
    #样本数目+1
    file_count[train_lbl[i]] = file_count[train_lbl[i]] + 1
    #获取文件保存的路径
    path = os.path.join(os.path.curdir,str(train_lbl[i])) 
    #生成文件名
    file_name = str(path + "/" + str(file_count[train_lbl[i]]) + ".jpg")
    #保存文件
    imageio.imwrite(file_name,train_img[i])

经过上面的处理,我们可以得到十个文件夹,文件夹的文件名就是图像的label。我已经将打包好的数据上传到了CSDN,有需要的可以点击CSDN链接

现在使用刚刚提取出来的数据,再将其还原为rec格式。根据后面的操作发现在进行数据转化的时候需要用到cv2模块,所以,首先用pip安装opencv

pip install opencv-python


在得到了原始数据,也安装了opencv module以后,就可以使用mxnet文件夹下/tools/im2re.py程序来完成:

# 我已经将im2rec.py文件复制到了需要操作的文件夹下,这样方便一点
python im2rec.py  --recursive=Ture --exts=.jpg --list=True MNIST MNIST
# --recursive=Ture表示对图像文件夹下的所有文件进行递归操作
# --exts=.jpg 表示图像文件的后缀为jpg
# --list=True表示,首先生成一个list文件
# MNIST表示生成的list文件的前缀,后缀默认为.lst
# MNIST表示保存图像的文件夹

值得注意的是这个im2re.py 文件存在一个Bug,主要是-exts这个选项这里需要修改一下:

#Pay attention, different from the source code here
cgroup.add_argument('--exts', type=list, action='append', default=['.jpeg', '.jpg'],
#增加action = 'append',这样就可以接受新的参数

如果我们打开生成的MNIST.lst文件,可以得到看到像下面的样子:

647   0.000000  MNIST/0/1581.jpg
21679   3.000000    MNIST/3/375.jpg
39270   6.000000    MNIST/6/3927.jpg
41692   6.000000    MNIST/6/780.jpg
23150   3.000000    MNIST/3/5073.jpg
44133   7.000000    MNIST/7/2978.jpg
32353   5.000000    MNIST/5/2580.jpg

每行最后一项是某图像的位置,倒数第二项是对应的label,也就是该类文件夹的名字,第一项是该文件对于的一个index。得到这list以后,我们可以进一步生成rec文件了。根据im2rec.py文件的源代码,这一过程可以使用多线程也可以使用单线程,但是多线程往往会出错,我的办法是直接将多线程的部分注释掉,直接用单线程处理,修改im2rec.pymain函数部分如下:

if __name__ == '__main__':
    args = parse_args()
    if args.list:
        make_list(args)
    else:
        if os.path.isdir(args.prefix):
            working_dir = args.prefix
        else:
            working_dir = os.path.dirname(args.prefix)
        files = [os.path.join(working_dir, fname) for fname in os.listdir(working_dir)
                    if os.path.isfile(os.path.join(working_dir, fname))]
        count = 0
        for fname in files:
            if fname.startswith(args.prefix) and fname.endswith('.lst'):
                print('Creating .rec file from', fname, 'in', working_dir)
                count += 1
                image_list = read_list(fname)
                # -- write_record -- #
                #if args.num_thread > 1 and multiprocessing is not None:
                #    q_in = [multiprocessing.Queue(1024) for i in range(args.num_thread)]
                #    q_out = multiprocessing.Queue(1024)
                #    read_process = [multiprocessing.Process(target=read_worker, args=(args, q_in[i], q_out)) \
                #                    for i in range(args.num_thread)]
                #    for p in read_process:
                #        p.start()
                #    write_process = multiprocessing.Process(target=write_worker, args=(q_out, fname, working_dir))
                #    write_process.start()

                #    for i, item in enumerate(image_list):
                #        q_in[i % len(q_in)].put((i, item))
                #    for q in q_in:
                #        q.put(None)
                #    for p in read_process:
                #        p.join()

                #    q_out.put(None)
                #    write_process.join()
                #else:
                #print('multiprocessing not available, fall back to single threaded encoding')
                import Queue
                q_out = Queue.Queue()
                fname = os.path.basename(fname)
                fname_rec = os.path.splitext(fname)[0] + '.rec'
                fname_idx = os.path.splitext(fname)[0] + '.idx'
                record = mx.recordio.MXIndexedRecordIO(os.path.join(working_dir, fname_idx),
                                                       os.path.join(working_dir, fname_rec), 'w')
                cnt = 0
                pre_time = time.time()
                for i, item in enumerate(image_list):
                    #打印文件列表
                    print( "current i is " + str(i))
                    print( "current item is " + str(item))
                    image_encode(args, i, item, q_out)
                    if q_out.empty():
                        continue
                    _, s, _ = q_out.get()
                    record.write_idx(item[0], s)
                    if cnt % 1000 == 0:
                        cur_time = time.time()
                        print('time:', cur_time - pre_time, ' count:', cnt)
                        pre_time = cur_time
                    cnt += 1
        if not count:
            print('Did not find and list file with prefix %s'%args.prefix)

现在再次使用im2rec.py文件来生成rec文件:

python im2rec.py  MNIST.lst  MNIST
#  MNIST.lst是对应的list文件
# MNIST 是最后保存rec文件的位置

最后,在当前文件夹下就生成了MNIST.rec文件。
如果Opencv的版本为3.x的话,可能会出现下面的错误,只要将Opencv的版本退回到2.x版本就可以了

Segmentation fault (core dumped)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容