PyTorch给句子加所谓的mask

1. 什么叫mask?

我们在自然语言处理中,听到给一个句子加mask,意义是:
我们如果有3个句子:

今天天气真的好
我讨厌阳光强烈的天气
雨天真美

ok,这三个句子的句子长度分别是(按字算,当然你也可以分词处理):7,10,4。
我们假设从词表中获取每个字对应的数字后,句子变成:

12 13 14 15 16 18 20
23 24 25 26 27 28 29 18 13 14
30 13 16 45

但是我们的模型一般无法处理变长序列,因此需要统一长度。那么一般采用补的方法,即所有句子长度统一为所有句子中长度最长的句子长度,即10。
处理后的长度为:

12 13 14 15 16 18 20 0 0 0
23 24 25 26 27 28 29 18 13 14
30 13 16 45 0 0 0 0 0 0

我们发现其中0所代表的位置,其实并没有字,只是一个补充,此时我们需要一个mask(遮罩),来表示一下哪些位置有词,哪些位置没有词,遮罩的样子应该是:

1 1 1 1 1 1 1 0 0 0
1 1 1 1 1 1 1 1 1 1
1 1 1 1 0 0 0 0 0 0

ok,现在你知道什么是mask了,那么怎么构建一个mask呢?

2. 以Pytorch为例写个mask

sentence_lengths = torch.Tensor([7, 10, 4]) # 代表每个句子的长度
mask = torch.arange(sentence_lengths.max().item())[None, :] < sentence_lengths[:, None]


"""输出
tensor([[ True,  True,  True,  True,  True,  True,  True, False, False, False],
        [ True,  True,  True,  True,  True,  True,  True,  True,  True,  True],
        [ True,  True,  True,  True, False, False, False, False, False, False]])
"""
# 我们发现里面是Boolean值,需要将其转化成 0, 1值 只需要
mask = mask.float()
mask
"""输出
tensor([[1., 1., 1., 1., 1., 1., 1., 0., 0., 0.],
        [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 0., 0., 0., 0., 0., 0.]])
"""

3. 代码详解!!!

这段代码中max() 是取tensor中的最大值,返回值仍然是Tensor格式,需要用item()将其“值”取出来,返回一个float。
然后torch.arange(10)生成一个0到9的Tensor,即:tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])。
然后通过[None,:]给其在“外层”添加一个维度,变成:tensor([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])。
倘若是在内层添加一个维度,torch.arange(10)[:, None],则变成:

tensor([
[0],
[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]])

其实sentence_lengths就是执行的[:, None],相当于变成列向量:

Tensor([
[7],
[10],
[4]])

然后是大小比较,是tensor([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])先复制3行,然后第一行中的每个元素去和[7]比较,第二行和[10]比较,第三行和[4]比较,
以第一行为例:如果小于7,则成立,返回True,即1;否则返回False,即0。
最后形成3*10的mask矩阵。

给 👴 懂!

希望没有为代码挣扎的孩子。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值