TFRecords详解

news2024/10/6 22:20:02

内容目录

  • TFRecords 是什么
  • 序列化(Serialization)
    • tf.data
  • 图像序列化(Serializing Images)
    • tf.Example
    • 函数封装
  • 小结

TFRecords 是什么

TPU拥有八个核心,充当八个独立的工作单元。我们可以通过将数据集分成多个文件或分片(shards),更有效地将数据传输给每个核心。这样,每个核心都可以在需要时获取数据的独立部分。

在TensorFlow中,用于分片的最方便的文件类型是TFRecord。TFRecord是一种包含字节串序列的二进制文件。数据在写入TFRecord之前需要被序列化(编码为字节串)。

在TensorFlow中,最方便的数据序列化方式是使用tf.Example封装数据。这是一种基于谷歌的protobufs的记录格式,但专为TensorFlow设计。它更或多或少地类似于带有一些类型注释的字典。

首先,我们将介绍如何使用TFRecords读取和写入数据。然后,我们将介绍如何使用tf.Example封装数据。

Protobufs(Protocol Buffers),也称为Protocol Buffers语言,是一种由Google开发的数据序列化格式。它可以用于结构化数据的序列化、反序列化以及跨不同平台和语言的数据交换。通过在一个结构体定义文件中定义数据结构,然后使用相应的编译器将其编译为特定语言的类,您可以方便地在不同的系统和编程语言之间共享和传输数据。

序列化(Serialization)

TFRecord是TensorFlow用于存储二进制数据的一种文件类型。TFRecord包含字节串序列。下面是一个非常简单的TFRecord示例:

import tensorflow as tf
import numpy as np

PATH = '/kaggle/working/data.tfrecord'

with tf.io.TFRecordWriter(path=PATH) as f:
    f.write(b'123') # write one record
    f.write(b'xyz314') # write another record

with open(PATH, 'rb') as f:
    print(f.read())

在这里插入图片描述

TFRecord是一系列字节,因此在将数据放入TFRecord之前,我们必须将数据转换为字节串。我们可以使用tf.io.serialize_tensor将张量转换为字节串使用tf.io.parse_tensor将其转换回张量。在解析字符串并将其再次转换为张量时,保持张量的数据类型(在这种情况下为tf.uint8)非常重要,因为您必须在解析过程中指定该数据类型。

x = tf.constant([[1, 2], [3, 4]], dtype=tf.uint8)
print('x:', x, '\n')

x_bytes = tf.io.serialize_tensor(x)
print('x_bytes:', x_bytes, '\n')

print('x:', tf.io.parse_tensor(x_bytes, out_type=tf.uint8))

在这里插入图片描述

tf.data

那么如何将数据集写入TFRecord呢?如果您的数据集由字节串组成,您可以使用data.TFRecordWriter。要再次读取数据集,可以使用data.TFRecordsDataset。

from tensorflow.data import Dataset, TFRecordDataset
from tensorflow.data.experimental import TFRecordWriter

# 创建一个小数据集
ds = Dataset.from_tensor_slices([b'abc', b'123'])

# 写入数据
writer = TFRecordWriter(PATH)
writer.write(ds)
    
# 读取数据集
ds_2 = TFRecordDataset(PATH)
for x in ds_2:
    print(x)

如果您的数据集由张量组成,请首先通过在数据集上映射tf.io.serialize_tensor来进行序列化。然后,在读取数据时,使用tf.io.parse_tensor来将字节串转换回张量。


features = tf.constant([
    [1, 2],
    [3, 4],
    [5, 6],
], dtype=tf.uint8)
ds = Dataset.from_tensor_slices(features)

# 对张量进行序列化操作
# 通过使用 `map` 函数,可以在数据集中的每个张量上应用 `tf.io.serialize_tensor` 进行序列化操作。
ds_bytes = ds.map(tf.io.serialize_tensor)

# 写入数据
writer = TFRecordWriter(PATH)
writer.write(ds_bytes)

# 读取数据(反序列化)
ds_bytes_2 = TFRecordDataset(PATH)
ds_2 = ds_2.map(lambda x: tf.io.parse_tensor(x, out_type=tf.uint8))

