SiameseNet

本文介绍了SiameseNet,一种利用双向LSTM提取文本特征并优化对比损失的深度学习模型。它通过字嵌入、堆叠LSTM层和余弦相似度计算来评估文本对的相似度。此外,文章详细阐述了数据增强策略,如拼写纠错、同义词替换和信息添加,以提升模型的泛化能力。
摘要由CSDN通过智能技术生成

SiameseNet

SiameseNet

孪生网络(SiameseNet):输入是成对的,两部分网络结构和参数一模一样(即只有一个网络)
优点:

  1. 利用双向LSTM抽取语义特征
  2. 利用对比损失优化模型
  3. 提出多种文本数据增强方法

模型结构
在这里插入图片描述
模型流程

  1. 采用字嵌入,长度固定为100,超出部分进行截取,不足补0
  2. 利用双向LSTM提取文本表示特征,堆叠四层双向LSTM结构
  3. 平均池化操作:在文本长度维度上做平均
  4. 全连接层,提取出文本的最终表示
  5. 利用余弦相似度计算两个输入的文本相似度。

模型损失函数
首先,模型输出为余弦相似度,即:
在这里插入图片描述
每一个样本数据的损失函数为:
在这里插入图片描述
其中:
在这里插入图片描述
损失函数的形式本质为两个函数合在一起:
在这里插入图片描述
数据增强

  1. 增加拼写错误,即对于正类样本,随机替换20%字符并删除5%字符,操作后额外生成大量训练数据。另外,再取19928条作为测试数据,这些测试数据中被替换或删除的字符占比5%。(符合正常人类拼写错误)
  2. 同义词替换,对原数据进行同义词扩充。
  3. 添加多余信息,一些文本可能包含无用信息,为近似现实数据,在文本数据上添加一些多余信息。
  4. 人工反馈,人工检测数据是否存在标注错误,人为进行改正。

代码

import torch
import torch.nn as nn
import args
from data_load import load_char_data
from torch.utils.data import Dataset


class SiameseNet(nn.Module):
    def __init__(self, embed):
        super(SiameseNet, self).__init__()
        self.embed = nn.Embedding(args.char_size, args.embedding_size)
        self.embed.weight.data.copy_(torch.from_numpy(embed))
        self.lstm = nn.LSTM(args.embedding_size, args.lstm_hidden_size,
                            num_layers=2, dropout=0.2,
                            bidirectional=True, batch_first=True)

        self.dense = nn.Linear(args.lstm_hidden_size * 2, args.linear_hidden_size)
        self.dropout = nn.Dropout(p=0.3)

    def forward(self, a, b):
        emb_a = self.embed(a)
        emb_b = self.embed(b)

        lstm_a, _ = self.lstm(emb_a)
        lstm_b, _ = self.lstm(emb_b)

        avg_a = torch.mean(lstm_a, dim=1)
        avg_b = torch.mean(lstm_b, dim=1)

        out_a = torch.tanh(self.dense(avg_a))
        out_a = self.dropout(out_a)

        out_b = torch.tanh(self.dense(avg_b))
        out_b = self.dropout(out_b)

        cosine = torch.cosine_similarity(out_a, out_b, dim=1, eps=1e-8)
        return cosine


class LcqmcDataset(Dataset):
    def __init__(self, data_path, vocab_file):
        self.data_path = data_path
        self.vocab_path = vocab_file
        self.a_index, self.b_index, self.label = load_char_data(self.data_path, self.vocab_path)

    def __len__(self):
        return len(self.a_index)

    def __getitem__(self, idx):
        return self.a_index[idx], self.b_index[idx], self.label[idx]


class ContrastiveLoss(nn.Module):
    def __init__(self):
        super(ContrastiveLoss, self).__init__()

    def forward(self, Ew, y):
        l_1 = 0.25 * (1.0 - Ew) * (1.0 - Ew)
        l_0 = torch.where(Ew < args.m * torch.ones_like(Ew), torch.full_like(Ew, 0), Ew) * torch.where(
            Ew < args.m * torch.ones_like(Ew), torch.full_like(Ew, 0), Ew)

        loss = y * 1.0 * l_1 + (1 - y) * 1.0 * l_0
        return loss.sum()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值