简体   繁体   English

计算 lambda 层中两个张量向量之间的余弦相似度?

[英]Computing cosine similarity between two tensor vectors in lambda layer?

Here's the basic code,这是基本代码,

def euclidean_distance(vects):
    x, y = vects
    sum_square = K.sum(K.square(x - y), axis=1, keepdims=True)
    return K.sqrt(K.maximum(sum_square, K.epsilon()))

def eucl_dist_output_shape(shapes):
    shape1, shape2 = shapes
    return (shape1[0], 1)


# measure the similarity of the two vector outputs
output = Lambda(euclidean_distance, name="output_layer", output_shape=eucl_dist_output_shape)([output_a, output_b])

# specify the inputs and output of the model
model = Model([input_a, input_b], output)

I want to use cosine similarity (0 to 1 scale) instead of euclidean distance to measure the similarity between two vectors, I tried to use cosine_similarity from scikit-learn but it didn't work.我想使用余弦相似度(0 到 1 比例)而不是欧几里得距离来测量两个向量之间的相似度,我尝试使用cosine_similarity中的scikit-learn但它没有用。

So, we need to use keras.backend to build it?那么,我们需要使用keras.backend来构建它吗? Can someone tell me how do I do it?有人可以告诉我该怎么做吗?

Previously, in old keras , we can use mode='cos' in the merge layer but it's deprecated in new tf. keras以前,在旧的keras中,我们可以在merge层中使用mode='cos'但在新的tf. keras tf. keras . tf. keras Now we can use layers. Dot现在我们可以使用layers. Dot layers. Dot layer and specify normalize=True for cosine proximity or cosine similarity or ( 1 - cosine distance ). layers. Dot层并为余弦接近度余弦相似度或( 1 - 余弦距离)指定normalize=True According to the doc :根据 文档

tf.keras.layers.Dot(
    axes, normalize=False, **kwargs
)

normalize : Whether to L2-normalize samples along the dot product axis before taking the dot product. normalize :是否在取点积之前沿积轴对样本进行L2 标准化 If set to True , then the output of the dot product is the cosine proximity between the two samples.如果设置为True ,则点积的 output 是两个样本之间的余弦接近度

So, we can compute cosine similarity of the two samples using the built-in layer.因此,我们可以使用内置层计算两个样本的余弦相似度 But as you seeking a way to use the Lambda layer to wrap a custom-defined cosine similarity function, here are some demonstration using both of them.但是当您寻求一种使用Lambda层来包装自定义余弦相似度function 的方法时,这里有一些使用它们的演示。

from tensorflow.keras import backend as K
from tensorflow.keras.layers import Lambda
import tensorflow as tf 

# computing cosine similarity 
def cosine_similarity(vests):
    x, y = vests
    x = K.l2_normalize(x, axis=-1)
    y = K.l2_normalize(y, axis=-1)
    return K.batch_dot(x, y, axes=-1)

def cos_sim_output_shape(shapes):
    shape1, shape2 = shapes
    return (shape1[0], 1)

Let's take 2 samples and run them to check their similarity:让我们取 2 个样本并运行它们以检查它们的相似性:

# 2 samples 
x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
x2 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))

# (1). Wrap custom function into Lambda layer
distance = Lambda(cosine_similarity, 
                  output_shape=cos_sim_output_shape)([x1, x2])
print(distance.shape, distance.numpy())

# (2). Use built-in method: Dot layer with normalize = True
dotted = tf.keras.layers.Dot(axes=-1, normalize=True)([x1, x2])
print(dotted.shape, dotted.numpy())

(5, 1) [[-0.22463222]
 [-0.22639492]
 [-0.2283202 ]
 [-0.22915731]
 [-0.22962123]]

(5, 1) [[-0.22463222]
 [-0.22639492]
 [-0.2283202 ]
 [-0.22915731]
 [-0.22962123]]

The following article has details on how to calculate the cosine similarity.以下文章详细介绍了如何计算余弦相似度。 I have created a simple example using the same article:我使用同一篇文章创建了一个简单的示例:

Article: https://towardsdatascience.com/cosine-similarity-how-does-it-measure-the-similarity-maths-behind-and-usage-in-python-50ad30aad7db文章: https://towardsdatascience.com/cosine-similarity-how-does-it-measure-the-similarity-maths-behind-and-usage-in-python-50ad30aad7db

Example:例子:

import tensorflow as tf
from tensorflow.keras.layers import Lambda

A = tf.constant([7,3])
B = tf.constant([3,7])

# cosine similarity between A and B using numpy

def cos_sim(vects):
  A, B = vects
  cos_sim=np.dot(A,B)/(np.linalg.norm(A)*np.linalg.norm(B))
  return cos_sim

output = Lambda(cos_sim, name="output_layer")([A, B])

>>>output: 0.7241379310344827

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM