OFRecord 数据格式
OFRecord 数据格式
深度学习应用需要复杂的多阶段数据预处理流水线,数据加载是流水线的第一步,OneFlow 支持多种格式数据的加载,其中 OFRecord 格式是 OneFlow 原生的数据格式。
OFRecord 的格式定义参考了 TensorFlow 的 TFRecord,熟悉 TFRecord 的用户,可以很快上手 OneFlow 的 OFRecord。
本文将介绍:
- OFRecord 使用的数据类型
- 如何将数据转化为 OFRecord 对象并序列化
- OFRecord 文件格式
有助于学习加载与准备 OFRecord 数据集。
OFRecord 相关数据类型
OneFlow 内部采用Protocol Buffers 描述 OFRecord 的序列化格式。相关的 .proto 文件在 oneflow/core/record/record.proto 中,具体定义如下:
syntax = "proto2";
package oneflow;
message BytesList {
repeated bytes value = 1;
}
message FloatList {
repeated float value = 1 [packed = true];
}
message DoubleList {
repeated double value = 1 [packed = true];
}
message Int32List {
repeated int32 value = 1 [packed = true];
}
message Int64List {
repeated int64 value = 1 [packed = true];
}
message Feature {
oneof kind {
BytesList bytes_list = 1;
FloatList float_list = 2;
DoubleList double_list = 3;
Int32List int32_list = 4;
Int64List int64_list = 5;
}
}
message OFRecord {
map<string, Feature> feature = 1;
}
先对以上的重要数据类型进行解释:
- OFRecord: OFRecord 的实例化对象,可用于存储所有需要序列化的数据。它由任意多个 string->Feature 的键值对组成;
- Feature: Feature 可存储 BytesList、FloatList、DoubleList、Int32List、Int64List 各类型中的任意一种;
- OFRecord、Feature、XXXList 等类型,均由 Protocol Buffers 生成对应的同名接口,使得可以在 Python 层面构造对应对象。
转化数据为 Feature 格式
可以通过调用 ofrecord.xxxList 及 ofrecord.Feature 将数据转为 Feature 格式,为了更加方便,需要对 protocol buffers 生成的接口进行简单封装:
import oneflow.core.record.record_pb2 as ofrecord
def int32_feature(value):
if not isinstance(value, (list, tuple)):
value = [value]
return ofrecord.Feature(int32_list=ofrecord.Int32List(value=value))
def int64_feature(value):
if not isinstance(value, (list, tuple)):
value = [value]
return ofrecord.Feature(int64_list=ofrecord.Int64List(value=value))
def float_feature(value):
if not isinstance(value, (list, tuple)):
value = [value]
return ofrecord.Feature(float_list=ofrecord.FloatList(value=value))
def double_feature(value):
if not isinstance(value, (list, tuple)):
value = [value]
return ofrecord.Feature(double_list=ofrecord.DoubleList(value=value))
def bytes_feature(value):
if not isinstance(value, (list, tuple)):
value = [value]
if not six.PY2:
if isinstance(value[0], str):
value = [x.encode() for x in value]
return ofrecord.Feature(bytes_list=ofrecord.BytesList(value=value))
创建 OFRecord 对象并序列化
在下例子中,将创建有2个 feature 的 OFRecord 对象,并且调用它的 SerializeToString 方法序列化。
obserations = 28 * 28
f = open("./dataset/part-0", "wb")
for loop in range(0, 3):
image = [random.random() for x in range(0, obserations)]
label = [random.randint(0, 9)]
topack = {
"images": float_feature(image),
"labels": int64_feature(label),
}
ofrecord_features = ofrecord.OFRecord(feature=topack)
serilizedBytes = ofrecord_features.SerializeToString()
通过以上例子,可以总结序列化数据的步骤:
- 将需要序列化的数据,通过调用 ofrecord.Feature 及 ofrecord.XXXList 转为 Feature 对象;
- 将上一步得到的各个 Feature 对象,以 string->Feature 键值对的形式,存放在 Python 字典中;
- 调用 ofrecord.OFRecord 创建 OFRecord 对象
- 调用 OFRecord 对象的 SerializeToString 方法得到序列化结果
序列化的结果,可以存为 ofrecord 格式的文件。
OFRecord 格式的文件
将 OFRecord 对象序列化后按 OneFlow 约定的格式存文件,就得到 OFRecord文件 。
1个 OFRecord 文件中可存储多个 OFRecord 对象,OFRecord 文件可用于 OneFlow 数据流水线,具体操作可见加载与准备 OFRecord 数据集
OneFlow 约定,对于 每个 OFRecord 对象,用以下格式存储:
uint64 length
byte data[length]
即头8个字节存入数据长度,然后存入序列化数据本身。
length = ofrecord_features.ByteSize()
f.write(struct.pack("q", length))
f.write(serilizedBytes)
代码
以下完整代码展示如何生成 OFRecord 文件,并调用 protobuf 生成的 OFRecord 接口手工读取 OFRecord 文件中的数据。
实际上,OneFlow 提供了 flow.data.decode_ofrecord 等接口,可以更方便地提取 OFRecord 文件(数据集)中的内容。详细内容请参见加载与准备 OFRecord 数据集。
将 OFRecord 对象写入文件
以下脚本,模拟了3个样本,每个样本为28*28的图片,并且包含对应标签。将三个样本转化为 OFRecord 对象后,按照 OneFlow 约定格式,存入文件。
从 OFRecord 文件中读取数据
以下脚本,读取上例中生成的 OFRecord 文件,调用 FromString 方法反序列化得到 OFRecord 对象,并最终显示数据:
OFRecord 数据格式的更多相关文章
- OFRecord 图片文件制数据集
OFRecord 图片文件制数据集 在 OFRecord 数据格式 和 加载与准备 OFRecord 数据集 中,分别学习了 OFRecord 数据格式,以及如何将其它数据集转为 OFRecord 数 ...
- OFRecord 数据集加载
OFRecord 数据集加载 在数据输入一文中知道了使用 DataLoader 及相关算子加载数据,往往效率更高,并且学习了如何使用 DataLoader 及相关算子. 在 OFrecord 数据格式 ...
- libsvm的数据格式及制作
1.libsvm数据格式 libsvm使用的训练数据和检验数据文件格式如下: [label] [index1]:[value1] [index2]:[value2] … [label] [index1 ...
- Data组件的JSON数据格式
{ // "@type" - 类型标识,"table"表明这个JSON是一个table结构的数据 "@type" : &qu ...
- 【原创】开源Math.NET基础数学类库使用(04)C#解析Matrix Marke数据格式
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...
- 【原创】开源Math.NET基础数学类库使用(05)C#解析Delimited Formats数据格式
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...
- 黄聪:phpexcel中文教程-设置表格字体颜色背景样式、数据格式、对齐方式、添加图片、批注、文字块、合并拆分单元格、单元格密码保护
首先到phpexcel官网上下载最新的phpexcel类,下周解压缩一个classes文件夹,里面包含了PHPExcel.php和PHPExcel的文件夹,这个类文件和文件夹是我们需要的,把class ...
- XML和JSON数据格式对比
概念 XML 扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语 ...
- VS快速生成JSON数据格式对应的实体
有固定好的Json数据格式,你还在手动敲对应的实体吗?有点low了!步入正题,这是一个json字符串,先去验证JSON数据格式(http://www.bejson.com/)如下: { & ...
随机推荐
- 怎样用SQL修改某个字段的部分内容
方法:update dede_addonarticle set body = replace(body,'#p#分页标题#e#',' ') where body like '%#p#分页标题#e#%'
- 逆向工程第001篇:解锁FIFA07传奇模式
FIFA07传奇难度的解锁,可以说是所有FIFA07玩家的终极目标.但是如果想以正常方式对其进行解锁,绝对是一件耗时耗力的工作.所以在这里我打算通过分析游戏存档文件的十六进制代码的方式,一步一步地找到 ...
- 缓冲区溢出分析第07课:MS06-040漏洞研究——静态分析
前言 我在之前的课程中讨论过W32Dasm这款软件中的漏洞分析与利用的方法,由于使用该软件的人群毕竟是小众群体,因此该漏洞的危害相对来说还是比较小的.但是如果漏洞出现在Windows系统中,那么情况就 ...
- sqlyog报错2058
报错描述 SQLyog连接mysql8.0时,SQLyog Ultimate显示报错信息并附带乱码 "错误号码2058,Plugin caching--sha2_passward could ...
- 数据表格 layui.table
layui官网-表单 自动渲染 方法渲染 table.render,cols中的field是后台传递的data map.put("data",stuService.selectSt ...
- MySQL redo与undo日志解析
前言: 前面文章讲述了 MySQL 系统中常见的几种日志,其实还有事务相关日志 redo log 和 undo log 没有介绍.相对于其他几种日志而言, redo log 和 undo log 是更 ...
- [DB] Flink 读 MySQL
思路 在 Flink 中创建一张表有两种方法: 从一个文件中导入表结构(Structure)(常用于批计算)(静态) 从 DataStream 或者 DataSet 转换成 Table (动态) pa ...
- [刷题] PTA 03-树3 Tree Traversals Again
用栈实现树遍历 1 #include<stdio.h> 2 #include<string.h> 3 #define MAXSIZE 30 4 5 int Pre[MAXSIZ ...
- 【打印机】无法连接 fail to connect to server cups 服务器错误 打印机
打印机 fail to connect to server cups 服务器错误兆芯 打印机 连不上了####message可知 服务fail## systemd: cups.servi ...
- 详解Linux中的cat文本输出命令用法
作系统 > LINUX > 详解Linux中的cat文本输出命令用法 Linux命令手册 发布时间:2016-01-14 14:14:35 作者:张映 我要评论 这篇 ...