news 2026/2/9 19:26:13

tensorflow 零基础吃透:RaggedTensor 的底层编码原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
tensorflow 零基础吃透:RaggedTensor 的底层编码原理

零基础吃透:RaggedTensor的底层编码原理

RaggedTensor的核心设计是**“扁平化存储+行分区描述”** —— 不直接存储嵌套列表(低效),而是将所有有效元素扁平存储在values张量中,再通过row_partition(行分区)描述“如何将扁平值拆分为可变长度的行”。以下从「核心编码结构」「四种行分区编码」「多不规则维度」「不规则秩与扁平值」「均匀维度编码」五大模块,拆解底层原理和用法。

一、RaggedTensor的核心编码结构

核心公式

RaggedTensor = values(扁平张量) + row_partition(行分区规则)
  • values:所有有效元素按顺序拼接成的一维/多维扁平张量(无嵌套,无空值);
  • row_partition:描述“如何将values拆分为可变长度行”的规则,支持4种编码方式(下文详解)。

基础示例(row_splits编码)

importtensorflowastf# 构造RaggedTensor:values+row_splitsrt=tf.RaggedTensor.from_row_splits(values=[3,1,4,1,5,9,2],# 所有有效元素的扁平列表row_splits=[0,4,4,6,7]# 行拆分点:[起始, 行0结束, 行1结束, 行2结束, 行3结束])print("构造的RaggedTensor:",rt)

输出<tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9], [2]]>

拆分点逻辑(关键!)

row_splits的每个值是values的索引,定义每行的元素范围:

行索引拆分点范围values切片行内容
00 → 4values[0:4] → [3,1,4,1][3,1,4,1]
14 → 4values[4:4] → [][](空行)
24 → 6values[4:6] → [5,9][5,9]
36 → 7values[6:7] → [2][2]

二、四种row_partition编码方式(行分区规则)

TF内部管理行分区的编码方式,不同编码适配不同场景(效率/兼容性),以下是4种核心编码的原理、示例和优缺点:

1. row_splits(拆分点编码)

定义

一维整型向量,每个值表示values中“行的结束索引”,长度=行数+1(首元素必为0,末元素必为values长度)。

示例(复用上文)
rt=tf.RaggedTensor.from_row_splits(values=[3,1,4,1,5,9,2],row_splits=[0,4,4,6,7])print("row_splits:",rt.row_splits.numpy())# 直接访问拆分点

输出[0 4 4 6 7]

核心优缺点

✅ 优点:恒定时间索引/切片(直接通过拆分点定位行),适合频繁索引的场景;
❌ 缺点:空行仍需占用拆分点位置,存储大量空行时效率低。

2. value_rowids(值的行索引编码)

定义

一维整型向量,长度=values长度,每个值表示“对应values元素所属的行索引”。

示例
# 构造:values=[3,1,4,1,5,9,2],对应行索引[0,0,0,0,2,2,3]rt=tf.RaggedTensor.from_value_rowids(values=[3,1,4,1,5,9,2],value_rowids=[0,0,0,0,2,2,3],nrows=4# 总行数(包含空行1))print("value_rowids构造的RaggedTensor:",rt)print("value_rowids:",rt.value_rowids.numpy())

输出

value_rowids构造的RaggedTensor: <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9], [2]]> value_rowids: [0 0 0 0 2 2 3]
核心优缺点

✅ 优点:

  • 存储大量空行时高效(仅存储有效元素的行索引,空行无开销);
  • 兼容tf.segment_sum等分段运算(输入格式匹配);
    ❌ 缺点:索引单行需遍历value_rowids,效率低于row_splits。

3. row_lengths(行长度编码)

定义

一维整型向量,长度=行数,每个值表示“对应行的元素长度”(空行长度为0)。

示例
# 构造:行长度[4,0,2,1] → 对应行0:4个元素,行1:0个,行2:2个,行3:1个rt=tf.RaggedTensor.from_row_lengths(values=[3,1,4,1,5,9,2],row_lengths=[4,0,2,1])print("row_lengths构造的RaggedTensor:",rt)print("row_lengths:",rt.row_lengths.numpy())

输出

row_lengths构造的RaggedTensor: <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9], [2]]> row_lengths: [4 0 2 1]
核心优缺点

✅ 优点:拼接(concat)效率高(拼接时仅需合并row_lengths,无需修改values);
❌ 缺点:空行仍需存储长度0,大量空行时效率低于value_rowids。

4. uniform_row_length(均匀行长度编码)

定义

整型标量,表示“所有行的长度相同”(仅用于“非内层维度为均匀”的场景)。

示例(见下文“均匀非内层维度”)
核心优缺点

✅ 优点:存储效率极高(仅需一个标量,无需向量);
❌ 缺点:仅适用于所有行长度相同的场景,通用性差。

四种编码方式对比表

