LoginSignup
8
5

More than 3 years have passed since last update.

kerasでcos類似度レイヤーを作る

Last updated at Posted at 2018-03-24

環境

  • keras (2.1.4)
  • tensorflow-gpu (1.3.0)

cosレイヤー作る

実際に書くのは 1-cos(x) のタイプ
ここでは10次元のベクトル2つのcos類似度?を求めます

Sequentialじゃなくてfunctional APIでモデル構築

from keras.models import Model
from keras.layers import Input, Dot, Reshape, Lambda
import keras.backend as K

import numpy as np

input_dim = 10
input_a = Input(shape=(input_dim, 1))
input_b = Input(shape=(input_dim, 1))

# --------------------------------------------------------------
# ここで 2入力のcos類似度レイヤーを定義しています
# --------------------------------------------------------------
cos_distance = Dot(axes = 1, normalize=True)([input_a, input_b]) # ここで cos(x)
cos_distance = Reshape((1,))(cos_distance)
cos_similarity = Lambda(lambda x: 1-x)(cos_distance) # ここで 1-cos(x) (こっちのほうが使いやすい的な)


model = Model(inputs=[input_a, input_b], outputs=[cos_similarity])

v1 = np.random.uniform(-1,1,10).reshape(1, 10, 1)
v2 = np.random.uniform(-1,1,10).reshape(1, 10, 1)

[[y]] = model.predict([v1, v2])
print("model: ", y)

def cos_sim(v1, v2):
    return 1-(np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)))

cs = cos_sim(v1[0].reshape(10), v2[0].reshape(10))
print("numpy: ", cs)

出力はこんな感じ

model:  0.6803855
numpy:  0.6803854938830672

正しくcos類似度を求めるレイヤーが作れましたっ

蛇足

参考にしたissueにある、mergeを使った書き方(古い)(需要ない)

from keras.models import Model
from keras.layers import Input, merge, Reshape, Lambda
import keras.backend as K

~~
~~

cos_distance = merge([input_a, input_b], mode='cos', dot_axes=1) # ここで cos(x)
cos_distance = Reshape((1,))(cos_distance)
cos_similarity = Lambda(lambda x: 1-x)(cos_distance) # ここで 1-cos(x) (こっちのほうが使いやすい的な)

~~
~~

UserWarning: The merge function is deprecated and will be removed after 08/2017. Use instead layers from keras.layers.merge, e.g. add, concatenate, etc.

はい。

追記

Input(shape=(input_dim, 1)) じゃなくて Input(shape=(input_dim,)) もおっけい(当たり前っちゃ当たり前かも)

from keras.models import Model
from keras.layers import Input, Dot, Reshape, Lambda
import keras.backend as K

import numpy as np

input_dim = 10
input_a = Input(shape=(input_dim,))
input_b = Input(shape=(input_dim,))

# --------------------------------------------------------------
# ここで 2入力のcos類似度レイヤーを定義しています
# --------------------------------------------------------------
cos_distance = Dot(axes = 1, normalize=True)([input_a, input_b])
cos_distance = Reshape((1,))(cos_distance)
cos_similarity = Lambda(lambda x: 1-x)(cos_distance)


model = Model(inputs=[input_a, input_b], outputs=[cos_similarity])

v1 = np.random.uniform(-1,1,10).reshape(1, 10)
v2 = np.random.uniform(-1,1,10).reshape(1, 10)

[[y]] = model.predict([v1, v2])
print("model: ", y)

def cos_sim(v1, v2):
    return 1-(np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)))

cs = cos_sim(v1[0].reshape(10), v2[0].reshape(10))
print("numpy: ", cs)

参考

いじょうっ!

最後まで読んでくださってありがとうございますっ
(よかったらいいねくださいっ!励みになります!!!!!)

twitter: https://twitter.com/namahoge

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5