使用 keras 的句子相似度
Posted
技术标签:
【中文标题】使用 keras 的句子相似度【英文标题】:Sentence similarity using keras 【发布时间】:2017-01-10 08:56:03 【问题描述】:我正在尝试基于此work using the STS dataset 实现句子相似性架构。标签是从 0 到 1 的归一化相似度分数,因此被假定为回归模型。
我的问题是,从第一个纪元开始,损失直接转到NaN
。我做错了什么?
我已经尝试更新到最新的 keras 和 theano 版本。
我的模型的代码是:
def create_lstm_nn(input_dim):
seq = Sequential()`
# embedd using pretrained 300d embedding
seq.add(Embedding(vocab_size, emb_dim, mask_zero=True, weights=[embedding_weights]))
# encode via LSTM
seq.add(LSTM(128))
seq.add(Dropout(0.3))
return seq
lstm_nn = create_lstm_nn(input_dim)
input_a = Input(shape=(input_dim,))
input_b = Input(shape=(input_dim,))
processed_a = lstm_nn(input_a)
processed_b = lstm_nn(input_b)
cos_distance = merge([processed_a, processed_b], mode='cos', dot_axes=1)
cos_distance = Reshape((1,))(cos_distance)
distance = Lambda(lambda x: 1-x)(cos_distance)
model = Model(input=[input_a, input_b], output=distance)
# train
rms = RMSprop()
model.compile(loss='mse', optimizer=rms)
model.fit([X1, X2], y, validation_split=0.3, batch_size=128, nb_epoch=20)
我也尝试使用简单的Lambda
代替Merge
层,但结果相同。
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])
【问题讨论】:
嗨,我知道你是 *** 的新手。为了帮助我们确定问题并更快地获得您需要的答案,您是否可以提供任何其他信息?你看到了什么错误,如果有的话?你期待的是什么? 好吧,现在我想弄清楚为什么我的网络在训练时会变成 nan 损失。 可能你的学习率太高了。也许还有另一个问题。如果您使用的是 Theano,则可以在启动脚本时使用THEANO_FLAGS='mode=NanGuardMode'
,让它在检测到 nan
值时抛出异常,从而为您提供问题所在位置的回溯。
【参考方案1】:
nan 是深度学习回归中的常见问题。由于您使用的是连体网络,您可以尝试以下方法:
-
检查您的数据:它们是否需要标准化?
尝试在网络中添加一个密集层作为最后一层,但要小心选择激活函数,例如回复
尝试使用其他损失函数,例如contrastive_loss
降低你的学习率,例如0.0001
cos 模式没有仔细处理除以零,可能是 NaN 的原因
让深度学习完美地工作并不容易。
【讨论】:
【参考方案2】:我没有遇到nan
问题,但我的损失不会改变。我找到了这个信息
check this out
def cosine_distance(shapes):
y_true, y_pred = shapes
def l2_normalize(x, axis):
norm = K.sqrt(K.sum(K.square(x), axis=axis, keepdims=True))
return K.sign(x) * K.maximum(K.abs(x), K.epsilon()) / K.maximum(norm, K.epsilon())
y_true = l2_normalize(y_true, axis=-1)
y_pred = l2_normalize(y_pred, axis=-1)
return K.mean(1 - K.sum((y_true * y_pred), axis=-1))
【讨论】:
以上是关于使用 keras 的句子相似度的主要内容,如果未能解决你的问题,请参考以下文章
Java之词义相似度计算(语义识别词语情感趋势词林相似度拼音相似度概念相似度字面相似度)