# They are the same!
for x in ds:
    print(x)
print()
for x in ds_2:
    print(x)

在这里插入图片描述

# 简化
def parse_serialized(serialized):
    return tf.io.parse_tensor(serialized, out_type=tf.uint8)  # 修改 out_type 根据您的张量数据类型

ds_3 = TFRecordDataset(PATH)

ds_3 = ds_3.map(parse_serialized)

for x in ds_3:
    print(x) #结果和上面一致

图像序列化(Serializing Images)

对图像进行序列化有多种方法:

  • 使用tf.io.serialize_tensor进行原始编码,使用tf.io.parse_tensor进行解码。
  • 使用tf.io.encode_jpeg进行JPEG编码,使用tf.io.decode_jpeg或tf.io.decode_and_crop_jpeg进行解码。
  • 使用tf.io.encode_png进行PNG编码,使用tf.io.decode_png进行解码。

只需确保使用与您选择的编码器相对应的解码器。通常,在使用TPU时,使用JPEG编码对图像进行编码是一个不错的选择,因为这可以对数据进行一定程度的压缩,从而可能提高数据传输速度。

from sklearn.datasets import load_sample_image
import matplotlib.pyplot as plt

# Load numpy array
image_raw = load_sample_image('flower.jpg')
print("Type {} with dtype {}".format(type(image_raw), image_raw.dtype))
plt.imshow(image_raw)
plt.title("Numpy")
plt.show()

在这里插入图片描述

from IPython.display import Image

# jpeg encode / decode
image_jpeg = tf.io.encode_jpeg(image_raw)
print("Type {} with dtype {}".format(type(image_jpeg), image_jpeg.dtype)) 
print("Sample: {}".format(image_jpeg.numpy()[:25])) #显示前25个编码后的字节
Image(image_jpeg.numpy())

在这里插入图片描述

image_raw_2 = tf.io.decode_jpeg(image_jpeg)

print("Type {} with dtype {}".format(type(image_raw_2), image_raw_2.dtype))
plt.imshow(image_raw_2)
plt.title("Numpy")
plt.show()

在这里插入图片描述

tf.Example

如果您有结构化数据,比如成对的图像和标签,该怎么办?TensorFlow还包括用于结构化数据的API,即tf.Example。它们基于谷歌的Protocol Buffers。

一个单独的Example旨在表示数据集中的一个实例,比如一个(图像、标签)对。每个Example都有Features,这被描述为特征名称和值的字典。一个值可以是BytesList、FloatList或Int64List,每个值都包装为单独的Feature。没有用于张量的值类型;相反,使用tf.io.serialize_tensor对张量进行序列化,通过numpy方法获取字节串,并将其编码为BytesList。

以下是我们如何对带有标签的图像数据进行编码的示例:

from tensorflow.train import BytesList, FloatList, Int64List
from tensorflow.train import Example, Features, Feature

# The Data
image = tf.constant([ # this could also be a numpy array
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
])
label = 0
class_name = "Class A"


# Wrap with Feature as a BytesList, FloatList, or Int64List
image_feature = Feature(
    bytes_list=BytesList(value=[
        tf.io.serialize_tensor(image).numpy(),
    ])
)
label_feature = Feature(
    int64_list=Int64List(value=[label]),
)
class_name_feature = Feature(
    bytes_list=BytesList(value=[
        class_name.encode()
    ])
)


# Create a Features dictionary
features = Features(feature={
    'image': image_feature,
    'label': label_feature,
    'class_name': class_name_feature,
})

# Wrap with Example
example = Example(features=features)

print(example)

在这里插入图片描述
查看标签内容
![[Pasted image 20230810140233.png]]![[Pasted image 20230810140309.png]]

一旦所有内容都被编码为一个示例(Example),可以使用SerializeToString方法将其序列化。
![[Pasted image 20230810140347.png]]

函数封装

def make_example(image, label, class_name):
    image_feature = Feature(
        bytes_list=BytesList(value=[
            tf.io.serialize_tensor(image).numpy(),
        ])
    )
    label_feature = Feature(
        int64_list=Int64List(value=[
            label,
        ])
    )
    class_name_feature = Feature(
        bytes_list=BytesList(value=[
            class_name.encode(),
        ])
    )

    features = Features(feature={
        'image': image_feature,
        'label': label_feature,
        'class_name': class_name_feature,
    })
    
    example = Example(features=features)
    
    return example.SerializeToString()

