zoukankan      html  css  js  c++  java
  • 『MXNet』im2rec脚本使用以及数据读取

    一、im2rec用法简介

    首先看文档:

    usage: im2rec.py [-h] [--list] [--exts EXTS [EXTS ...]] [--chunks CHUNKS]
                     [--train-ratio TRAIN_RATIO] [--test-ratio TEST_RATIO]
                     [--recursive] [--no-shuffle] [--pass-through]
                     [--resize RESIZE] [--center-crop] [--quality QUALITY]
                     [--num-thread NUM_THREAD] [--color {-1,0,1}]
                     [--encoding {.jpg,.png}] [--pack-label]
                     prefix root
    
    Create an image list or make a record database by reading from an image list
    
    positional arguments:
      prefix                prefix of input/output lst and rec files.
      root                  path to folder containing images.
    
    optional arguments:
      -h, --help            show this help message and exit
    
    Options for creating image lists:
      --list                If this is set im2rec will create image list(s) by
                            traversing root folder and output to <prefix>.lst.
                            Otherwise im2rec will read <prefix>.lst and create a
                            database at <prefix>.rec (default: False)
      --exts EXTS [EXTS ...]
                            list of acceptable image extensions. (default:
                            ['.jpeg', '.jpg', '.png'])
      --chunks CHUNKS       number of chunks. (default: 1)
      --train-ratio TRAIN_RATIO
                            Ratio of images to use for training. (default: 1.0)
      --test-ratio TEST_RATIO
                            Ratio of images to use for testing. (default: 0)
      --recursive           If true recursively walk through subdirs and assign an
                            unique label to images in each folder. Otherwise only
                            include images in the root folder and give them label
                            0. (default: False)
      --no-shuffle          If this is passed, im2rec will not randomize the image
                            order in <prefix>.lst (default: True)
    
    Options for creating database:
      --pass-through        whether to skip transformation and save image as is
                            (default: False)
      --resize RESIZE       resize the shorter edge of image to the newsize,
                            original images will be packed by default. (default:
                            0)
      --center-crop         specify whether to crop the center image to make it
                            rectangular. (default: False)
      --quality QUALITY     JPEG quality for encoding, 1-100; or PNG compression
                            for encoding, 1-9 (default: 95)
      --num-thread NUM_THREAD
                            number of thread to use for encoding. order of images
                            will be different from the input list if >1. the input
                            list will be modified to match the resulting order.
                            (default: 1)
      --color {-1,0,1}      specify the color mode of the loaded image. 1: Loads a
                            color image. Any transparency of image will be
                            neglected. It is the default flag. 0: Loads image in
                            grayscale mode. -1:Loads image as such including alpha
                            channel. (default: 1)
      --encoding {.jpg,.png}
                            specify the encoding of the images. (default: .jpg)
      --pack-label          Whether to also pack multi dimensional label in the
                            record file (default: False)
    

    必须要填写的参数有prefix、和root两个路径参数,

    prefix:生成文件文件夹目录

         可以指定为.lst的路径,这样生成文件会和.lst同一级别,且会根据.lst中的条目生成二进制文件

    root:图片文件目录,默认的话里面是类别文件夹,类别名做label,每个文件夹存储图像

              如果指定了.lst,则每个图片路径变为root路径+.lst中每个图片的路径

    --pack-label:在指定了.lst后很有用,此时允许label为高维度(主要是label可以设置为数组)

    实际上我们之前也介绍过,.lst文件并不是必须的,仅有.rec和.idx就可以满足需要(标签存储在.rec中),它是一个辅助(人工生成.lst指导.rec生成),或者作为一个结果展示(自动生成.rec时选择同时生成.lst)。

    【注意】,最新版本的pack-label等bool参数已经变成了开关型参数,即输入--pack-label表示原意True。

    使用简介

    二、通用图像数据存储以及迭代读取方式

    1、生成.lst文件

    具体格式如下,各列之间使用' '分隔第一列为索引最后一列为文件路径,这两列是固定的,中间为标签列,列数不固定。

    0    2    5    0    0.0    0.0    0.3    0.3    2007_000129.jpg
    1    2    5    1    0.1    0.1    0.4    0.4    2007_000027.jpg
    2    2    5    2    0.2    0.2    0.5    0.5    2007_000123.jpg
    3    2    5    3    0.3    0.3    0.6    0.6    2007_000063.jpg
    4    2    5    4    0.4    0.4    0.7    0.7    2007_000033.jpg
    5    2    5    5    0.5    0.5    0.8    0.8    2007_000121.jpg
    6    2    5    6    0.6    0.6    0.9    0.9    2007_000042.jpg
    7    2    5    7    0.7    0.7    1.0    1.0    2007_000039.jpg
    8    2    5    8    0.8    0.8    1.1    1.1    2007_000032.jpg
    9    2    5    9    0.9    0.9    1.2    1.2    2007_000061.jpg
    10    2    5    10    1.0    1.0    1.3    1.3    2007_000068.jpg
    11    2    5    11    1.1    1.1    1.4    1.4    2007_000170.jpg

    代码如下,

    import os
    name_list = [f for f in os.listdir('./') if f.endswith('jpg')]
    with open('my_test.lst', 'w+') as f:  
        for i, n in enumerate(name_list):  
            f.write(  
                str(i) + '	' +  # idx
                '2' + '	' + '5' + '	' +  # 头信息长度(不含索引), 每个obj长度
                str(i) + '	' +  # class  
                str((i / 10)) + '	' + str((i / 10)) + '	' + str(((i + 3) / 10)) + '	' +str(((i + 3) / 10)) + '	' +  
                # xmin, ymin, xmax, ymax  
                n + '
    '
                # image path
            )
    

    2、创建.rec

    调用子进程创建rec文件:

    import subprocess
    import mxnet as mx
    
    im2rec_path = os.path.join(mx.__path__[0], 'tools/im2rec.py')  # 寻找im2rec.py路径
    # final validation - sometimes __path__ (or __file__) gives 'mxnet/python/mxnet' instead of 'mxnet'
    if not os.path.exists(im2rec_path):
        im2rec_path = os.path.join(os.path.dirname(os.path.dirname(mx.__path__[0])), 'tools/im2rec.py')
        
    subprocess.check_call(["python", im2rec_path,
            os.path.abspath('my_test.lst'), os.path.abspath('./'), "--pack-label"])
    

    返回0表示进程顺利结束。

    3、读取.rec

    这里我门介绍一下几种读取API使用方式,ImageIter要求标签列数固定,label_width=7表示中间7列为标签列,我们打印了标签作示范:

    data_iter = mx.image.ImageIter(batch_size=4, 
                                  resize=30,
                                  label_width=7,
                                  data_shape=(3, 30, 60),# depth,height,width
                                  path_imgrec="./my_test.rec",
                                  path_imgidx="./my_test.idx" )
    data_iter.reset()
    batch = data_iter.next()
    img, labels = batch.data[0], batch.label[0]
    print(labels)
    [[ 2.          5.          0.          0.          0.          0.30000001  0.30000001]
     [ 2.          5.          1.          0.1         0.1         0.40000001  0.40000001]
     [ 2.          5.          2.          0.2         0.2         0.5         0.5       ]
     [ 2.          5.          3.          0.30000001  0.30000001  0.60000002  0.60000002]]
    <NDArray 4x7 @cpu(0)>

    简明易懂,不过对于很多目标检测任务来说,object数目并不一致,中间的label列也就不一致,此时下面的API泛用性更好:

    rec = mx.image.ImageDetIter(
                path_imgrec     = './my_test.rec',
                path_imglist    = '',
                batch_size      = 4,
                data_shape      = (3, 300, 300))
    rec.next().label[0]
    

     InageDetIter没有label_width参数,其扣除首末两列,中间都作为待定标签列:0列-索引列,1列-头信息列数,2列-每个对象信息列数,3~(n-1)列-标签列,n列-图像路径。

    输出时会在1~n-1列中先扣除第二列数字的列数(本例中1、2两列被扣除),之后的列数才是标签:

    [[[ 0.          0.          0.          0.30000001  0.30000001]]
    
     [[ 1.          0.1         0.1         0.40000001  0.40000001]]
    
     [[ 2.          0.2         0.2         0.5         0.5       ]]
    
     [[ 3.          0.30000001  0.30000001  0.60000002  0.60000002]]]
    <NDArray 4x1x5 @cpu(0)>

    下面我们测试一下各张图片label长度不等的情况:

    im2rec_path = os.path.join(mx.__path__[0], 'tools/im2rec.py')  # 寻找im2rec.py路径
    # final validation - sometimes __path__ (or __file__) gives 'mxnet/python/mxnet' instead of 'mxnet'
    if not os.path.exists(im2rec_path):
        im2rec_path = os.path.join(os.path.dirname(os.path.dirname(mx.__path__[0])), 'tools/im2rec.py')
        
    subprocess.check_call(["python", im2rec_path,
            os.path.abspath('my_test.lst'), os.path.abspath('./'), "--pack-label"])
    
    rec = mx.image.ImageDetIter(
                path_imgrec     = './my_test.rec',
                path_imglist    = '',
                batch_size      = 4,
                data_shape      = (3, 300, 300))
    rec.next().label[0]
    

    label长度不足的图片使用-1进行了补齐:

    [[[ 0.          0.          0.          0.30000001  0.30000001]
      [ 1.          2.          3.          4.          5.        ]]
    
     [[ 1.          0.1         0.1         0.40000001  0.40000001]
      [-1.         -1.         -1.         -1.         -1.        ]]
    
     [[ 2.          0.2         0.2         0.5         0.5       ]
      [-1.         -1.         -1.         -1.         -1.        ]]
    
     [[ 3.          0.30000001  0.30000001  0.60000002  0.60000002]
      [-1.         -1.         -1.         -1.         -1.        ]]]
    <NDArray 4x2x5 @cpu(0)>

    这一点上反倒是TensorFlow宽松一点,如果是None位置,在同一个会话中也可以通过不同的形状:

    import tensorflow as tf
    
    input_ = tf.placeholder(dtype=tf.int8, shape=(None,))
    
    with tf.Session() as sess:
        print(sess.run(input_, feed_dict={input_:(10,1)}))
        print(sess.run(input_, feed_dict={input_:(10,1,5)}))
    

    [10 1]

    [10 1 5] 

    也即是说在标签读取中,TensorFlow不需要补全-1,不同图片的标签形状不需要进行统一(见前面的TensorFlow-SSD标签处理一节)。

  • 相关阅读:
    Ubuntu 16.04 快速搭建ftp服务(转载)
    emmc协议简介(转载)
    产品经理简介
    小程序常用代码
    微信登录
    sql临时表与变量表
    备份数据库与还原数据库
    JQuery多个异步操作后执行(resolve,promise,when,done)
    苹果IOS下text-shadow与box-shadow失效的解决办法
    jS弹出新窗口被拦截的解决方法
  • 原文地址:https://www.cnblogs.com/hellcat/p/9373890.html
Copyright © 2011-2022 走看看