编码方式存储形式核心优势适用场景
row_splits拆分点向量索引/切片高效频繁单行查询、切片操作
value_rowids行索引向量大量空行存储高效、兼容segment运算含大量空行的数据集、分段求和/均值
row_lengths行长度向量拼接/拆分高效频繁拼接多个RaggedTensor
uniform_row_length长度标量存储效率最高非内层维度所有行长度相同的场景

三、多个不规则维度的编码

核心原理

多不规则维度的RaggedTensor通过嵌套RaggedTensor编码:外层RaggedTensor的values是内层RaggedTensor,每一层嵌套对应一个不规则维度(ragged_rank+1)。

方式1:嵌套from_row_splits构造

# 外层RaggedTensor:values是内层RaggedTensor,row_splits=[0,1,1,5]# 内层RaggedTensor:values=[10-19],row_splits=[0,3,3,5,9,10]rt=tf.RaggedTensor.from_row_splits(values=tf.RaggedTensor.from_row_splits(values=[10,11,12,13,14,15,16,17,18,19],row_splits=[0,3,3,5,9,10]),row_splits=[0,1,1,5])print("多不规则维度RaggedTensor:",rt)print("形状:",rt.shape)print("不规则秩(ragged_rank):",rt.ragged_rank)

输出

多不规则维度RaggedTensor: <tf.RaggedTensor [[[10, 11, 12]], [], [[], [13, 14], [15, 16, 17, 18], [19]]]> 形状: (3, None, None) 不规则秩(ragged_rank): 2

方式2:from_nested_row_splits(更简洁)

直接传入“嵌套拆分点列表”,无需手动嵌套构造:

