download:云原生 + 边缘计算 +KubeEdge,打造智能边缘治理平台
Embedding 的中文含意是嵌入(将一个物品嵌入到另一个空间中),这种思维同 Embedding 在深度学习中的作用类似。Embedding 最早应是出现在 NLP 领域,比如 word2vec,起初推广至其余领域,例如搜推广等。在学习过一段时间后,现对 Embedding 的作用和生成方法做一个简要的总结。
Embedding 是对某个对象在低维浓密空间上的一个向量示意,它可能将高维浓密特色转化为一个低维的浓密向量,进而提高模型的泛化性能,这个向量示意表征出了原始对象的某些个性,Embedding 之间的距离可示意两个对象之间的类似性。另外 Embedding 的生成可能和下层深度神经网络模型的锤炼独立进行,因此在迁徙学习或者冷启动中也有相应的利用。
晚期的矩阵合成已经有了 Embedding 的思维,例如对共现矩阵进行合成失去隐向量的过程。前面就是词向量在天然语言处理领域大放异彩,并逐渐取代了以往的 n -gram 方法,其中代表性的 word2vec 方法是 CBOW 和 Skip-gram 方法,总体的网络结构如下:
词向量的生成可能看做是对离散变量(特色)求对应的 Embedding 的过程,输出的是每个词对应的 one-hot 向量,而后对应的隐层中每行的权重即为 Embedding 向量。one-hot 向量和隐层权重的乘积本质上是一个查表的过程。在推荐领域,求离散变量对应的 Embedding 的过程也是一个查表的过程,即需要对不同的离散变量进行编号,而后在表中查找对应地位的 Embedding 向量。
对于连续变量,求 Ebedding 的方法目前有多种:例如间接将连续型变量输出到 DNN 中输入 Embedding,而后再和离散型变量的 Embedding 进行 concat;另外一种方法是 Field Embedidng,划分为多个域,同一个域内共享同一个 Embedding,连续变量对应的 Embedding 为其数值乘以对应域内的 Embedding;第三种方法则是对连续变量进行离散化,而后转化为求离散变量的 Embedding,这种方法的缺点是生成的 Embedding 可能不具备足够的分别性,例如间断值处于离散化边陲或者离散化为同一个值的情况。在 2021 KDD 上华为提出了名为 AutoDis 的连续变量的 Embedding 方法,此方法将间断值输出到 DNN 中,通过 softmax 输入对应的 K 个桶的概率,每个桶对应的一个 Embedding,而后用最大池化或者 Top- k 或者加权平均进行聚合失去对应的 Embedidng,此过程融合了 attention 的思维。上面是 Embedding 的一种代码实现形式(连续变量进行离散化):
class CpuEmbedding(nn.Module):
def __init__(self, num_embeddings, embed_dim):
super(CpuEmbedding, self).__init__()
self.weight = nn.Parameter(torch.zeros((num_embeddings, embed_dim)))
nn.init.xavier_uniform_(self.weight.data)
def forward(self, x):
"""
:param x: shape (batch_size, num_fields)
:return: shape (batch_size, num_fields, embedding_dim)
"""
return self.weight[x]
class Embedding:
def __new__(cls, num_embeddings, embed_dim):
if torch.cuda.is_available():
embedding = nn.Embedding(num_embeddings, embed_dim)
nn.init.xavier_uniform_(embedding.weight.data)
return embedding
else:
return CpuEmbedding(num_embeddings, embed_dim)
class FeaturesEmbedding(nn.Module):
def __init__(self, field_dims, embed_dim):
super(FeaturesEmbedding, self).__init__()
self.embedding = Embedding(sum(field_dims), embed_dim)
# e.g. field_dims = [2, 3, 4, 5], offsets = [0, 2, 5, 9]
self.offsets = np.array((0, *np.cumsum(field_dims)[:-1]), dtype=np.long)
复制代码
另外按照 Embedding 的生成工作的类型分类,可能将其分为序列生成和目标拟合两种,比如词向量的生成属于序列生成类型,推荐领域中双塔模型的 Embedding 属于目标拟合类型。从更广的层面看,利用无监督学习方法失去的表征 Representation 也是一种形式的 Embedding,例如各种形式的编码器 Encoder 输入的表征,或者通过对比学习失去的表征,都可能按照 Embedding 的形式用于上游的工作,另外还有图卷积中 Graph Embedding,也是一块可能深挖的领域。