zoukankan      html  css  js  c++  java
  • 数据输入

    数据输入

    深度学习是一种数据驱动的技术,为了兼顾易用性与效率, OneFlow 提供了两种“喂”数据给神经网络的方法:

    • 一种方法,可以直接将 NumPy ndarray 对象作为参数传递给作业函数。也就是说 OneFlow 能够直接使用 NumPy 数据作为输入。
    • 另外一种方法是使用 OneFlow 的 DataLoader 及其相关算子,从文件系统加载特定格式的数据集并做预处理。

    直接使用 NumPy 数据的方式简单方便,但仅适合小数据量的情况。因为当数据量过大时,可能在准备 NumPy 数据上遭遇效率瓶颈。因此,这种方式比较适合项目的初始阶段,快速验证和改进算法;

    OneFlow 的 DataLoader 内部采用了多线程和数据流水线等技术使得数据加载、数据预处理等效率更高。但是,需要为已经支持的格式准备数据集或为 OneFlow 暂时还不支持的格式开发自己的 DataLoader。因此,推荐在成熟的项目中使用。

    使用 Numpy 数据作为输入

    运行例子

    在 Oneflow 中,可以直接使用 NumPy 类型的数据作为作业函数的输入,下面是一个完整的例子:

    # feed_numpy.py

    import numpy as np

    import oneflow as flow

    import oneflow.typing as tp

    from typing import Tuple

     

     

    @flow.global_function(type="predict")

    def test_job(

        images: tp.Numpy.Placeholder((32, 1, 28, 28), dtype=flow.float),

        labels: tp.Numpy.Placeholder((32,), dtype=flow.int32),

    ) -> Tuple[tp.Numpy, tp.Numpy]:

        # do something with images or labels

        return (images, labels)

     

     

    if __name__ == "__main__":

        images_in = np.random.uniform(-10, 10, (32, 1, 28, 28)).astype(np.float32)

        labels_in = np.random.randint(-10, 10, (32,)).astype(np.int32)

        images, labels = test_job(images_in, labels_in)

        print(images.shape, labels.shape)

    下载完整代码:feed_numpy.py ,然后用 python 执行即可:

    python feed_numpy.py

    将得到如下结果

    (32, 1, 28, 28) (32,)

    代码解读

    在上面的代码中,定义了一个作业函数 test_job(),其输入为 images 和 labels ,并且通过注解(注意形参后面是“:”,而不是“=”。),指定了数据的形状与数据类型。

    因此,例子中按照作业函数对形状和数据类型的要求随机生成了 NumPy数据:images_in 和 labels_in :

      images_in = np.random.uniform(-10, 10, (32, 1, 28, 28)).astype(np.float32)

      labels_in = np.random.randint(-10, 10, (32, )).astype(np.int32)

    并在调用作业函数是,直接将 NumPy 数据 images_in 和 labels_in 作为参数传递:

    images, labels = test_job(images_in, labels_in)

    代码中的 oneflow.typing.Numpy.Placeholder 是 NumPy ndarray 对象的占位符,OneFlow 中还有多种占位符,可以表示更复杂的 NumPy 数据形式。具体可以参考作业函数的定义与调用

    使用 DataLoader 及相关算子

    在 oneflow.data 模块下,有用于加载数据集的 DataLoader 算子以及相关的数据预处理算子。DataLoader 一般以 data.xxx_reader 的形式命名,如目前已有的 data.ofrecord_reader 和 data.coco_reader,分别支持 OneFlow 原生的 OFRecord 格式的文件和 COCO 数据集。

    此外,在该模块下,还包含有其它数据预处理算子,用于处理 DataLoader 加载后的数据。如下文代码使用的 data.OFRecordImageDecoderRandomCrop 用于图片随机裁剪,data.OFRecordRawDecoder 用于图片解码。具体使用方法可以查阅 API 文档

    运行例子

    以下的例子,读取 OFRecord 数据格式文件,处理的是 ImageNet 数据集中的图片。完整代码可以点此下载:of_data_pipeline.py

    这个脚本,需要一个 OFRecord 数据集,可以自己制作一个。

    或者下载已经准备好的 part-00000 数据文件,它包含了64张图片。并且,将脚本中的 path/to/ImageNet/ofrecord 替换为 part-00000 文件 所在的目录,然后运行脚本。

    以下是使用预先准备的数据集运行脚本的例子:

    wget https://oneflow-public.oss-cn-beijing.aliyuncs.com/online_document/docs/basics_topics/part-00000

    sed -i "s:path/to/ImageNet/ofrecord:./:" of_data_pipeline.py

    python3 of_data_pipeline.py

    将得到下面的输出:

    (64, 3, 224, 224) (64,)

    代码解读

    使用 OneFlow DataLoader 一般为两个阶段: 数据加载 和 数据预处理 。

    脚本中 flow.data.ofrecord_reader 负责从文件系统中加载数据到内存。

        ofrecord = flow.data.ofrecord_reader(

            "path/to/ImageNet/ofrecord",

            batch_size=batch_size,

            data_part_num=1,

            part_name_suffix_length=5,

            random_shuffle=True,

            shuffle_after_epoch=True,

        )

    需要指定 OFRecord 格式文件所在的目录,和一些其他参数,请参考 data.ofrecord_reader

    DataLoader 的返回值,如果是简单的基本数据类型,那么可以直接作为下游的算子的输入,否则,需要继续调用数据预处理算子,进行预处理。

    比如,在以上脚本中:

        image = flow.data.OFRecordImageDecoderRandomCrop(

            ofrecord, "encoded", color_space=color_space

        )

        label = flow.data.OFRecordRawDecoder(

            ofrecord, "class/label", shape=(), dtype=flow.int32

        )

        rsz = flow.image.Resize(

            image, resize_x=224, resize_y=224, color_space=color_space

        )

        rng = flow.random.CoinFlip(batch_size=batch_size)

        normal = flow.image.CropMirrorNormalize(

            rsz,

            mirror_blob=rng,

            color_space=color_space,

            mean=[123.68, 116.779, 103.939],

            std=[58.393, 57.12, 57.375],

            output_dtype=flow.float,

        )

    OFRecordImageDecoderRandomCrop 负责图片解码并随机做了裁剪,OFRecordRawDecoder 负责从 ofrecord 对象中直接解码出标签, image.Resize 把裁剪后的图片调整成224x224的大小, CropMirrorNormalize 把图片进行了正则化。

    支持更多格式的 DataLoader

    OneFlow 提供了一些 DataLoader 和预处理的算子,详细请参考 oneflow.data。未来会不断丰富和优化这些算子,用户也可以参考 这篇文章 自定义 DataLoader 满足特定的需求。

    人工智能芯片与自动驾驶
  • 相关阅读:
    24.Spring-Boot-Actuator与Spring-Security整合应用
    Spring Boot 和 Spring 到底有啥区别?用了这么久,你知道吗?
    一文,5 分钟搞明白 MySQL 是如何利用索引的!
    大厂面试必问的Spring全家桶 4 大开源框架,思维脑图全总结,终于出来了
    这些SQL错误用法,如果经常犯,说明你的水平还很low...
    新技能 MyBatis 千万数据表,快速分页!
    牛逼!在IDEA里搞Spring Boot Mybatis反向工程,太爽咯~
    有了 HTTP 协议,为什么还要 RPC 协议,两者有什么区别?
    把 Spring Cloud 给拆了!详解每个组件的作用,值得收藏!
    27个阿里 Java 开源项目,值得收藏!
  • 原文地址:https://www.cnblogs.com/wujianming-110117/p/14403182.html
Copyright © 2011-2022 走看看