siamese模型码详解(每一句代码都有解释!!!)

本文详细解析Siamese模型在文本相似度计算中的应用,包括数据处理(读取、格式调整、batch设置)、训练过程(参数设置、数据切分、验证集训练、每个epoch训练)和LSTM模型的初始化与神经网络层。每一步代码都有解释,适合初学者理解。
摘要由CSDN通过智能技术生成

最近在研究Siamese模型来进行文本相似度的计算,今天就做一期代码详解,每一行的代码都会做出相应的解释,对于初学LSTM的人来说读懂代码是非常有必要的,Siamese模型就是将两个句子(训练数据)通过embeding层(word2vec)分别输入到LSTM进行运算,并共享参数,利用损失函数不断的进行正向传播和反向传播来优化参数,最终达到成为一个比较优秀的模型

原理就不在细说了,这里主要是把代码解释一下

(1)数据处理部分

首先是数据预处理部分:这里主要分为“读取数据“,“调整数据格式”和“对于batch 的设置”

读取数据

将数据通过pickle工具读取出来,因为pickle序列化和反序列化的工具,可以持久化储存数据格式,将数据读取出来后,分成句子和标签,匹配句子中的每一个单词对应的wor2dvec(词向量)最后返回数据和标签

def load_set(embed, datapath, embed_dim):
    #使用pickle读取数据
    with open(datapath, 'rb') as f:
        mylist = pkl.load(f,encoding="utf-8")
    #初始化句子和标签
    s0 = []
    s1 = []
    labels = []
    #将句子一句一句的读取出来
    for each in mylist:
        #句子一
        s0x = each[0]
        #句子二
        s1x = each[1]
        #标签
        label = each[2]
        #将标签转化为float类型的
        score = float(label)
        #存入标签
        labels.append(score)
        #将句子中的每一个单词读取出来
        for i, ss in enumerate([s0x, s1x]):
            #将句子分成一个个的单词
            words = word_tokenize(ss)
            index = []
            for word in words:
                #如果单词存在词典中,将该词对应的词向量存入index中
                if word in dtr:
                    index.append(embed[dtr[word]])
                #如果单词没有存在词典,而是在embed中,将对应的词向量存入index中
                elif word in embed.vocab:
                    index.append(embed[word])
                #否则将该词屏蔽掉(设置为0)
                else:
                    index.append(np.zeros(embed_dim, dtype=float))
            #i=0 表示的是s0的数据,将s0的embed存入
            if i == 0:
                s0.append(np.array(index, dtype=float))
            # 1=0 表示的是s1的数据,将s1的embed存入(embed表示的是对应的词向量)
            else:
                s1.append(np.array(index, dtype=float))
    #返回标签和数据
    return [s0, s1, labels]
调整数据格式

将数据取出来打散,这是为了提升模型的泛化能力,将数据格式统一,由于句子的长短不一,因此进行特殊化处理,保证是句子数据格式一样,设置最大长度的句子,如果句子的长度小于最大长度,末尾表示0,

# 从文件中读取数据集,并分为训练、验证和测试集合
def load_data(max_len, embed, datapath, embed_dim):
    #读取数据
    train_set = load_set(embed, datapath, embed_dim)
    #将数据分为句子1、句子2和标签
    train_set_x1, train_set_x2, train_set_y = train_set
    # n_samples表示句数据的个数
    n_samples = len(train_set_x1)
    # 打散数据集(permutation是最常用的打散数据集的方式,可以保障数据和标签不混乱)
    sidx = np.random.permutation(n_samples)
    train_set_x1 = [train_set_x1[s] for s in sidx]
    train_set_x2 = [train_set_x2[s] for s in sidx]
    train_set_y = [train_set_y[s] for s in sidx]
    # 打散划分好的训练和测试集
    train_set = [train_set_x1, train_set_x2, train_set_y]
    # 创建用于存放训练、测试和验证集的矩阵
    #max_len 表示句子长度
    # embed_dim表示的是词向量的维度
    # len(train_set[0])表示的是句子的个数
    new_train_set_x1 = np.zeros([len(train_set[0]), max_len, embed_dim], dtype=float)
    new_train_set_x2 = np.zeros([len(train_set[0]), max_len, embed_dim], dtype=float)
    new_train_set_y = np.zeros(len(train_set[0]), dtype=float)
    mask_train_x1 = np.zeros([len(train_set[0]), max_len])
    mask_train_x2 = np.zeros([len(train_set[0]), max_len])
 #匹配数据矩阵,大于最大长度的删掉,小于的补零
    def padding_and_generate_mask(x1, x2, y, new_x1, new_x2, new_y, new_mask_x1, new_mask_x2):
        for i, (x1, x2, y) in enumerate(zip(x1, x2, y)):
            # whether to remove sentences with length larger than maxlen
            #如果句子一小于最大长度
            if len(x1) <= max_len:
                #前面放数据后面补零
                new_x1[i, 0:len(x1)] = x1
                # 将句子的最后一个词赋值为1,表示句子的结尾
                new_mask_x1[i, len(x1) - 1] = 1
                #标签数据不变
                new_y[i] = y
            else:
                #只保留前max-len的值  ::??
                new_x1[i, :, :] = (x1[0:max_len:embed_dim])
                #最后一个就是句子结尾
                new_mask_x1[i, max_len - 1] = 1
                #标签数据不用变
                new_y[i] = y
                #和x1表示的一样
            if len(x2) <= max_len:
                new_x2[i, 0:len(x2)] = x2
                new_mask_x2[i, len(x2) - 1] = 1  # 标记句子的结尾
                new_y[i] = y
            else:
                new_x2[i, :, :] = (x2[0:max_len:embed_dim])
                new_mask_x2[i, max_len - 1] = 1
                new_y[i
  • 9
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值