環境
- 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 fromkeras.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