假设SENT_a和SENT_b是一组相似句,那么在同一个batch中,把[CLS] SENT_a [SEP] SENT_b [SEP]和[CLS] SENT_b [SEP] SENT_a [SEP]都加入训练,做一个相似句的生成任务,这是Seq2Seq部分。
另一方面,把整个batch内的[CLS]向量都拿出来,得到一个bxd的句向量矩阵V(b是batch_size,d是hidden_size),然后对d维度做l2归一化,得到新的V,然后两两做内积,得到bxv的相似度矩阵VV^T,接着乘以一个scale(我们取了30),并mask掉对角线部分,最后每一行进行softmax,作为一个分类任务训练,每个样本的目标标签是它的相似句(至于自身已经被mask掉)。说白了,就是把batch内所有的非相似样本都当作负样本,借助softmax来增加相似样本的相似度,降低其余样本的相似度。
softmax除了归一化还有有放大的作用 1.语料不咋好,神经网络会自动泛化好的,有什么根据吗? 1.依据是“正确的都是相似的,错误的各有各的错误”,所以当数据足够多时,正确的效应能叠加,错误的效应有可能相互抵消;
with paddle.no_grad():
for batch_data in data_loader:
query_input_ids, query_token_type_ids, title_input_ids, title_token_type_ids = batch_data
query_input_ids = paddle.to_tensor(query_input_ids)
query_token_type_ids = paddle.to_tensor(query_token_type_ids)
title_input_ids = paddle.to_tensor(title_input_ids)
title_token_type_ids = paddle.to_tensor(title_token_type_ids)
vecs_query = model(
input_ids=query_input_ids, token_type_ids=query_token_type_ids)
vecs_title = model(
input_ids=title_input_ids, token_type_ids=title_token_type_ids)
vecs_query = vecs_query[1].numpy()
vecs_title = vecs_title[1].numpy()
vecs_query = vecs_query / (vecs_query**2).sum(axis=1,
keepdims=True)**0.5
vecs_title = vecs_title / (vecs_title**2).sum(axis=1,
keepdims=True)**0.5
sims = (vecs_query * vecs_title).sum(axis=1)
results.extend(sims)
return results
假设SENT_a和SENT_b是一组相似句,那么在同一个batch中,把[CLS] SENT_a [SEP] SENT_b [SEP]和[CLS] SENT_b [SEP] SENT_a [SEP]都加入训练,做一个相似句的生成任务,这是Seq2Seq部分。
另一方面,把整个batch内的[CLS]向量都拿出来,得到一个句向量矩阵V∈Rb×d(b是batch_size,d是hidden_size),然后对d维度做l2归一化,得到V,然后两两做内积,得到b×b的相似度矩阵VV~?,接着乘以一个scale(我们取了30),并mask掉对角线部分,最后每一行进行softmax,作为一个分类任务训练,每个样本的目标标签是它的相似句(至于自身已经被mask掉)。说白了,就是把batch内所有的非相似样本都当作负样本,借助softmax来增加相似样本的相似度,降低其余样本的相似度。
说到底,关键就是“[CLS]的向量事实上就代表着输入的句向量”,所以可以用它来做一些NLU相关的事情。最后的loss是Seq2Seq和相似句分类两部分loss之和。
用到了样本增强,和统一模型的NLG和NLU
单向MASK 通过乱序得到双向mask seq2seq mask 每一种mask就能得出一致语言模型的结构,GPT>XLNET>UNILM
苏剑林. (May. 18, 2020). 《鱼与熊掌兼得:融合检索和生成的SimBERT模型 》[Blog post]. Retrieved from https://kexue.fm/archives/7427
|