NLP中mask矩阵

mask矩阵是什么?是一个由0和1组成的矩阵。一个例子是,在自然语言处理(NLP)中,句子的长度是不等长的,但因为我们经常将句子组成mini-batch用以训练,因此那些长度较短的句子都会在句尾进行填充0,也即padding的操作。一个mask矩阵即用以指示哪些是真正的数据,哪些是padding。如:

图片来源:Theano:LSTM源码解析

其中mask矩阵中1代表真实数据;0代表padding数据。

为什么

为什么要使用mask矩阵?使用mask矩阵是为了让那些被mask掉的tensor不会被更新。考虑一个tensor T的size(a,b),同样大小的mask矩阵M,相乘后,在反向回传的时候在T对应mask为0的地方,0的梯度仍为0。因此不会被更新。

怎么做

接下来介绍几种(可能不全)使用mask的场景。

对输入进行mask

考虑NLP中常见的句子不等长的情况。设我们的输入的batch I:(batch_size,max_seqlen),我们在过一层Embedding层之前,
在过了一层Embedding层,则有 E:(batch_size,max_seqlen,embed_dim),如果我们希望Embedding是更新的(比如我们的Embedding是随机初始化的,那当然Embedding需要更新),但我们又不希望padding更新。
一种方法即令E与M相乘。其中M是mask矩阵(batch_size,max_seqlen,1) (1是因为要broadcast),这样在Embedding更新梯度时,因为mask矩阵的关系,padding位置上的梯度就是0。
当然在Pytorch中还可以直接显式地写:

1
self.embedding = nn.Embedding(vocab_size, embed_dim,padding_idx=0)

 

而此时应当将padding显式添加到词典的第一个。

对模型中间进行mask

一个很经典的场景就是dropout。
对于参数矩阵W:(h,w),同样大小的mask矩阵M,在前向传播时令W’=W*M,则在反向传播时,M中为0的部分不被更新。
当然,我们可以直接调用PyTorch中的包nn.Dropout()

1
2
3
m = nn.Dropout(p=0.2)
input = torch.randn(20, 16)
output = m(input)

对loss进行mask

考虑NLP中的language model,每个词都需要预测下一个词,在一个batch中句子总是有长有短,对于一个短句,此时在计算loss的时候,会出现这样的场景:<pad>词要预测下一个<pad>词。举个例子:三个句子[a,b,c,d],[e,f,g],[h,i],在组成batch后,会变成
X:

    
abcd
efg<pad>
hi<pad><pad>

Y:

    
bcd<pad>
fg<eos><pad>
i<eos><pad><pad>

X是输入,Y是预测。那么从第三行可以看出,<pad>在预测下一个<pad>。这显然是有问题的。
一种解决方案就是使用mask矩阵,在loss的计算时,将那些本不应该计算的mask掉,使得其loss为0,这样就不会反向回传了。
具体实践:在PyTorch中,以CrossEntropy为例:

1
2
class torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, 
reduce=None, reduction=’elementwise_mean’

如果reduction=None则会返回一个与输入同样大小的矩阵。在与mask矩阵相乘后,再对新矩阵进行mean操作。
在PyTorch实践上还可以可以这么写:

1
2
3
masked_outputs = torch.masked_select(dec_outputs, mask)
masked_targets = torch.masked_select(targets, mask)
loss = my_criterion(masked_outputs, masked_targets)

另一种更为简单的解决方案是,直接在CrossEntropy中设ignore_index=0,这样,在计算loss的时候,发现target=0时,会自动不对其进行loss的计算。其本质和mask矩阵是一致的。

总结

mask矩阵可以用在任何地方,只要希望与之相乘的tensor相对应的地方不更新就可以进行mask操作。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值