Cálculo de la similitud de coseno entre dos tensores en Keras.

He estado siguiendo un tutorial que muestra cómo hacer un modelo de word2vec.

Este tutorial utiliza esta pieza de código:

similarity = merge([target, context], mode='cos', dot_axes=0) (no se proporcionó ninguna otra información, pero supongo que esto proviene de keras.layers )

Ahora, he investigado un poco sobre el método de merge , pero no pude encontrar mucho al respecto. Por lo que entiendo, ha sido reemplazado por muchas funciones como layers.Add(), layers.Concat()...

¿Qué debo usar? Hay .Dot() , que tiene un parámetro de axis (que parece ser correcto) pero ningún parámetro de mode .

¿Qué puedo usar en este caso?

Hay algunas cosas que no están claras de la documentación de Keras que creo que son cruciales de entender:

Para cada función en la documentación de keras para Merge , hay una minúscula y una mayúscula, una definida, es decir, add() y Add() .

En Github, farizrahman4u describe las diferencias:

 Merge is a layer. Merge takes layers as input Merge is usually used with Sequential models merge is a function. merge takes tensors as input. merge is a wrapper around Merge. merge is used in Functional API Using Merge: left = Sequential() left.add(...) left.add(...) right = Sequential() right.add(...) right.add(...) model = Sequential() model.add(Merge([left, right])) model.add(...) using merge: a = Input((10,)) b = Dense(10)(a) c = Dense(10)(a) d = merge([b, c]) model = Model(a, d) 

Para responder a su pregunta, ya que Merge ha quedado en desuso, tenemos que definir y construir una capa nosotros mismos para la cosine similarity . En general, esto implicará el uso de esas funciones en minúsculas, que envolvemos dentro de un Lambda para crear una capa que podemos usar dentro de un modelo.

He encontrado una solución aquí:

 from keras import backend as K def cosine_distance(vests): x, y = vests x = K.l2_normalize(x, axis=-1) y = K.l2_normalize(y, axis=-1) return -K.mean(x * y, axis=-1, keepdims=True) def cos_dist_output_shape(shapes): shape1, shape2 = shapes return (shape1[0],1) distance = Lambda(cosine_distance, output_shape=cos_dist_output_shape)([processed_a, processed_b] 

Dependiendo de sus datos, es posible que desee eliminar la normalización de L2. Lo que es importante tener en cuenta acerca de la solución es que se construye utilizando la función Keras api, por ejemplo, K.mean() . Creo que esto es necesario al definir una capa personalizada o incluso funciones de pérdida.

Espero haber sido claro, esta fue mi primera respuesta de SO!

La capa de puntos en Keras ahora admite la similitud de coseno incorporada utilizando el parámetro normalize = True .

De los documentos de Keras:

keras.layers.Dot(axes, normalize=True)

normalizar: si L2 normaliza las muestras a lo largo del eje del producto de puntos antes de tomar el producto de puntos. Si se establece en Verdadero, la salida del producto punto es la proximidad del coseno entre las dos muestras.

Fuente