深度文本匹配模型(二):Conv-knrm模型复现

本文介绍了Conv-knrm模型,该模型基于k-nrm进行了改进,通过添加n-gram卷积来捕捉更细腻的语义信息。内容包括word embedding、卷积层、交叉匹配层、核池化和全连接层的详细讲解,并提供了数据预处理和完整代码。
摘要由CSDN通过智能技术生成

开篇

这篇是基于k-nrm改进的一篇论文提出的方法。同样的作者,前后隔了一年左右的时间。前面讲k-nrm的博客我没有放出代码,这一篇我会放出一个详细的模型解读源码以供大家参考。本博客没有使用任何公司的数据,也未集成到公司的任何系统中,属于学术型文章开源。

Conv-knrm

Conv-knrm相比k-nrm,最大的改变就是它添加了n-gram的卷积,增加了原先模型的层次,这里有一个好处就是它能够捕捉更加细微的语义实体,交叉的粒度也更加细。这边我放上它完整的模型图,如果大家想更加细致的了解它的原理,建议阅读它的原始论文Convolutional Neural Networks for Soft-Matching N-Grams in Ad-hoc Search。下面我简单的讲一下整体的模型。
这里写图片描述

word embedding

首先还是embedding层,之前的博客已经讲过,就是把我们的句子转换成我们词向量组合的一个矩阵,这样就基本形成了我们的图,编程的时候要注意的是,我们期待卷积的张量是三维了,是带有通道数,原始的输入是要扩展维度的。这点在tensorflow里面尤其要注意。

query = Input(name='query', shape=(text1_maxlen,))
doc = Input(name='doc', shape=(text2_maxlen,))

embedding = Embedding(vocab_size, embed_size, weights=[embed],
                          trainable=True)
##这里的embed是预训练好的词向量
q_embed = embedding(query)
d_embed = embedding(doc)

keras使用预训练的词向量

keras文本与序列处理

Convolutional Layer

就是单纯的卷积层,图中所示的是1-gram,2-gram大小的两种卷积核。

q_convs = []
d_convs = []
for i in range(max_ngram):
    c = keras.layers.Conv1D(num_filters, i + 1, activation='relu', padding='same')
    q_convs.append(c(q_embed))
    d_convs.append(c(d_embed))

这里使用的卷积和tensorflow不一样,它是把词向量的维度当做通道数的,所以使用的卷积是1d的。

Cross-match Layer

这里搞了一波交叉组合矩阵,计算公式依旧是cos。

    for qi in range(max_ngram):
        for di in range(max_ngram):
            # if not corssmatch, then do not match n-gram with different length
            if not if_crossmatch and qi != di:
                print("non cross")
                continue
            q_ngram = q_convs[qi]
            d_ngram = d_convs[di]
            mm = Dot(axes=[2, 2], normalize=True)([q_ngram, d_ngram])

kernel pooling

这个在之前的博客里面详细的解释过,包括它公式,这里不多赘述,我们代码里面见。

    def Kernel_layer(mu, sigma):
        def kernel(x):
            return K.tf.exp(-0.5 * (x - mu) * (x - mu) / sigma / sigma)

        return Activation(kernel)
    for qi in range(max_ngram):
        for di in range(max_ngram):
            # if not corssmatch, then do not match n-gram with different length
            if not if_crossmatch and qi != di:
                print("non cross")
                continue
            q_ngram = q_convs[qi]
            d_ngram = d_convs[di]
            mm = Dot(axes=[2, 2], normalize=True)([q_ngram, d_ngram])

            for i in range(kernel_num):
                mu = 1. / (kernel_num - 1) + (2. * i) / (kernel_num - 1) - 1.0
         
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值