rt=tf.RaggedTensor.from_nested_row_splits(flat_values=[10,11,12,13,14,15,16,17,18,19],# 最内层扁平值nested_row_splits=([0,1,1,5],[0,3,3,5,9,10])# 外层+内层拆分点)print("from_nested_row_splits构造:",rt)

输出:与嵌套构造完全一致。

四、不规则秩(ragged_rank)与扁平值(flat_values)

1. 不规则秩(ragged_rank)

定义:RaggedTensor的嵌套深度(即values被分区的次数),等于nested_row_splits的长度。

  • ragged_rank=1:一维不规则(如[[1,2], [3]]);
  • ragged_rank=2:二维不规则(如[[[1], []], [[2,3]]])。

2. 扁平值(flat_values)

定义:最内层的非嵌套张量(所有有效元素的扁平存储),是RaggedTensor的“数据核心”。

示例(ragged_rank=3)

# 4维结构:[batch, (paragraph), (sentence), (word)]conversations=tf.ragged.constant([[[["I","like","ragged","tensors."]],[["Oh","yeah?"],["What","can","you","use","them","for?"]],[["Processing","variable","length","data!"]]],[[["I","like","cheese."],["Do","you?"]],[["Yes."],["I","do."]]]])print("形状:",conversations.shape)print("不规则秩:",conversations.ragged_rank)print("flat_values(前10个元素):",conversations.flat_values.numpy()[:10])

输出

形状: (2, None, None, None) 不规则秩: 3 flat_values(前10个元素): [b'I' b'like' b'ragged' b'tensors.' b'Oh' b'yeah?' b'What' b'can' b'you' b'use']
关键解读
  • ragged_rank=3:因为有3层不规则维度(paragraph、sentence、word);
  • flat_values:所有单词的一维张量(共24个元素),是整个RaggedTensor的底层数据存储。

五、均匀维度的编码

RaggedTensor允许部分维度为“均匀”(长度固定),分为「均匀内层维度」和「均匀非内层维度」,编码方式不同。

1. 均匀内层维度

定义

最内层维度(flat_values)是多维密集张量(长度固定),外层为不规则维度。

示例
rt=tf.RaggedTensor.from_row_splits(values=[[1,3],[0,0],[1,3],[5,3],[3,3],[1,2]],# 内层是2列的密集张量row_splits=[0,3,4,6]# 外层不规则:行0=3个元素,行1=1个,行2=2个)print("均匀内层维度RaggedTensor:",rt)print("形状:",rt.shape)print("不规则秩:",rt.ragged_rank)print("flat_values形状:",rt.flat_values.shape)print("flat_values:\n",rt.flat_values)

输出

均匀内层维度RaggedTensor: <tf.RaggedTensor [[[1, 3], [0, 0], [1, 3]], [[5, 3]], [[3, 3], [1, 2]]]> 形状: (3, None, 2) 不规则秩: 1 flat_values形状: (6, 2) flat_values: [[1 3] [0 0] [1 3] [5 3] [3 3] [1 2]]
关键解读
  • 形状(3, None, 2):3行(均匀)、每行元素数可变(None)、每个元素是2列(均匀);
  • flat_values是(6,2)的密集张量(内层维度固定为2),外层通过row_splits拆分为可变长度行。

2. 均匀非内层维度

定义

非内层维度为均匀(所有行长度相同),通过uniform_row_length编码行分区。

示例
rt=tf.RaggedTensor.from_uniform_row_length(values=tf.RaggedTensor.from_row_splits(values=[10,11,12,13,14,15,16,17,18,19],row_splits=[0,3,5,9,10]# 内层不规则),uniform_row_length=2# 外层均匀:每行固定2个元素)print("均匀非内层维度RaggedTensor:",rt)print("形状:",rt.shape)print("不规则秩:",rt.ragged_rank)

输出

均匀非内层维度RaggedTensor: <tf.RaggedTensor [[[10, 11, 12], [13, 14]], [[15, 16, 17, 18], [19]]]> 形状: (2, 2, None) 不规则秩: 2
关键解读
  • 形状(2, 2, None):2行(均匀)、每行固定2个元素(均匀)、每个元素长度可变(None);
  • 外层通过uniform_row_length=2编码(仅存一个标量),内层通过row_splits编码不规则维度。

核心总结

1. 编码核心逻辑

RaggedTensor的底层是“扁平存储+分区规则”,避免嵌套列表的低效存储,四种行分区编码适配不同场景;

2. 多维度扩展

多不规则维度通过嵌套RaggedTensor实现,ragged_rank表示嵌套深度,flat_values是最内层扁平数据;

3. 均匀维度兼容

支持部分维度均匀(内层/非内层),分别通过“多维flat_values”和“uniform_row_length”编码;

4. 性能优化

  • 频繁索引 → 选row_splits;
  • 大量空行 → 选value_rowids;
  • 频繁拼接 → 选row_lengths;
  • 行长度均匀 → 选uniform_row_length。

理解RaggedTensor的编码原理,能帮助你在高性能场景(如大规模可变长度数据处理)中选择最优的构造/操作方式,避免性能瓶颈。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/5 13:00:08

百度网盘资源过期?官方GitHub镜像提供稳定Qwen-Image下载

百度网盘资源过期&#xff1f;官方GitHub镜像提供稳定Qwen-Image下载 在AI生成内容&#xff08;AIGC&#xff09;浪潮席卷创意产业的今天&#xff0c;越来越多企业与开发者开始将文生图模型集成到设计流程中。然而&#xff0c;一个令人头疼的现实问题始终存在&#xff1a;从社区…

作者头像 李华
网站建设 2026/2/5 19:06:24

易代账结账和反结账流程

【问题现象】如何结账与反结账&#xff1f;【解决方法】结账&#xff1a;当本月所有相关凭证制作完成&#xff0c;点击 设置→结账→马上检查→结账&#xff1b;2.如何反结账&#xff08;1&#xff09;点击【结账】-【结账】&#xff0c;选择需反结账的月份&#xff0c;点击【反…

作者头像 李华
网站建设 2026/2/5 9:50:54

Vue-next-admin:现代化Vue3后台管理系统完整指南

Vue-next-admin&#xff1a;现代化Vue3后台管理系统完整指南 【免费下载链接】vue-next-admin &#x1f389;&#x1f389;&#x1f525;基于vue3.x 、Typescript、vite、Element plus等&#xff0c;适配手机、平板、pc 的后台开源免费模板库&#xff08;vue2.x请切换vue-prev-…

作者头像 李华
网站建设 2026/2/8 18:52:55

Git 下载大型模型文件时使用LFS管理Qwen3-VL-8B权重

Git 下载大型模型文件时使用LFS管理Qwen3-VL-8B权重 在AI项目开发中&#xff0c;一个常见的痛点是&#xff1a;如何高效地版本化和分发那些动辄数GB的模型权重文件&#xff1f;传统的Git操作面对这类大文件常常显得力不从心——克隆慢、存储膨胀、协作卡顿。尤其是在处理像 Qw…

作者头像 李华
网站建设 2026/2/6 8:15:33

三步快速解密音乐文件:免费工具完整指南

三步快速解密音乐文件&#xff1a;免费工具完整指南 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库&#xff1a; 1. https://github.com/unlock-music/unlock-music &#xff1b;2. https://git.unlock-music.dev/um/web 项目地址: https://gitcode.co…

作者头像 李华
网站建设 2026/2/7 0:39:29

轻量级视频生成时代来临:Wan2.2-T2V-5B应用前景分析

轻量级视频生成时代来临&#xff1a;Wan2.2-T2V-5B应用前景分析 在短视频日均播放量突破数百亿次的今天&#xff0c;内容创作者正面临一个矛盾现实&#xff1a;用户对视觉创意的需求越来越“快、多、新”&#xff0c;而传统视频制作流程却依然缓慢且昂贵。一条30秒广告片动辄需…

作者头像 李华