lhj*_*ohn 4 python embedding hyperbolic-function tensorflow
我正在尝试为我的分层数据实现 Poincar\xc3\xa9 嵌入,如 Facebook 的一篇论文(链接)中所讨论的。您可以在此处找到 Poincar\xc3\xa9 嵌入的更易于理解的解释。
\n根据这篇论文,我在这里和这里找到了 Tensorflow 的一些实现,以及Tensorflow Addons 中的tfa.layers.PoincareNormalize。后者甚至有上面提到的论文的链接,这让我相信这对我来说可能是一个很好的起点。然而,到目前为止,我没有成功实现 tfa.layers.PoincareNormalize,除了我链接的 API 页面上的一些通用信息之外,也找不到任何文档。
\n有谁知道应该如何实现该层以提供论文中讨论的双曲空间中的嵌入?我的出发点是使用标准嵌入层的实现,如下所示(它实际上是分类变量的实体嵌入)?
\ninput = Input(shape=(1, ))\nmodel = Embedding(input_dim=my_input_dim, \n output_dim=embed_dim, name="my_feature")(input)\nmodel = Reshape(target_shape=(embed_dim, ))(model)\nmodel = Dense(1)(model)\nmodel = Activation(\'sigmoid\')(model)\n
Run Code Online (Sandbox Code Playgroud)\n由于输入不同,仅用 tfa.layers.PoincareNormalize 替换 Embedding 层是行不通的。我假设它可以放置在嵌入层之后的某个位置,以便对于反向传播步骤,“值”在每次迭代时都投影到双曲空间中,但到目前为止也没有运气。
\n\n\n然而,虽然复杂的符号数据集通常表现出潜在的层次结构,但最先进的方法通常学习欧几里德向量空间中的嵌入,而这并没有考虑到这一特性。为此,我们引入了一种新方法,通过将符号数据嵌入到双曲空间 \xe2\x80\x93 或更准确地说嵌入到 n 维 Poincar\xc3\xa9 球中来学习符号数据的层次表示。
\n
Poincar\xc3\xa9 嵌入允许您在非欧几里得空间中创建分层嵌入。与中心的向量相比,Poincar\xc3\xa9 球外侧的向量层次较低。
\n\n将欧几里得度量张量映射到黎曼度量张量的变换是一个开放的 d 维单位球。
\n\n该非欧几里得空间中 2 个向量之间的距离计算如下
\n\nPoincar\xc3\xa9 嵌入的研究论文写得非常精彩,您也会在流行的库中找到一些精彩的实现。不用说,他们的评价被低估了。
\n您可以在以下位置找到两个可以使用的实现:
\ntensorflow_addons.PoincareNormalize
gensim.models.poincare
根据文档,对于一维张量,tfa.layers.PoincareNormalize
沿 axis=0 计算以下输出。
(x * (1 - epsilon)) / ||x|| if ||x|| > 1 - epsilon\noutput =\n x otherwise\n
Run Code Online (Sandbox Code Playgroud)\n对于更高维的张量,它沿维度轴独立地标准化每个一维切片。
\n这种变换可以简单地应用于 n 维的嵌入。让我们为时间序列的每个元素创建 5 个暗淡嵌入。本例中维度轴=-1,从欧几里德空间映射到非欧几里德空间。
\nfrom tensorflow.keras import layers, Model, utils\nimport tensorflow_addons as tfa\n\nX = np.random.random((100,10))\ny = np.random.random((100,))\n\n\ninp = layers.Input((10,))\nx = layers.Embedding(500, 5)(inp)\nx = tfa.layers.PoincareNormalize(axis=-1)(x) #<-------\nx = layers.Flatten()(x)\nout = layers.Dense(1)(x)\n\nmodel = Model(inp, out)\nmodel.compile(optimizer=\'adam\', loss=\'binary_crossentropy\')\nutils.plot_model(model, show_shapes=True, show_layer_names=False)\n\nmodel.fit(X, y, epochs=3)\n
Run Code Online (Sandbox Code Playgroud)\nEpoch 1/3\n4/4 [==============================] - 0s 2ms/step - loss: 7.9455\nEpoch 2/3\n4/4 [==============================] - 0s 2ms/step - loss: 7.5753\nEpoch 3/3\n4/4 [==============================] - 0s 2ms/step - loss: 7.2429\n<tensorflow.python.keras.callbacks.History at 0x7fbb14595310>\n
Run Code Online (Sandbox Code Playgroud)\n庞加莱嵌入的另一种实现可以在 Gensim 中找到。它与您使用 Gensim 的 Word2Vec 时使用的非常相似。
\n该过程将是 -
\nfrom gensim.models.poincare import PoincareModel\n\nrelations = [(\'kangaroo\', \'marsupial\'), (\'kangaroo\', \'mammal\'), (\'gib\', \'cat\'), (\'cow\', \'mammal\'), (\'cat\',\'pet\')]\n\nmodel = PoincareModel(relations, size = 2, negative = 2) #Change size for higher dims\nmodel.train(epochs=10)\n\nprint(\'kangroo vs marsupial:\',model.kv.similarity(\'kangaroo\',\'marsupial\'))\nprint(\'gib vs mammal:\', model.kv.similarity(\'gib\',\'mammal\'))\n\nprint(\'Embedding for Cat: \', model.kv[\'cat\'])\n
Run Code Online (Sandbox Code Playgroud)\nkangroo vs marsupial: 0.9481239343527523\ngib vs mammal: 0.5325816385250299\n\nEmbedding for Cat: [0.22193988 0.0776986 ]\n
Run Code Online (Sandbox Code Playgroud)\n有关训练和保存庞加莱嵌入的更多详细信息,请参阅此处。
\n