• 2018百度之星开发者大赛-paddlepaddle学习(二)将数据保存为recordio文件并读取


    paddlepaddle将数据保存为recordio文件并读取

    因为有时候一次性将数据加载到内存中有可能太大,所以我们可以选择将数据转换成标准格式recordio文件并读取供我们的网络利用,接下来记录一下如何保存数据为recordio,并读取。

    将数据保存为RecordIO文件

    官网给出了例子

    import paddle.fluid as fluid
    import numpy
    
    def reader_creator():
        def __impl__():
            for i in range(1000):
                yield [
                         numpy.random.random(size=[3,224,224], dtype="float32"),
                         numpy.random.random(size=[1], dtype="int64")
                      ]
        return __impl__
    
    img = fluid.layers.data(name="image", shape=[3, 224, 224])
    label = fluid.layers.data(name="label", shape=[1], dtype="int64")
    feeder = fluid.DataFeeder(feed_list=[img, label], place=fluid.CPUPlace())
    
    BATCH_SIZE = 32
    reader = paddle.batch(reader_creator(), batch_size=BATCH_SIZE)
    fluid.recordio_writer.convert_reader_to_recordio_file(
       "train.recordio", feeder=feeder, reader_creator=reader)
    

    乍看也能看懂,非常合理,但是我这么保存以后就出现问题,在后面的读取数据的时候,一般我们会把[3,244,244]的图片送入卷积层,但是会报错,提示维数至少为4维,这点跟tensorflow一样,第一维是维数,那么应该怎么办呢?我的方法是:

        def reader_creator():
            def __impl__():
                for i in range(len(src_im_test)):
                    yield [
                        src_im_test[i],#shape=[3,244,244]
                        test_desmap[i],#shape=[3,244,244]
                        test_num[i] #shape=[1]
                    ]
    
            return __impl__
        img = fluid.layers.data(name="image", shape=[-1,3, 244, 244])#注意这里要加-1
        label = fluid.layers.data(name="label", shape=[-1,1,244, 244])
        num = fluid.layers.data(name="num", shape=[1], dtype='int64')
        feeder = fluid.DataFeeder(feed_list=[img, label, num], place=fluid.CPUPlace())
        reader = paddle.batch(reader_creator(), batch_size=1)
    	fluid.recordio_writer.convert_reader_to_recordio_file(
            "train.recordio", feeder=feeder, reader_creator=reader)
    

    这里把batch_size 设为1,后面读取的时候可以自由组batch_size。

    从RecordIO读取数据传入网络

    这里是官网代码

    import paddle.fluid as fluid
    
    file_obj = fluid.layers.open_files(
      filenames=["train.recordio"],
      shape=[[3, 224, 224], [1]],
      lod_levels=[0, 0],
      dtypes=["float32", "int64"],
      pass_num=100
    )
    
    image, label = fluid.layers.read_file(file_obj)
    

    对应于上面的官网例子,但是前面说过,这样子有问题(在我这里是不能送入卷积层),下面给出我的读取方法,和上面我的代码相对应:

    import paddle.fluid as fluid
    file_obj = fluid.layers.open_files(
        filenames=["train.recordio"],
        shapes = [[-1,3, 244, 244], [-1,1,244, 244],[-1, 1]],
        dtypes=['float32','float32','int64'],
        lod_levels=[0, 0, 0],
    )
    file_obj = fluid.layers.batch(file_obj, batch_size=9)
    img, des_im, total_num = fluid.layers.read_file(file_obj)#这里的数据可以直接送入网络
    conv1 = fluid.layers.conv2d(img, 1, 1)#如果前面保存时不指定-1,这里就会报错
    loss =fluid.layers.reduce_mean(fluid.layers.square_error_cost(input=conv1,label=des_im))
    exe = fluid.Executor(fluid.CPUPlace())
    exe.run(fluid.default_startup_program())
    loss_v, = exe.run(fetch_list=[loss])
    print "loss is {}".format(loss_v)
    

    这里需要说明的是,从文件里面读取的数据已经是网络可以识别的数据格式了,有兴趣的话可以fluid.layers.data生成的变量一起print出来看一下,是一样的类型。

    结果:

    loss is [190564.94]
    

    注意,返回的是一个numpy array,这里可以修改exe.run里面的参数return_numpy=False来决定。

    我们再来看一下:

    num = exe.run(fetch_list=[total_num])
    print "num is {}".format(num)
    

    结果:

    num is [[17]
    		[13]
    		[61]
    		[9]
    		[8]
    		[9]
    		[17]
    		[29]
    		[9]]
    

    同样返回的也是numpy array,可以看出来是怎么组成batch的。

  • 相关阅读:
    构建企业级数据湖?Azure Data Lake Storage Gen2实战体验(中)
    构建企业级数据湖?Azure Data Lake Storage Gen2实战体验(上)
    寻觅Azure上的Athena和BigQuery (二):神奇的PolyBase
    寻觅Azure上的Athena和BigQuery(一):落寞的ADLA
    Azure中国CDN全球覆盖功能初探
    第一次负责项目感悟
    C#读取静态类常量属性和值
    std::thread使用
    C#泛型编程
    C++模板类
  • 原文地址:https://www.cnblogs.com/bobxxxl/p/9332429.html
Copyright © 2020-2023  润新知