✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。
我是Srlua小谢,在这里我会分享我的知识和经验。🎥
希望在这里,我们能一起探索IT世界的奥妙,提升我们的技能。🔮
记得先点赞👍后阅读哦~ 👏👏
📘📚 所属专栏:传知代码论文复现
欢迎访问我的主页:Srlua小谢 获取更多信息和资源。✨✨🌙🌙
目录
本文所有资源均可在该地址处获取。
概述
近年来,对话理解引起了广泛关注,其主要任务是根据对话上下文预测每个话语的标签。为了准确识别目标句子的情感,关键在于将句子语义与上下文信息相结合。目前的研究大多集中于捕捉不同类型的上下文信息,并通过各种方式进行整合,如当前和全局上下文,或通过同一说话者和不同说话者之间的整合。然而,现有研究对上下文整合后的词表示重要性探讨不足,而词语信息对于反映说话者在对话中的情感至关重要。因此,本研究旨在探讨累积词向量表示在句子建模中的作用,并结合多层次上下文整合。我们提出了一种有效的句子建模方法,并在四个广泛认可的基准数据集(IEMOCAP、MELD、EmoryNLP 和 DailyDialog)上取得了具有竞争力的最新成果。我们的源码可以通过以下链接获取。
基本方法
1.Utterance Vector Representation(每一句话的向量表示)
旨在将包含多个话语的原始对话(C)从文本转换为隐藏向量。按照BERT模型[16]提出的模板,每个输入句子(si)会与特殊标记[CLS]连接,然后输入预训练语言模型(例如RoBERTa [17])。特别是,如前所述,另一种方法是基于固定窗口大小的周围话语构建话语向量。在这种情况下,si 被替换为按以下模板组合的文本:[CLS], si−w, si−w+1 …, , si, , … si+w,其中w是局部上下文窗口大小的超参数(例如,w = 2)。[CLS]标记的隐藏向量用于表示话语(ui,其中i是对话中第i个话语的索引,0 ≤ i < |C|)。
h[CLS],hwords=RoBERTa(si)(1)h[CLS],hwords=RoBERTa(si)(1)
ui=h[CLS](2)ui=h[CLS](2)
个人理解:这个部分是非常关键的,人工智能深度学习的本质是将世间万物映射到一个机器可以理解的向量空间再进行操作;
2.上下文层次建模
该组件旨在学习对话中话语之间的关系。给定所有句子向量表示(uiui),通过注意力机制 [22] 建模这些话语之间的各种关系,包括全局上下文、说话者内部和说话者之间的关系 [3]。公式如下
qh,kh,vh=uiWhq,uiWhk,uiWhv(3)qh,kh,vh=uiWhq,uiWhk,uiWhv(3)
headh=Attention(qh,kh,vh,mask)(4)headh=Attention(qh,kh,vh,mask)(4)
hMulti-head=concat([headh∣0<h≤H])Wo(5)hMulti-head=concat([headh∣0<h≤H])Wo(5)
通过这些步骤,模型能够捕捉对话中的不同层次的上下文关系。
具体来说,按照 [3] 的方法,我们为每种关系构建掩码矩阵,例如全局上下文(所有话语对都连接)、说话者内部(仅连接同一说话者的话语对)和说话者之间(仅连接不同说话者的话语对)。因此,我们得到了三个新的隐藏状态(来自公式 5):hglobalhglobal、hintrahintra 和 hinterhinter,用于建模对话中话语之间的不同关系,并传递给分类组件。
3.将提取到的特征进行分类
整合所有话语的隐藏特征以进行情感标签分类
hout=uiWu+hglobalWg+hintraWi+hinterWthout=uiWu+hglobalWg+hintraWi+hinterWt
eout=softmax(hout)eout=softmax(hout)
其中,W_* 是可学习的参数。然后,情感向量 eout 被用来通过交叉熵函数计算损失,并根据真实的情感标签进行训练.
简单优化
在本研究中,重点是词向量表示的积累,这在之前的研究中尚未得到充分探讨。在DialogueEIN [3] 架构,作者单独对话语进行编码,因此尚未充分利用预训练语言模型的全部能力。此外,一些先前的工作也将周围的对话语与特殊标记 [CLS] 连接起来,然后由预训练语言模型进行编码(图1中的方法2)。这些模型利用自注意力机制来区分哪些对话语用于情感标注,哪些用于上下文信息。
提出了一种机制(称为 AccWR)用于在对话建模中积累词向量表示。我们的机制简单而有效,因为它利用了基于周围上下文的预训练语言模型的全部能力,并通过直接关注被考虑的对话语来支持模型。为此,我们使用了几种不同的词向量聚合方法:
平均法: 我们使用平均函数来聚合当前句子的所有词隐藏状态。公式 (2) 被替换为:
ui=average(hsiwords)ui=average(hsiwords)
LSTM: 我们使用双向LSTM架构 [12] 来丰富当前句子词隐藏状态的顺序信息。公式 (2) 被修改为以下公式:
ui=average(BiLSTM(hsiwords))ui=average(BiLSTM(hsiwords))
多层感知机(MLP): 我们使用一个简单的多层感知机来用 tanh 激活函数聚合词信息。
ui=tanh(average(hsiwords)⋅Ws)ui=tanh(average(hsiwords)⋅Ws)
最后,该模型的其他组件保持与前一节中提出的基线模型相同。
演示效果
核心逻辑
在这里可以粘贴您的核心代码逻辑:
# start
def __call__(self, batch): #调用的默认先执行的函数
raw_sentences = []
raw_sentences_flatten = []
labels = []
# masked tensor
lengths = [len(sample['sentences']) for sample in batch]
max_len_conversation = max(lengths) #找出最长的对话
padding_utterance_masked = torch.BoolTensor([[False]*l_i+ [True]*(max_len_conversation - l_i) for l_i in lengths])
# collect all sentences
# - intra speaker
intra_speaker_masekd_all = torch.BoolTensor(len(batch), max_len_conversation,max_len_conversation)
for i, sample in enumerate(batch):
sentences_mixed_arround = self.sentence_mixed_by_surrounding(sample['sentences'],
around_window=self.window_ct,
s_id=sample['s_id'],
genders=sample['genders'],
data_name=self.dataset_name)
# conversation padding
padded_conversation = sentences_mixed_arround + ["<pad_sentence>"]* (max_len_conversation - lengths[i])
raw_sentences.append(padded_conversation)
raw_sentences_flatten += padded_conversation
# label padding
labels += [int(label) for label in sample['labels']] + [-1]* (max_len_conversation - lengths[i])
# speaker
intra_speaker_masekd= torch.BoolTensor(len(padded_conversation),len(padded_conversation)).fill_(False)
for j in range(len( sample['genders'])):
for k in range(len( sample['genders'])):
gender_j = sample['genders'][j]
gender_k = sample['genders'][k]
if gender_j == gender_k:
intra_speaker_masekd[j][k] = True
else:
intra_speaker_masekd[j][k] = False
intra_speaker_masekd_all[i] = intra_speaker_masekd
if len(labels)!= len(raw_sentences_flatten):
print('len(labels)!= len(raw_sentences_flatten)')
# utterance vectorizer
# v_single_sentences = self._encoding(sample['sentences'])
contextual_sentences_ids = self.tokenizer(raw_sentences_flatten, padding='longest', max_length=512, truncation=True, return_tensors='pt')
sent_indices, word_indices = torch.where(contextual_sentences_ids['input_ids'] == self.separate_token_id)
gr_sent_indices = [[] for e in range(len(raw_sentences_flatten))]
for sent_idx, w_idx in zip (sent_indices, word_indices):
gr_sent_indices[sent_idx].append(w_idx.item())
cur_sentence_indexes_masked = torch.BoolTensor(contextual_sentences_ids['input_ids'].shape).fill_(False)
for i in range(contextual_sentences_ids['input_ids'].shape[0]):
if raw_sentences_flatten[i] =='<pad_sentence>':
cur_sentence_indexes_masked[i][gr_sent_indices[i][0]] = True
continue
for j in range(contextual_sentences_ids['input_ids'].shape[1]):
if gr_sent_indices[i][0] <= j <= gr_sent_indices[i][1]:
cur_sentence_indexes_masked[i][j] = True
return (contextual_sentences_ids, torch.LongTensor(labels), padding_utterance_masked, intra_speaker_masekd_all, cur_sentence_indexes_masked, raw_sentences)
原创部分说明
1.开源代码无测试相关代码,已进行补充;
2.代码提供已经完成训练的模型,大小约3GB,在readme文件的百度云网盘链接中获取;
使用方式
1.下载源码
2.按照readme中详细步骤配置环境
3.关于训练
将readme中训练相关的bash代码粘贴到终端处即可:
4.关于测试
将readme中测试相关的bash代码粘贴到终端处即可:
5.提供已完成训练的模型文件
在云盘中,readme文件中有具体链接地址
6.演示
b站上有操作演示,购买后有任何疑问欢迎给我留言。
温馨提示
请注意目录,更改成本地目录