2026/1/9 20:48:52
网站建设
项目流程
网站建设 织梦者,网站版面做得好的,用什么软件做动漫视频网站,百度识图在线网页版零基础吃透#xff1a;RaggedTensor的底层编码原理
RaggedTensor的核心设计是**“扁平化存储行分区描述”** —— 不直接存储嵌套列表#xff08;低效#xff09;#xff0c;而是将所有有效元素扁平存储在values张量中#xff0c;再通过row_partition#xff08;行分区RaggedTensor的底层编码原理RaggedTensor的核心设计是**“扁平化存储行分区描述”** —— 不直接存储嵌套列表低效而是将所有有效元素扁平存储在values张量中再通过row_partition行分区描述“如何将扁平值拆分为可变长度的行”。以下从「核心编码结构」「四种行分区编码」「多不规则维度」「不规则秩与扁平值」「均匀维度编码」五大模块拆解底层原理和用法。一、RaggedTensor的核心编码结构核心公式RaggedTensor values扁平张量 row_partition行分区规则values所有有效元素按顺序拼接成的一维/多维扁平张量无嵌套无空值row_partition描述“如何将values拆分为可变长度行”的规则支持4种编码方式下文详解。基础示例row_splits编码importtensorflowastf# 构造RaggedTensorvaluesrow_splitsrttf.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长度。示例复用上文rttf.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]rttf.RaggedTensor.from_value_rowids(values[3,1,4,1,5,9,2],value_rowids[0,0,0,0,2,2,3],nrows4# 总行数包含空行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个rttf.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行长度向量拼接/拆分高效频繁拼接多个RaggedTensoruniform_row_length长度标量存储效率最高非内层维度所有行长度相同的场景三、多个不规则维度的编码核心原理多不规则维度的RaggedTensor通过嵌套RaggedTensor编码外层RaggedTensor的values是内层RaggedTensor每一层嵌套对应一个不规则维度ragged_rank1。方式1嵌套from_row_splits构造# 外层RaggedTensorvalues是内层RaggedTensorrow_splits[0,1,1,5]# 内层RaggedTensorvalues[10-19]row_splits[0,3,3,5,9,10]rttf.RaggedTensor.from_row_splits(valuestf.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方式2from_nested_row_splits更简洁直接传入“嵌套拆分点列表”无需手动嵌套构造rttf.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_values1. 不规则秩ragged_rank定义RaggedTensor的嵌套深度即values被分区的次数等于nested_row_splits的长度。ragged_rank1一维不规则如[[1,2], [3]]ragged_rank2二维不规则如[[[1], []], [[2,3]]]。2. 扁平值flat_values定义最内层的非嵌套张量所有有效元素的扁平存储是RaggedTensor的“数据核心”。示例ragged_rank3# 4维结构[batch, (paragraph), (sentence), (word)]conversationstf.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个元素 [bI blike bragged btensors. bOh byeah? bWhat bcan byou buse]关键解读ragged_rank3因为有3层不规则维度paragraph、sentence、wordflat_values所有单词的一维张量共24个元素是整个RaggedTensor的底层数据存储。五、均匀维度的编码RaggedTensor允许部分维度为“均匀”长度固定分为「均匀内层维度」和「均匀非内层维度」编码方式不同。1. 均匀内层维度定义最内层维度flat_values是多维密集张量长度固定外层为不规则维度。示例rttf.RaggedTensor.from_row_splits(values[[1,3],[0,0],[1,3],[5,3],[3,3],[1,2]],# 内层是2列的密集张量row_splits[0,3,4,6]# 外层不规则行03个元素行11个行22个)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编码行分区。示例rttf.RaggedTensor.from_uniform_row_length(valuestf.RaggedTensor.from_row_splits(values[10,11,12,13,14,15,16,17,18,19],row_splits[0,3,5,9,10]# 内层不规则),uniform_row_length2# 外层均匀每行固定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_length2编码仅存一个标量内层通过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的编码原理能帮助你在高性能场景如大规模可变长度数据处理中选择最优的构造/操作方式避免性能瓶颈。