热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

nlpEmbedding

基本概念及原理一种表述:Embedding是个英文术语,如果非要找一个中文翻译对照的话,我觉得“向量化”(Vectorize


基本概念及原理


一种表述:Embedding 是个英文术语,如果非要找一个中文翻译对照的话,我觉得“向量化”(Vectorize)最合适。Embedding 的过程,就是把数据集合映射到向量空间,进而把数据进行向量化的过程。Embedding 的目标,就是找到一组合适的向量,来刻画现有的数据集合。


  1. 比如让国家作为模型参数&#xff0c;我们该如何用数字化的方式来表示它们呢&#xff1f;毕竟&#xff0c;模型只能消费数值&#xff0c;不能直接消费字符串。一种方法是把字符串转换为连续的整数&#xff0c;然后让模型去消费这些整数。。在理论上&#xff0c;这么做没有任何问题。但从模型的效果出发&#xff0c;整数的表达方式并不合理。为什么这么说呢&#xff1f;我们知道&#xff0c;连续整数之间&#xff0c;是存在比较关系的&#xff0c;比如 1 <3&#xff0c;6 > 5&#xff0c;等等。但是原始的字符串之间&#xff0c;比如&#xff0c;国家并不存在大小关系&#xff0c;如果强行用 0 表示“中国”、用 1 表示“美国”&#xff0c;逻辑上就会出现“中国”<“美国”的悖论。仅仅是把字符串转换为数字&#xff0c;转换得到的数值是不能直接喂给模型做训练


  1. 我们需要把这些数字进一步向量化&#xff0c;才能交给模型去消费。Embedding 的方法也是日新月异、层出不穷。从最基本的热独编码到 PCA 降维&#xff0c;从 Word2Vec 到 Item2Vec&#xff0c;从矩阵分解到基于深度学习的协同过滤&#xff0c;可谓百花齐放、百家争鸣。


一种表述&#xff1a;embedding 是指将客观世界中离散的物体或对象&#xff08;如单词、短语、图片&#xff09;等映射到特征空间的操作&#xff0c;embedding向量是指映射后 的特征空间中连续且稠密的高维向量。在机器学习场景中&#xff0c;我们经常使用embedding向量 来描述客观世界的物体。embedding向量 不是对物体进行简单编号的结果&#xff0c;而是在尽量保持相似不变性的前提下 对物体进行特征抽象和编码的产物。通过不断训练&#xff0c;我们能够将客观世界中的物体不失真的映射到高维特征空间中&#xff0c;进而可以使用这些embedding向量 实现分类、回归和预测等操作。


Embedding 就是用一个数值向量“表示”一个对象&#xff08;Object&#xff09;的方法。“实体对象”可以是image、word等&#xff0c;“数值化表示”就是一个编码向量。例如对“颜色“这种实体对象用&#xff08;R&#xff0c;G&#xff0c;B&#xff09;这样一个三元素向量编码。embedding还可以理解成将离散目标投影到连续空间中的某个点上。数值化的embedding vector本身是没有意义的&#xff0c;不同vector之间的相对关系才是有实际意义的。例如&#xff1a;NLP中最基本的word embedding&#xff0c;给每一个单词一个N维编码向量&#xff08;或者说将每个word投影到N维空间中&#xff09;&#xff0c;我们期望这种编码满足这样的特性&#xff1a;两个向量之间的”距离“越小&#xff0c;代表这两个单词含义越接近。比如利用 Word2vec 这个模型把单词映射到了高维空间中&#xff0c;从 king 到 queen 的向量和从 man 到 woman 的向量&#xff0c;无论从方向还是尺度来说它们都异常接近。









Embedding 技术对深度学习推荐系统的重要性


  1. Embedding 是处理稀疏特征的利器。因为推荐场景中的类别、ID 型特征非常多&#xff0c;大量使用 One-hot 编码会导致样本特征向量极度稀疏&#xff0c;而深度学习的结构特点又不利于稀疏特征向量的处理&#xff0c;因此几乎所有深度学习推荐模型都会由 Embedding 层负责将稀疏高维特征向量转换成稠密低维特征向量。


  1. Embedding 可以融合大量有价值信息&#xff0c;本身就是极其重要的特征向量 。 相比由原始信息直接处理得来的特征向量&#xff0c;Embedding 的表达能力更强&#xff0c;特别是 Graph Embedding 技术被提出后&#xff0c;Embedding 几乎可以引入任何信息进行编码&#xff0c;使其本身就包含大量有价值的信息&#xff0c;所以通过预训练得到的 Embedding 向量本身就是极其重要的特征向量。


Word2vec 是生成对“词”的向量表达的模型&#xff0c;其中&#xff0c;Word2vec 的训练样本是通过滑动窗口一一截取词组生成的。在训练完成后&#xff0c;模型输入向量矩阵的行向量&#xff0c;就是我们要提取的词向量。
















在 Word2vec 诞生之后&#xff0c;Embedding 的思想迅速从自然语言处理领域扩散到几乎所有机器学习领域&#xff0c;既然 Word2vec 可以对词“序列”中的词进行 Embedding&#xff0c;那么对于用户购买“序列”中的一个商品&#xff0c;用户观看“序列”中的一个电影&#xff0c;也应该存在相应的 Embedding 方法。于是&#xff0c;微软于 2015 年提出了 Item2Vec 方法&#xff0c;它是对 Word2vec 方法的推广&#xff0c;使 Embedding 方法适用于几乎所有的序列数据。只要能够用序列数据的形式把我们要表达的对象表示出来&#xff0c;再把序列数据“喂”给 Word2vec 模型&#xff0c;我们就能够得到任意物品的 Embedding 了。假设我们知道 用户看过的电影的id 序列&#xff0c;比如296 380 344 588 593 231 595 318 480&#xff0c;那么此时电影id 是词&#xff0c;电影id 序列是句子&#xff0c;一个句子内的词有相互关系&#xff0c;那么就可以 根据 Item2vec 计算电影id 对应的 Embedding 向量。


Embedding这块&#xff0c;spark MLlib 和 机器学习库 都提供了处理函数。利用Tensorboard很容易将embedding进行可视化&#xff0c;不过既然是可视化&#xff0c;最高只能“可视”三维空间&#xff0c;所以高维向量需要被投影到三维&#xff08;或二维空间&#xff09;。不过不用担心细节&#xff0c;Tensorboard做了足够高质量的封装。


一文梳理推荐系统中Embedding应用实践


  1. 端到端的方法是将Embedding层作为神经网络的一部分&#xff0c;在进行BP更新每一层参数的时候同时更新Embedding&#xff0c;这种方法的好处是让Embedding的训练成为一个有监督的方式&#xff0c;可以很好的与最终的目标产生联系&#xff0c;使得Embedding与最终目标处于同一意义空间。但这样做的缺点同样显而易见的&#xff0c;由于Embedding层输入向量的维度甚大&#xff0c;Embedding层的加入会拖慢整个神经网络的收敛速度。大部分的训练时间和计算开销都被Embedding层所占据。正因为这个原因&#xff0c;「对于那些时间要求较为苛刻的场景&#xff0c;Embedding最好采用非端到端&#xff0c;也就是预训练的方式完成。」


  1. 非端到端&#xff08;预训练&#xff09;&#xff0c;在一些时间要求比较高的场景下&#xff0c;Embedding的训练往往独立于深度学习网络进行&#xff0c;在得到稀疏特征的稠密表达之后&#xff0c;再与其他特征一起输入神经网络进行训练。在做任务时&#xff0c;将训练集中的词替换成事先训练好的向量表示放到网络中。Word2Vec&#xff0c;Doc2Vec&#xff0c;Item2Vec都是典型的非端到端的方法


在自然语言中&#xff0c;非端到端很常见&#xff0c;因为学到一个好的的词向量表示&#xff0c;就能很好地挖掘出词之间的潜在关系&#xff0c;那么在其他语料训练集和自然语言任务中&#xff0c;也能很好地表征这些词的内在联系&#xff0c;预训练的方式得到的Embedding并不会对最终的任务和模型造成太大影响&#xff0c;但却能够「提高效率节省时间」&#xff0c;这也是预训练的一大好处。但是在推荐场景下&#xff0c;根据不同目标构造出的序列不同&#xff0c;那么训练得到的Embedding挖掘出的关联信息也不同。所以&#xff0c;「在推荐中要想用预训练的方式&#xff0c;必须保证Embedding的预训练和最终任务目标处于同一意义空间」&#xff0c;否则就会造成预训练得到Embedding的意义和最终目标完全不一致。比如做召回阶段的深度模型的目标是衡量两个商品之间的相似性&#xff0c;但是CTR做的是预测用户点击商品的概率&#xff0c;初始化一个不相关的 Embedding 会给模型带来更大的负担&#xff0c;更慢地收敛。


在梯度下降这块对embedding weight也有针对性的优化算法&#xff0c;从梯度下降到FTRLFTRL是在广告/推荐领域会用到的优化方法&#xff0c;适用于对高维稀疏模型进行训练&#xff0c;获取稀疏解。


实践


《深度学习推荐系统实战》为什么深度学习的结构特点不利于稀疏特征向量的处理呢&#xff1f;


  1. 如果我们深入到神经网络的梯度下降学习过程就会发现&#xff0c;特征过于稀疏会导致整个网络的收敛非常慢&#xff0c;因为每一个样本的学习只有极少数的权重会得到更新&#xff0c;这在样本数量有限的情况下会导致模型不收敛。


  1. One-hot 类稀疏特征的维度往往非常地大&#xff0c;可能会达到千万甚至亿的级别&#xff0c;如果直接连接进入深度学习网络&#xff0c;那整个模型的参数数量会非常庞大。因此&#xff0c;我们往往会先通过 Embedding 把原始稀疏特征稠密化&#xff0c;然后再输入复杂的深度学习网络进行训练&#xff0c;这相当于把原始特征向量跟上层复杂深度学习网络做一个隔离。


案例


从论文源码学习 之 embedding_lookup Embedding最重要的属性是&#xff1a;越“相似”的实体&#xff0c;Embedding之间的距离越小。比如用one-hot编码来表示4个梁山好汉。


李逵 [0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0]
刘唐 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
武松 [0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
鲁智深 [0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
&#61;&#61;>
二 出 官 武
货 家 阶 力
李逵 [1 0 0 0.5]
刘唐 [1 0 0 0.4]
武松 [0 1 0.5 0.8]
鲁智深 [0 1 0.75 0.8]

Embedding层把我们的稀疏矩阵&#xff0c;通过一些线性变换&#xff08;比如用全连接层进行转换&#xff0c;也称为查表操作&#xff09;&#xff0c;变成了一个密集矩阵&#xff0c;这个密集矩阵用了N&#xff08;例子中N&#61;4&#xff09;个特征来表征所有的好汉。在这个密集矩阵中&#xff0c;表象上代表着密集矩阵跟单个好汉的一一对应关系&#xff0c;实际上还蕴含了大量的好汉与好汉之间的内在关系&#xff08;如&#xff1a;我们得出的李逵跟刘唐的关系&#xff09;。它们之间的关系&#xff0c;用嵌入层学习来的参数进行表征。这个从稀疏矩阵到密集矩阵的过程&#xff0c;叫做embedding&#xff0c;很多人也把它叫做查表&#xff0c;因为它们之间也是一个一一映射的关系。这种映射关系在反向传播的过程中一直在更新。因此能在多次epoch后&#xff0c;使得这个关系变成相对成熟&#xff0c;即&#xff1a;正确的表达整个语义以及各个语句之间的关系。这个成熟的关系&#xff0c;就是embedding层的所有权重参数。Embedding最大的劣势是无法解释每个维度的含义&#xff0c;这也是复杂机器学习模型的通病。


Embedding除了把独立向量联系起来之外&#xff0c;还有两个作用&#xff1a;降维&#xff0c;升维。


  1. embedding层 降维的原理就是矩阵乘法。比如一个 1 x 4 的矩阵&#xff0c;乘以一个 4 x 3 的矩阵&#xff0c;得倒一个 1 x 3 的矩阵。4 x 3 的矩阵缩小了 1 / 4。假如我们有一个100W X 10W的矩阵&#xff0c;用它乘上一个10W X 20的矩阵&#xff0c;我们可以把它降到100W X 20&#xff0c;瞬间量级降了。


  1. 升维可以理解为&#xff1a;前面有一幅图画&#xff0c;你离远了看不清楚&#xff0c;离近了看就可以看清楚细节。当对低维的数据进行升维时&#xff0c;可能把一些其他特征给放大了&#xff0c;或者把笼统的特征给分开了。同时这个embedding是一直在学习在优化的&#xff0c;就使得整个拉近拉远的过程慢慢形成一个良好的观察点。


如何生成?


  1. 矩阵分解


  1. 无监督建模


  1. 有监督建模


Embedding与深度学习推荐系统的结合


NVIDIA HugeCTR&#xff0c;GPU版本参数服务器— (5) 嵌入式hash表 具有两个嵌入表和多个全连接层的神经网络









Embedding 权重矩阵可以是一个 [item_size, embedding_size] 的稠密矩阵&#xff0c;item_size是需要embedding的物品个数&#xff0c;embedding_size是映射的向量长度&#xff0c;或者说矩阵的大小是&#xff1a;特征数量 * 嵌入维度。Embedding 权重矩阵的每一行对应输入的一个维度特征&#xff08;one-hot之后的维度&#xff09;。用户可以用一个index表示选择了哪个特征。









这样就把两个 1 x 9 的高维度&#xff0c;离散&#xff0c;稀疏向量&#xff0c;压缩到 两个 1 x 3 的低维稠密向量。这里把 One-Hot 向量中 “1”的位置叫做sparseID&#xff0c;就是一个编号。这个独热向量和嵌入表的矩阵乘法就等于利用sparseID进行的一次查表过程。


TensorFlow 的 embedding_lookup(params, ids) 函数的目的是按照ids从params这个矩阵中拿向量&#xff08;行&#xff09;&#xff0c;所以ids就是这个矩阵索引&#xff08;行号&#xff09;&#xff0c;需要int类型。即按照ids顺序返回params中的第ids行。比如说&#xff0c;ids&#61;[1,3,2],就是返回params中第1,3,2行。返回结果为由params的1,3,2行组成的tensor。


embedding_lookup是一种特殊的全连接层的实现方法&#xff0c;其针对 输入是超高维 one hot向量的情况。


  1. 神经网络处理不了onehot编码&#xff0c;Z &#61; WX &#43; b。由于X是One-Hot Encoding 的原因&#xff0c;WX 的矩阵乘法看起来就像是取了Weights矩阵中对应的一行&#xff0c;看起来就像是在查表&#xff0c;所以叫做 lookup。embedding_lookup(W,X)等于说进行了一次矩阵相乘运算&#xff0c;其实就是一次线性变换。


  1. 假设embedding权重矩阵是一个[vocab_size, embed_size]的稠密矩阵W&#xff0c;vocab_size是需要embed的所有item的个数&#xff08;比如&#xff1a;所有词的个数&#xff0c;所有商品的个数&#xff09;&#xff0c;embed_size是映射后的向量长度。所谓embedding_lookup(W, id1)&#xff0c;可以想像成一个只在id1位为1的[1, vocab_size]的one_hot向量&#xff0c;与[vocab_size, embed_size]的W矩阵相乘&#xff0c;结果是一个[1, embed_size]的向量&#xff0c;它就是id1对应的embedding向量&#xff0c;实际上就是W矩阵的第id1行。但是&#xff0c;以上过程只是forward&#xff0c;因为W一般是随机初始化的&#xff0c;是待优化的变量。因此&#xff0c;embedding_lookup除了要完成以上矩阵相乘的过程&#xff08;实现成“抽取id对应的行”&#xff09;&#xff0c;还要完成自动求导&#xff0c;以实现对W的更新。PS: 所以embedding_lookup 的底层是一个op&#xff0c;在tensorflow r1.4 分支下&#xff0c;底层执行的是 array_ops.gather


tensorflow 实现


一般在tensorflow中都会使用一个shape&#61;[id_index_size, embedding_size]的Variable 矩阵做embedding参数&#xff0c;然后根据id特征的index去Variable矩阵中查表得到相应的embedding表示。这里需要注意的是&#xff1a;id_index_size的大小一般都不会等于对应id table的元素个数&#xff0c;因为有很多id元素不在原始的id table表中&#xff0c;比如新上架的一些商品等。此时需要将id_index_size设置的大一些&#xff0c;以留一些位置给那些不在id table表的元素使用。


使用tf.Variable 作为 embedding参数


import numpy as np
import tensorflow as tf
sess &#61; tf.InteractiveSession()
embedding &#61; tf.Variable(np.identity(6, dtype&#61;np.int32)) # 创建一个embedding词典
input_ids &#61; tf.placeholder(dtype&#61;tf.int32, shape&#61;[None])
# 相对于 feature_column 中的EmbeddingColumn&#xff0c;embedding_lookup 是有点偏底层的api/op
input_embedding &#61; tf.nn.embedding_lookup(embedding, input_ids) # 把input_ids中给出的tensor表现成embedding中的形式
sess.run(tf.global_variables_initializer())
print("&#61;&#61;&#61;&#61;&#61;&#61; the embedding &#61;&#61;&#61;&#61;&#61;&#61; ")
print(sess.run(embedding) )
print("&#61;&#61;&#61;&#61;&#61;&#61; the input_embedding &#61;&#61;&#61;&#61;&#61;&#61; ")
print(sess.run(input_embedding, feed_dict&#61;{input_ids: [4, 0, 2]}))
&#61;&#61;&#61;&#61;&#61;&#61; the embedding &#61;&#61;&#61;&#61;&#61;&#61;
[[1 0 0 0 0 0]
[0 1 0 0 0 0]
[0 0 1 0 0 0]
[0 0 0 1 0 0]
[0 0 0 0 1 0]
[0 0 0 0 0 1]]
&#61;&#61;&#61;&#61;&#61;&#61; the input_embedding &#61;&#61;&#61;&#61;&#61;&#61;
[[0 0 0 0 1 0]
[1 0 0 0 0 0]
[0 0 1 0 0 0]]

使用get_embedding_variable接口


var &#61; tf.get_embedding_variable("var_0",embedding_dim&#61;3,initializer&#61;tf.ones_initializer(tf.float32),partitioner&#61;tf.fixed_size_partitioner(num_shards&#61;4))
shape &#61; [var1.total_count() for var1 in var]
emb &#61; tf.nn.embedding_lookup(var, tf.cast([0,1,2,5,6,7], tf.int64))
...

使用categorical_column_with_embedding接口


columns &#61; tf.feature_column.categorical_column_with_embedding("col_emb", dtype&#61;tf.dtypes.int64)
W &#61; tf.feature_column.embedding_column(categorical_column&#61;columns,dimension&#61;3,initializer&#61;tf.ones_initializer(tf.dtypes.float32))
ids&#61;{}
ids["col_emb"] &#61; tf.SparseTensor(indices&#61;[[0,0],[1,1],[2,2],[3,3],[4,4]], values&#61;tf.cast([1,2,3,4,5], tf.dtypes.int64), dense_shape&#61;[5, 4])
emb &#61; tf.feature_column.input_layer(ids, [W])

从论文源码学习 之 embedding层如何自动更新input_embedding &#61; embedding * input_ids 从效果上 可以把 input_ids 视为索引的作用&#xff0c;返回第4、0、2 行数据&#xff0c;但 embedding_lookup 函数 也可以看做是一个 矩阵乘法&#xff08;底层两种都支持&#xff0c;是一个策略参数&#xff09;&#xff0c;也因此 embedding层可以通过 optimizer 进行更新。


原生的tf optimizer 根据 梯度/grad 的类型 来决定更新weight/ variable 的方法&#xff0c;当传来的梯度是普通tensor时&#xff0c;调用_apply_dense方法去更新参数&#xff1b;当传来的梯度是IndexedSlices类型时&#xff0c;则去调用optimizer._apply_sparse_duplicate_indices函数。 Embedding 参数的梯度中包含每个 tensor 中发生变化的数据切片 IndexedSlices。IndexedSlices类型是一种可以存储稀疏矩阵的数据结构&#xff0c;只需要存储对应的行号和相应的值即可。可以认为是一种类似 SparseTensor 的思想&#xff0c;用元素数据和元素位置表示一个较大 tensor 。将 tensor 按第一维度切片&#xff0c;从而将一个较大的形状为 [LARGE0, D1, .. , DN] 的 tensor 表示为多个较小的形状为 [D1, .. , DN] 的 tensor。









总结一下涉及到哪些问题&#xff1a; 稀疏参数的表示&#xff08;开始由Variable 表示 &#xff0c;各种框架提供EmbeddingVariable 表示&#xff09;、存储(ps&#xff0c;底层是分布式hashmap)、通信&#xff08;只通信部分&#xff0c;数据存在gpu &#43; gpu 直接通信&#xff09;、优化&#xff08;稀疏参数的优化器与稠密参数的优化器不兼容&#xff09; 和 稀疏参数的梯度的表示、通信&#xff08;由IndexedSlices 表示&#xff09;、优化


TensorFlow 原生 Embedding Layer 存在以下问题


  1. 静态 Embedding OOV 问题。在构建 Embedding Layer 的时候&#xff0c;TensorFlow 需要首先构建一个静态 shape[Vocab_size, Embedding size ] 的 Variable&#xff0c;然后利用 Lookup 的算子将特征值的 Embedding 向量查询出。在增量或者流式训练中&#xff0c;会出现 OOV 的问题。


  1. 静态 Embedding hash 特征冲突。为了规避上述的 OOV 问题&#xff0c;通常做法是将特征值 hash 到一定的范围&#xff0c;但是又会引入 hash 冲突的问题&#xff0c;导致不同的特征值共用同一个 Embedding&#xff0c;会造成信息丢失&#xff0c;对模型训练是有损的。


  1. 静态 Embedding 内存浪费。为了缓解 hash 冲突&#xff0c;通常会设置比真实的特征值个数 N 大一到两倍的 hash 范围&#xff0c;而这又会强行地增加模型的体积。


  1. 低频特征冗余。在引入稀疏特征时&#xff0c;出现频次较低以及许久未出现的特征 ID 对于模型而言是冗余的。此外&#xff0c;交叉特征占据了大量的存储&#xff0c;可以在不影响训练效果的前提下过滤掉这些特征 ID。因此&#xff0c;迫切需求特征淘汰以及准入机制。









嵌入层的优化


DL 推荐模型的嵌入层是比较特殊的&#xff1a;它们为模型贡献了大量参数&#xff0c;但几乎不需要计算&#xff0c;而计算密集型denser layers的参数数量则要少得多。所以对于推荐系统&#xff0c;嵌入层的优化十分重要。


点击率预测模型Embedding层的学习和训练


TensorFlow 模型准实时更新上线的设计与实现计算图结构由模型的算法结构决定&#xff0c;对数据的操作即为 operation&#xff08; op &#xff09;。当模型结构确定的情况下&#xff0c;我们的增强就需要对 op 进行定制。 PS&#xff1a;介绍了针对 embedding 参数的特点&#xff0c;如何通过自定义op 对其进行优化。


a_matrix &#61; random.random(size&#61;(2,4))
b_matrix &#61; random.random(size&#61;(2,4))
print("a_matrix&#61;", a_matrix)
print("b_matrix&#61;", b_matrix)
a &#61; tf.Variable(a_matrix, dtype&#61;tf.float32, name&#61;"a")
b &#61; tf.Variable(b_matrix, dtype&#61;tf.float32, name&#61;"b")

res_a &#61; tf.nn.embedding_lookup(a, [0, 0], name&#61;"lookup_a")
res_b &#61; tf.nn.embedding_lookup(b, [1, 1], name&#61;"lookup_b")
y &#61; tf.add(res_a, res_b)

saver &#61; tf.train.Saver(variables._all_saveable_objects(), sharded&#61;True, write_version&#61;saver_pb2.SaverDef.V2, allow_empty&#61;True)
meta_graph_def &#61; saver.export_meta_graph(as_text&#61;True, clear_devices&#61;True, strip_default_attrs&#61;True)
with open("./meta_graph_def.pbtxt", "w") as f:
f.write(str(meta_graph_def))
...

这个计算图实现了简单的计算&#xff0c;定义两个变量&#xff0c;分别执行 embedding_lookup&#xff0c;然后对查询结果求和计算。代码中对 graph 进行保存&#xff0c;也保存了 tensorboard 所需的数据&#xff0c;用于进一步分析。使用 tensorboard 打开文件保存的路径&#xff0c;我们可以看到这个计算图的直观表现。分别查看计算节点&#xff0c;就可以观察到 op 的输入输出关系。PS&#xff1a;总结一下&#xff0c;定制tf时要不要新增python层接口&#xff1a;


  1. 新增python层接口。那么就要自定义一个python库&#xff0c;在这个库里应用自定义或原生OP&#xff0c;或者只是单纯调用下 c&#43;&#43;函数做一些初始化工作


  1. 使用原有的tf python层接口。那么就要从 tensorboard 看计算图&#xff0c;看看tf python 函数用到了哪些原生op&#xff0c;这些op有哪些作用&#xff0c;哪些op需要自己自定义实现&#xff0c;进而替换掉这些原生op。









定制好 op 后&#xff0c;如何替换模型计算图中原生的 op 呢&#xff1f;TensorFlow 在模型保存时&#xff0c;会生成 meta_graph_def 文件&#xff0c;文件内容是采用类似 json 的格式描述计算图的结构关系。当加载此文件时&#xff0c;TensorFlow 会根据文件中描述的结构信息构建出计算图。可以修改模型保存的 meta_graph_def 文件&#xff0c;将其中的 op 替换为我们定制的 op&#xff0c;同时修改每个 node 的 input 和 output 关系&#xff0c;以修改 op 之间的依赖关系。随后用修改过的 meta_graph_def 文件加载回模型的计算图&#xff0c;即完成了对原有计算图结构的修改


原理上


TensorFlow在美团外卖推荐场景的GPU训练优化实践-参数规模的合理化


  1. 去交叉特征


  1. 精简特征


  1. 压缩Embedding向量数


  1. 压缩Embedding向量维度


  1. 量化压缩




推荐阅读
  • Redis 是一个高性能的开源键值存储系统,支持多种数据结构。本文将详细介绍 Redis 中的六种底层数据结构及其在对象系统中的应用,包括字符串对象、列表对象、哈希对象、集合对象和有序集合对象。通过12张图解,帮助读者全面理解 Redis 的数据结构和对象系统。 ... [详细]
  • 非计算机专业的朋友如何拿下多个Offer
    大家好,我是归辰。秋招结束后,我已顺利入职,并应公子龙的邀请,分享一些秋招面试的心得体会,希望能帮助到学弟学妹们,让他们在未来的面试中更加顺利。 ... [详细]
  • 探索CNN的可视化技术
    神经网络的可视化在理论学习与实践应用中扮演着至关重要的角色。本文深入探讨了三种有效的CNN(卷积神经网络)可视化方法,旨在帮助读者更好地理解和优化模型。 ... [详细]
  • 视觉Transformer综述
    本文综述了视觉Transformer在计算机视觉领域的应用,从原始Transformer出发,详细介绍了其在图像分类、目标检测和图像分割等任务中的最新进展。文章不仅涵盖了基础的Transformer架构,还深入探讨了各类增强版Transformer模型的设计思路和技术细节。 ... [详细]
  • 本周三大青年学术分享会即将开启
    由雷锋网旗下的AI研习社主办,旨在促进AI领域的知识共享和技术交流。通过邀请来自学术界和工业界的专家进行在线分享,活动致力于搭建一个连接理论与实践的平台。 ... [详细]
  • 本笔记为自用,倘若没有相关的学习基础,也确实无法看懂文章写的是什么。近来有点越学越回去的感觉。竟然突然在想,为什么深度学习模型可以对图像进行分类或者语义分割。可怕的是,当时想到这里 ... [详细]
  • 精选10款Python框架助力并行与分布式机器学习
    随着神经网络模型的不断深化和复杂化,训练这些模型变得愈发具有挑战性,不仅需要处理大量的权重,还必须克服内存限制等问题。本文将介绍10款优秀的Python框架,帮助开发者高效地实现分布式和并行化的深度学习模型训练。 ... [详细]
  • 英特尔推出第三代至强可扩展处理器及傲腾持久内存,AI性能显著提升
    英特尔在数据创新峰会上发布了第三代至强可扩展处理器和第二代傲腾持久内存,全面增强AI能力和系统性能。 ... [详细]
  • PHP函数的工作原理与性能分析
    在编程语言中,函数是最基本的组成单元。本文将探讨PHP函数的特点、调用机制以及性能表现,并通过实际测试给出优化建议。 ... [详细]
  • 自动驾驶中的9种传感器融合算法
    来源丨AI修炼之路在自动驾驶汽车中,传感器融合是融合来自多个传感器数据的过程。该步骤在机器人技术中是强制性的,因为它提供了更高的可靠性、冗余性以及最终的 ... [详细]
  • 使用 Jupyter Notebook 实现 Markdown 编写与代码运行
    Jupyter Notebook 是一个开源的基于网页的应用程序,允许用户在同一文档中编写 Markdown 文本和运行多种编程语言的代码,并实时查看运行结果。 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
  • 本文介绍了如何使用 Google Colab 的免费 GPU 资源进行深度学习应用开发。Google Colab 是一个无需配置即可使用的云端 Jupyter 笔记本环境,支持多种深度学习框架,并且提供免费的 GPU 计算资源。 ... [详细]
  • 本文节选自《NLTK基础教程——用NLTK和Python库构建机器学习应用》一书的第1章第1.2节,作者Nitin Hardeniya。本文将带领读者快速了解Python的基础知识,为后续的机器学习应用打下坚实的基础。 ... [详细]
  • 本文介绍如何使用OpenCV和线性支持向量机(SVM)模型来开发一个简单的人脸识别系统,特别关注在只有一个用户数据集时的处理方法。 ... [详细]
author-avatar
辛博的调调最棒
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有