函数使用如下:

example = make_example(
    image=np.array([[1, 2], [3, 4]]),
    label=1,
    class_name="Class B",
)

print(example)

![[Pasted image 20230810140530.png]]

小结

整个过程可能如下所示:

  1. 使用tf.data.Dataset构建数据集。您可以使用from_generatorfrom_tensor_slices方法。
  2. 通过使用make_example遍历数据集来序列化数据集。
  3. 使用io.TFRecordWriterdata.TFRecordWriter将数据集写入TFRecords。

然而,请注意,如果要在数据集的map方法中使用make_example之类的函数,您需要首先使用tf.py_function对其进行包装,因为TensorFlow以图模式执行数据集变换。您可以编写类似以下的代码:

ds_bytes = ds.map(lambda image, label: tf.py_function(func=make_example, inp=[image, label], Tout=tf.string))

其他资料
API文档tf.data.Dataset | TensorFlow v2.13.0。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/859714.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

phpstorm添加vue 标签属性绑定提示和提示vue的方法提示

v-text v-html v-once v-if v-show v-else v-for v-on v-bind v-model v-ref v-el v-pre v-cloak v-on:click v-on:keyup.enter v-on:keyup click change input number debounce transition :is :class把上面这些文字粘贴到点击右下角放大按钮 后的文本框里,然后保存…

混合云环境中 Kubernetes 可观测性的 6 个有效策略...

2023 年,原生云应用程序和平台将快速增长。组织不断努力最大限度地发挥其应用程序的潜力,确保无缝的用户体验并推动业务增长。 混合云环境的兴起以及 Kubernetes 等容器化技术的采用彻底改变了现代应用程序的开发、部署和扩展方式。 在这个数字领域&am…

Redis 搭建分片集群

文章目录 0.10.2 散列插槽0.3 集群伸缩0.3.1 需求分析0.3.1 创建新的 Redis 实例0.3.3 添加新节点到 Redis0.3.4 转移插槽 0.4 故障转移0.4.1 自动故障转移0.4.2 生动故障转移 0.5 RedisTemplate访问分片集群 1. 集群架构2. 准备实例和配置3. 启动4. 创建集群5. 测试 0.1 主从…

刷新缓冲区(标准IO)

标准IO是带缓冲的,输入和输出函数属于行缓冲,stdin、stdin、printf、scanf 1.换行符刷新 2.缓冲区满刷新 3.fflush函数强制刷新 4.程序正常结束

绩效考核,职场人的痛!

绩效,已经成为职场人不能跳过的话题。 绩效作为提高员工和企业效率的有效手段,已经被越来越公司采用,现在,公司里几乎任何一个岗位都会被考核,特别是互联网公司。今天我们以产品经理为例,看看这个岗位的绩效…

苍穹外卖day11笔记

今日首先介绍前端技术Apache ECharts,说明后端需要准备的数据,然后讲解具体统计功能的实现,包括营业额统计、用户统计、订单统计、销量排名。 一、ECharts 是什么 ECharts是一款基于 Javascript 的数据可视化图表库。我们用它来展示图表数…

leetcode每日一练-第121题-买卖股票的最佳时机

一、思路 动态规划 二、解题方法 维护两个变量:一个表示当前最低的股票价格 minPrice,另一个表示当前最大的利润 maxProfit。 遍历数组中的每个价格,对于每个价格,更新 minPrice 和 maxProfit。具体做法是,如果当前…

【Linux】TCP协议——传输层

目录 TCP协议 谈谈可靠性 TCP协议格式 序号与确认序号 窗口大小 六个标志位 确认应答机制(ACK) 超时重传机制 连接管理机制 三次握手 四次挥手 流量控制 滑动窗口 拥塞控制 延迟应答 捎带应答 面向字节流 粘包问题 TCP异常情况 TC…

【RTT驱动框架分析06】-pwn驱动框架分析+pwm驱动实现

