nn.TransformerEncoder的输出为NaN值的原因及解决方法

问题描述:

当使用nn.TransformerEncoder时,即如下情况:

实例化一个TransformerEncoder 
 self.encoder_layer = nn.TransformerEncoderLayer(d_model=encoder_in_dim, nhead=encoder_head,
                                                           dim_feedforward=encoder_ffnn_dim,
                                                           batch_first=batch_first)
 self.model = nn.TransformerEncoder(self.pre_encoder_layer, num_layers=pre_encoder_layer_num)
调用:
transformer_features =  self.model(embeddings, src_key_padding_mask=src_padding_mask)

transformer_features的值为NaN
原因在于src_padding_mask的传入出现均为0/False的情况!即attention—mask出现了全1/True行
由于我们在使用MultiheadAttention做self-attention时因为batch内序列长度不一致,难免需要使用mask
以pytorch自带的torch.nn.TransformerEncoder方法为例,其forward函数如下

forward(src, mask=None, src_key_padding_mask=None)

这里的mask会送到torch.nn.TransformerEncoderLayer的forward函数:

def forward(self, src: Tensor, src_mask: Optional[Tensor] = None, src_key_padding_mask: Optional[Tensor] = None) -> Tensor:
        src2 = self.self_attn(src, src, src, attn_mask=src_mask,key_padding_mask=src_key_padding_mask)[0]

之后送到MultiheadAttention的forward函数的attn_mask参数,而这里做的是一个self attention。
此时若是attn_mask出现一整行都是True的情况,通过如下源码中的实现mask的方法可以看到:

    if attn_mask is not None:
        if attn_mask.dtype == torch.bool:
            attn_output_weights.masked_fill_(attn_mask, float('-inf'))
        else:
            attn_output_weights += attn_mask

把权重矩阵中需要mask的位置置为负无穷,然后再按行做softmax,问题就在这里,把一个元素全是是负无穷的tensor送给softmax,就会得到一个全是NaN的tensor。然后NaN和任何数运算都是NaN,NaN会传染,再经过一轮self attention,输出的tensor就全成NaN了。

解决方法:避免attention mask中存在全1/True的行

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值