pwm pwm应用程序开发 访问 PWM 设备API 应用程序通过 RT-Thread 提供的 PWM 设备管理接口来访问 PWM 设备硬件,相关接口如下所示: 函数描述rt_device_find()根据 PWM 设备名称查找设备获取设备句柄rt_pwm_set()设置 PWM 周期和脉冲宽度rt_pwm_enable…

橙河网络:2023年,我看谁还在做实体行业?

大家好,我是橙河老师,今天讲一讲实体行业。 现在实体行业还好干吗? 肯定是不好干了。 别的不扯,这几年很多大佬,能把老百姓干的事儿都干了。 一天收入上百万的演员,在直播间卖着九块九的东西&#xff0…

学习笔记-JVM-工具包(JVM分析工具)

常用工具 JDK工具 ① jps: JVM Process status tool:JVM进程状态工具,查看进程基本信息 ② jstat: JVM statistics monitoring tool : JVM统计监控工具,查看堆,GC详细信息 ③ jinfo:Java Configuration I…

MATLAB实现两组数据的延时对齐效果

博主在某次实验中,相同的实验条件下分别采集了两组数据,发现两组数据存在一个延时,如下图所示: 本文记录消除这个延时,实现相同数据状态的对齐效果,采用MATLAB自带的xcorr函数实现,具体步骤如下…

vteam透明屏,在场景化应用中,有哪些特点表现?

vteam透明屏是一种新型的显示技术,它采用透明材料制成,可以在显示内容的同时保持背景的透明度。 这种屏幕可以应用于各种领域,如广告、零售、展览等,具有很大的潜力和市场前景。 vteam透明屏的特点之一是其高透明度。与传统的显…

五、web应用程序技术——web功能

文章目录 一、服务器端功能1.1 SQL1.2 XML1.3 web服务 二、客户端功能2.1 HTML2.2 超链接2.3 表单2.4 CSS2.5 JavaScript2.6 文档对象模型2.7 Ajax2.8 JSON2.9 同源策略2.10浏览器拓展技术 一、服务器端功能 早期的web站点由各种静态资源组成,如HTML页面与图片。当用…

主数据管理案例-中国外运

1、 背景介绍及难点分析 作为世界领先的物流行业整合商、端到端的全程供应链解决方案和一站式物流服务提供商,中国外运非常重视信息化建设,先后投资建设了 300多个信息系统,为中国外运的内部管理和业务运作提供 IT 支持和保障。 由于缺乏统一…

当我准备出门时,发现了......我可以用Python实现12306自动买票

前言 不知道大家有没有之前碰到这样的情况,打算去某一个地方当你规划好了时间准备去买票的时候,你想要的那一列往往没有你想要的票了,尤其是国庆七天假和春节半月假,有时候甚至买不到规定计划时间内的票,真的是太烦躁…

数据分析-python学习 (1)numpy相关

内容为:https://juejin.cn/book/7240731597035864121的学习笔记 导包 import numpy as np numpy数组创建 创建全0数组,正态分布、随机数组等就不说了,提供了相应的方法通过已有数据创建有两种 arr1np.array([1,2,3,4,5]) 或者datanp.loadt…

vxe-grid\table 自定义动态列排序设置

实现动态加载的表格数据,根据设置动态控制指定的某些字段排序功能;如下图所示; 代码实现:标签内添加属性; :sort-config"{trigger:cell, defaultSort: {field: , order: desc}, orders:[desc, asc]}" sort-…

LinuxC编程——线程

目录 一、概念二、进程与线程的区别⭐⭐⭐三、线程资源四、函数接口4.1 线程创建4.2 线程退出4.3 线程回收4.3.1 阻塞回收4.3.2 非阻塞回收 4.4 pthread_create之传参4.5 练习 一、概念 是一个轻量级的进程,为了提高系统的性能引入线程。 进程与线程都参与cpu的统一…

这些可以将音频翻译成文字的工具你值得拥有

你是否曾经遇到过这样的情景:你收到了一段包含外国人发言内容的会议音频,但是由于自己的外语水平一般而却无法理解其中的外语内容?别担心,现在有一些神奇的翻译音频文件的软件可以帮助你解决这个问题!如果你还不知道翻…