sneedium/captcha_pixelplanet
1
1# pytorch 1.5.02import copy3import math4import warnings5from typing import Optional6 7import torch8import torch.nn as nn9from torch import Tensor10from torch.nn import Dropout, LayerNorm, Linear, Module, ModuleList, Parameter11from torch.nn import functional as F12from torch.nn.init import constant_, xavier_uniform_13 14 15def multi_head_attention_forward(query, # type: Tensor16 key, # type: Tensor17 value, # type: Tensor18 embed_dim_to_check, # type: int19 num_heads, # type: int20 in_proj_weight, # type: Tensor21 in_proj_bias, # type: Tensor22 bias_k, # type: Optional[Tensor]23 bias_v, # type: Optional[Tensor]24 add_zero_attn, # type: bool25 dropout_p, # type: float26 out_proj_weight, # type: Tensor27 out_proj_bias, # type: Tensor28 training=True, # type: bool29 key_padding_mask=None, # type: Optional[Tensor]30 need_weights=True, # type: bool31 attn_mask=None, # type: Optional[Tensor]32 use_separate_proj_weight=False, # type: bool33 q_proj_weight=None, # type: Optional[Tensor]34 k_proj_weight=None, # type: Optional[Tensor]35 v_proj_weight=None, # type: Optional[Tensor]36 static_k=None, # type: Optional[Tensor]37 static_v=None # type: Optional[Tensor]38 ):39 # type: (...) -> Tuple[Tensor, Optional[Tensor]]40 r"""41 Args:42 query, key, value: map a query and a set of key-value pairs to an output.43 See "Attention Is All You Need" for more details.44 embed_dim_to_check: total dimension of the model.45 num_heads: parallel attention heads.46 in_proj_weight, in_proj_bias: input projection weight and bias.47 bias_k, bias_v: bias of the key and value sequences to be added at dim=0.48 add_zero_attn: add a new batch of zeros to the key and49 value sequences at dim=1.50 dropout_p: probability of an element to be zeroed.51 out_proj_weight, out_proj_bias: the output projection weight and bias.52 training: apply dropout if is ``True``.53 key_padding_mask: if provided, specified padding elements in the key will54 be ignored by the attention. This is an binary mask. When the value is True,55 the corresponding value on the attention layer will be filled with -inf.56 need_weights: output attn_output_weights.57 attn_mask: 2D or 3D mask that prevents attention to certain positions. A 2D mask will be broadcasted for all58 the batches while a 3D mask allows to specify a different mask for the entries of each batch.59 use_separate_proj_weight: the function accept the proj. weights for query, key,60 and value in different forms. If false, in_proj_weight will be used, which is61 a combination of q_proj_weight, k_proj_weight, v_proj_weight.62 q_proj_weight, k_proj_weight, v_proj_weight, in_proj_bias: input projection weight and bias.63 static_k, static_v: static key and value used for attention operators.64 Shape:65 Inputs:66 - query: :math:`(L, N, E)` where L is the target sequence length, N is the batch size, E is67 the embedding dimension.68 - key: :math:`(S, N, E)`, where S is the source sequence length, N is the batch size, E is69 the embedding dimension.70 - value: :math:`(S, N, E)` where S is the source sequence length, N is the batch size, E is71 the embedding dimension.72 - key_padding_mask: :math:`(N, S)` where N is the batch size, S is the source sequence length.73 If a ByteTensor is provided, the non-zero positions will be ignored while the zero positions74 will be unchanged. If a BoolTensor is provided, the positions with the75 value of ``True`` will be ignored while the position with the value of ``False`` will be unchanged.76 - attn_mask: 2D mask :math:`(L, S)` where L is the target sequence length, S is the source sequence length.77 3D mask :math:`(N*num_heads, L, S)` where N is the batch size, L is the target sequence length,78 S is the source sequence length. attn_mask ensures that position i is allowed to attend the unmasked79 positions. If a ByteTensor is provided, the non-zero positions are not allowed to attend80 while the zero positions will be unchanged. If a BoolTensor is provided, positions with ``True``81 are not allowed to attend while ``False`` values will be unchanged. If a FloatTensor82 is provided, it will be added to the attention weight.83 - static_k: :math:`(N*num_heads, S, E/num_heads)`, where S is the source sequence length,84 N is the batch size, E is the embedding dimension. E/num_heads is the head dimension.85 - static_v: :math:`(N*num_heads, S, E/num_heads)`, where S is the source sequence length,86 N is the batch size, E is the embedding dimension. E/num_heads is the head dimension.87 Outputs:88 - attn_output: :math:`(L, N, E)` where L is the target sequence length, N is the batch size,89 E is the embedding dimension.90 - attn_output_weights: :math:`(N, L, S)` where N is the batch size,91 L is the target sequence length, S is the source sequence length.92 """93 # if not torch.jit.is_scripting():94 # tens_ops = (query, key, value, in_proj_weight, in_proj_bias, bias_k, bias_v,95 # out_proj_weight, out_proj_bias)96 # if any([type(t) is not Tensor for t in tens_ops]) and has_torch_function(tens_ops):97 # return handle_torch_function(98 # multi_head_attention_forward, tens_ops, query, key, value,99 # embed_dim_to_check, num_heads, in_proj_weight, in_proj_bias,100 # bias_k, bias_v, add_zero_attn, dropout_p, out_proj_weight,101 # out_proj_bias, training=training, key_padding_mask=key_padding_mask,102 # need_weights=need_weights, attn_mask=attn_mask,103 # use_separate_proj_weight=use_separate_proj_weight,104 # q_proj_weight=q_proj_weight, k_proj_weight=k_proj_weight,105 # v_proj_weight=v_proj_weight, static_k=static_k, static_v=static_v)106 tgt_len, bsz, embed_dim = query.size()107 assert embed_dim == embed_dim_to_check108 assert key.size() == value.size()109 110 head_dim = embed_dim // num_heads111 assert head_dim * num_heads == embed_dim, "embed_dim must be divisible by num_heads"112 scaling = float(head_dim) ** -0.5113 114 if not use_separate_proj_weight:115 if torch.equal(query, key) and torch.equal(key, value):116 # self-attention117 q, k, v = F.linear(query, in_proj_weight, in_proj_bias).chunk(3, dim=-1)118 119 elif torch.equal(key, value):120 # encoder-decoder attention121 # This is inline in_proj function with in_proj_weight and in_proj_bias122 _b = in_proj_bias123 _start = 0124 _end = embed_dim125 _w = in_proj_weight[_start:_end, :]126 if _b is not None:127 _b = _b[_start:_end]128 q = F.linear(query, _w, _b)129 130 if key is None:131 assert value is None132 k = None133 v = None134 else:135 136 # This is inline in_proj function with in_proj_weight and in_proj_bias137 _b = in_proj_bias138 _start = embed_dim139 _end = None140 _w = in_proj_weight[_start:, :]141 if _b is not None:142 _b = _b[_start:]143 k, v = F.linear(key, _w, _b).chunk(2, dim=-1)144 145 else:146 # This is inline in_proj function with in_proj_weight and in_proj_bias147 _b = in_proj_bias148 _start = 0149 _end = embed_dim150 _w = in_proj_weight[_start:_end, :]151 if _b is not None:152 _b = _b[_start:_end]153 q = F.linear(query, _w, _b)154 155 # This is inline in_proj function with in_proj_weight and in_proj_bias156 _b = in_proj_bias157 _start = embed_dim158 _end = embed_dim * 2159 _w = in_proj_weight[_start:_end, :]160 if _b is not None:161 _b = _b[_start:_end]162 k = F.linear(key, _w, _b)163 164 # This is inline in_proj function with in_proj_weight and in_proj_bias165 _b = in_proj_bias166 _start = embed_dim * 2167 _end = None168 _w = in_proj_weight[_start:, :]169 if _b is not None:170 _b = _b[_start:]171 v = F.linear(value, _w, _b)172 else:173 q_proj_weight_non_opt = torch.jit._unwrap_optional(q_proj_weight)174 len1, len2 = q_proj_weight_non_opt.size()175 assert len1 == embed_dim and len2 == query.size(-1)176 177 k_proj_weight_non_opt = torch.jit._unwrap_optional(k_proj_weight)178 len1, len2 = k_proj_weight_non_opt.size()179 assert len1 == embed_dim and len2 == key.size(-1)180 181 v_proj_weight_non_opt = torch.jit._unwrap_optional(v_proj_weight)182 len1, len2 = v_proj_weight_non_opt.size()183 assert len1 == embed_dim and len2 == value.size(-1)184 185 if in_proj_bias is not None:186 q = F.linear(query, q_proj_weight_non_opt, in_proj_bias[0:embed_dim])187 k = F.linear(key, k_proj_weight_non_opt, in_proj_bias[embed_dim:(embed_dim * 2)])188 v = F.linear(value, v_proj_weight_non_opt, in_proj_bias[(embed_dim * 2):])189 else:190 q = F.linear(query, q_proj_weight_non_opt, in_proj_bias)191 k = F.linear(key, k_proj_weight_non_opt, in_proj_bias)192 v = F.linear(value, v_proj_weight_non_opt, in_proj_bias)193 q = q * scaling194 195 if attn_mask is not None:196 assert attn_mask.dtype == torch.float32 or attn_mask.dtype == torch.float64 or \197 attn_mask.dtype == torch.float16 or attn_mask.dtype == torch.uint8 or attn_mask.dtype == torch.bool, \198 'Only float, byte, and bool types are supported for attn_mask, not {}'.format(attn_mask.dtype)199 if attn_mask.dtype == torch.uint8:200 warnings.warn("Byte tensor for attn_mask in nn.MultiheadAttention is deprecated. Use bool tensor instead.")201 attn_mask = attn_mask.to(torch.bool)202 203 if attn_mask.dim() == 2:204 attn_mask = attn_mask.unsqueeze(0)205 if list(attn_mask.size()) != [1, query.size(0), key.size(0)]:206 raise RuntimeError('The size of the 2D attn_mask is not correct.')207 elif attn_mask.dim() == 3:208 if list(attn_mask.size()) != [bsz * num_heads, query.size(0), key.size(0)]:209 raise RuntimeError('The size of the 3D attn_mask is not correct.')210 else:211 raise RuntimeError("attn_mask's dimension {} is not supported".format(attn_mask.dim()))212 # attn_mask's dim is 3 now.213 214 # # convert ByteTensor key_padding_mask to bool215 # if key_padding_mask is not None and key_padding_mask.dtype == torch.uint8:216 # warnings.warn("Byte tensor for key_padding_mask in nn.MultiheadAttention is deprecated. Use bool tensor instead.")217 # key_padding_mask = key_padding_mask.to(torch.bool)218 219 if bias_k is not None and bias_v is not None:220 if static_k is None and static_v is None:221 k = torch.cat([k, bias_k.repeat(1, bsz, 1)])222 v = torch.cat([v, bias_v.repeat(1, bsz, 1)])223 if attn_mask is not None:224 attn_mask = pad(attn_mask, (0, 1))225 if key_padding_mask is not None:226 key_padding_mask = pad(key_padding_mask, (0, 1))227 else:228 assert static_k is None, "bias cannot be added to static key."229 assert static_v is None, "bias cannot be added to static value."230 else:231 assert bias_k is None232 assert bias_v is None233 234 q = q.contiguous().view(tgt_len, bsz * num_heads, head_dim).transpose(0, 1)235 if k is not None:236 k = k.contiguous().view(-1, bsz * num_heads, head_dim).transpose(0, 1)237 if v is not None:238 v = v.contiguous().view(-1, bsz * num_heads, head_dim).transpose(0, 1)239 240 if static_k is not None:241 assert static_k.size(0) == bsz * num_heads242 assert static_k.size(2) == head_dim243 k = static_k244 245 if static_v is not None:246 assert static_v.size(0) == bsz * num_heads247 assert static_v.size(2) == head_dim248 v = static_v249 250 src_len = k.size(1)251 252 if key_padding_mask is not None:253 assert key_padding_mask.size(0) == bsz254 assert key_padding_mask.size(1) == src_len255 256 if add_zero_attn:257 src_len += 1258 k = torch.cat([k, torch.zeros((k.size(0), 1) + k.size()[2:], dtype=k.dtype, device=k.device)], dim=1)259 v = torch.cat([v, torch.zeros((v.size(0), 1) + v.size()[2:], dtype=v.dtype, device=v.device)], dim=1)260 if attn_mask is not None:261 attn_mask = pad(attn_mask, (0, 1))262 if key_padding_mask is not None:263 key_padding_mask = pad(key_padding_mask, (0, 1))264 265 attn_output_weights = torch.bmm(q, k.transpose(1, 2))266 assert list(attn_output_weights.size()) == [bsz * num_heads, tgt_len, src_len]267 268 if attn_mask is not None:269 if attn_mask.dtype == torch.bool:270 attn_output_weights.masked_fill_(attn_mask, float('-inf'))271 else:272 attn_output_weights += attn_mask273 274 275 if key_padding_mask is not None:276 attn_output_weights = attn_output_weights.view(bsz, num_heads, tgt_len, src_len)277 attn_output_weights = attn_output_weights.masked_fill(278 key_padding_mask.unsqueeze(1).unsqueeze(2),279 float('-inf'),280 )281 attn_output_weights = attn_output_weights.view(bsz * num_heads, tgt_len, src_len)282 283 attn_output_weights = F.softmax(284 attn_output_weights, dim=-1)285 attn_output_weights = F.dropout(attn_output_weights, p=dropout_p, training=training)286 287 attn_output = torch.bmm(attn_output_weights, v)288 assert list(attn_output.size()) == [bsz * num_heads, tgt_len, head_dim]289 attn_output = attn_output.transpose(0, 1).contiguous().view(tgt_len, bsz, embed_dim)290 attn_output = F.linear(attn_output, out_proj_weight, out_proj_bias)291 292 if need_weights:293 # average attention weights over heads294 attn_output_weights = attn_output_weights.view(bsz, num_heads, tgt_len, src_len)295 return attn_output, attn_output_weights.sum(dim=1) / num_heads296 else:297 return attn_output, None298 299class MultiheadAttention(Module):300 r"""Allows the model to jointly attend to information301 from different representation subspaces.302 See reference: Attention Is All You Need303 .. math::304 \text{MultiHead}(Q, K, V) = \text{Concat}(head_1,\dots,head_h)W^O305 \text{where} head_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V)306 Args:307 embed_dim: total dimension of the model.308 num_heads: parallel attention heads.309 dropout: a Dropout layer on attn_output_weights. Default: 0.0.310 bias: add bias as module parameter. Default: True.311 add_bias_kv: add bias to the key and value sequences at dim=0.312 add_zero_attn: add a new batch of zeros to the key and313 value sequences at dim=1.314 kdim: total number of features in key. Default: None.315 vdim: total number of features in value. Default: None.316 Note: if kdim and vdim are None, they will be set to embed_dim such that317 query, key, and value have the same number of features.318 Examples::319 >>> multihead_attn = nn.MultiheadAttention(embed_dim, num_heads)320 >>> attn_output, attn_output_weights = multihead_attn(query, key, value)321 """322 # __annotations__ = {323 # 'bias_k': torch._jit_internal.Optional[torch.Tensor],324 # 'bias_v': torch._jit_internal.Optional[torch.Tensor],325 # }326 __constants__ = ['q_proj_weight', 'k_proj_weight', 'v_proj_weight', 'in_proj_weight']327 328 def __init__(self, embed_dim, num_heads, dropout=0., bias=True, add_bias_kv=False, add_zero_attn=False, kdim=None, vdim=None):329 super(MultiheadAttention, self).__init__()330 self.embed_dim = embed_dim331 self.kdim = kdim if kdim is not None else embed_dim332 self.vdim = vdim if vdim is not None else embed_dim333 self._qkv_same_embed_dim = self.kdim == embed_dim and self.vdim == embed_dim334 335 self.num_heads = num_heads336 self.dropout = dropout337 self.head_dim = embed_dim // num_heads338 assert self.head_dim * num_heads == self.embed_dim, "embed_dim must be divisible by num_heads"339 340 if self._qkv_same_embed_dim is False:341 self.q_proj_weight = Parameter(torch.Tensor(embed_dim, embed_dim))342 self.k_proj_weight = Parameter(torch.Tensor(embed_dim, self.kdim))343 self.v_proj_weight = Parameter(torch.Tensor(embed_dim, self.vdim))344 self.register_parameter('in_proj_weight', None)345 else:346 self.in_proj_weight = Parameter(torch.empty(3 * embed_dim, embed_dim))347 self.register_parameter('q_proj_weight', None)348 self.register_parameter('k_proj_weight', None)349 self.register_parameter('v_proj_weight', None)350 351 if bias:352 self.in_proj_bias = Parameter(torch.empty(3 * embed_dim))353 else:354 self.register_parameter('in_proj_bias', None)355 self.out_proj = Linear(embed_dim, embed_dim, bias=bias)356 357 if add_bias_kv:358 self.bias_k = Parameter(torch.empty(1, 1, embed_dim))359 self.bias_v = Parameter(torch.empty(1, 1, embed_dim))360 else:361 self.bias_k = self.bias_v = None362 363 self.add_zero_attn = add_zero_attn364 365 self._reset_parameters()366 367 def _reset_parameters(self):368 if self._qkv_same_embed_dim:369 xavier_uniform_(self.in_proj_weight)370 else:371 xavier_uniform_(self.q_proj_weight)372 xavier_uniform_(self.k_proj_weight)373 xavier_uniform_(self.v_proj_weight)374 375 if self.in_proj_bias is not None:376 constant_(self.in_proj_bias, 0.)377 constant_(self.out_proj.bias, 0.)378 if self.bias_k is not None:379 xavier_normal_(self.bias_k)380 if self.bias_v is not None:381 xavier_normal_(self.bias_v)382 383 def __setstate__(self, state):384 # Support loading old MultiheadAttention checkpoints generated by v1.1.0385 if '_qkv_same_embed_dim' not in state:386 state['_qkv_same_embed_dim'] = True387 388 super(MultiheadAttention, self).__setstate__(state)389 390 def forward(self, query, key, value, key_padding_mask=None,391 need_weights=True, attn_mask=None):392 # type: (Tensor, Tensor, Tensor, Optional[Tensor], bool, Optional[Tensor]) -> Tuple[Tensor, Optional[Tensor]]393 r"""394 Args:395 query, key, value: map a query and a set of key-value pairs to an output.396 See "Attention Is All You Need" for more details.397 key_padding_mask: if provided, specified padding elements in the key will398 be ignored by the attention. This is an binary mask. When the value is True,399 the corresponding value on the attention layer will be filled with -inf.400 need_weights: output attn_output_weights.401 attn_mask: 2D or 3D mask that prevents attention to certain positions. A 2D mask will be broadcasted for all402 the batches while a 3D mask allows to specify a different mask for the entries of each batch.403 Shape:404 - Inputs:405 - query: :math:`(L, N, E)` where L is the target sequence length, N is the batch size, E is406 the embedding dimension.407 - key: :math:`(S, N, E)`, where S is the source sequence length, N is the batch size, E is408 the embedding dimension.409 - value: :math:`(S, N, E)` where S is the source sequence length, N is the batch size, E is410 the embedding dimension.411 - key_padding_mask: :math:`(N, S)` where N is the batch size, S is the source sequence length.412 If a ByteTensor is provided, the non-zero positions will be ignored while the position413 with the zero positions will be unchanged. If a BoolTensor is provided, the positions with the414 value of ``True`` will be ignored while the position with the value of ``False`` will be unchanged.415 - attn_mask: 2D mask :math:`(L, S)` where L is the target sequence length, S is the source sequence length.416 3D mask :math:`(N*num_heads, L, S)` where N is the batch size, L is the target sequence length,417 S is the source sequence length. attn_mask ensure that position i is allowed to attend the unmasked418 positions. If a ByteTensor is provided, the non-zero positions are not allowed to attend419 while the zero positions will be unchanged. If a BoolTensor is provided, positions with ``True``420 is not allowed to attend while ``False`` values will be unchanged. If a FloatTensor421 is provided, it will be added to the attention weight.422 - Outputs:423 - attn_output: :math:`(L, N, E)` where L is the target sequence length, N is the batch size,424 E is the embedding dimension.425 - attn_output_weights: :math:`(N, L, S)` where N is the batch size,426 L is the target sequence length, S is the source sequence length.427 """428 if not self._qkv_same_embed_dim:429 return multi_head_attention_forward(430 query, key, value, self.embed_dim, self.num_heads,431 self.in_proj_weight, self.in_proj_bias,432 self.bias_k, self.bias_v, self.add_zero_attn,433 self.dropout, self.out_proj.weight, self.out_proj.bias,434 training=self.training,435 key_padding_mask=key_padding_mask, need_weights=need_weights,436 attn_mask=attn_mask, use_separate_proj_weight=True,437 q_proj_weight=self.q_proj_weight, k_proj_weight=self.k_proj_weight,438 v_proj_weight=self.v_proj_weight)439 else:440 return multi_head_attention_forward(441 query, key, value, self.embed_dim, self.num_heads,442 self.in_proj_weight, self.in_proj_bias,443 self.bias_k, self.bias_v, self.add_zero_attn,444 self.dropout, self.out_proj.weight, self.out_proj.bias,445 training=self.training,446 key_padding_mask=key_padding_mask, need_weights=need_weights,447 attn_mask=attn_mask)448 449 450class Transformer(Module):451 r"""A transformer model. User is able to modify the attributes as needed. The architecture452 is based on the paper "Attention Is All You Need". Ashish Vaswani, Noam Shazeer,453 Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N Gomez, Lukasz Kaiser, and454 Illia Polosukhin. 2017. Attention is all you need. In Advances in Neural Information455 Processing Systems, pages 6000-6010. Users can build the BERT(https://arxiv.org/abs/1810.04805)456 model with corresponding parameters.457 458 Args:459 d_model: the number of expected features in the encoder/decoder inputs (default=512).460 nhead: the number of heads in the multiheadattention models (default=8).461 num_encoder_layers: the number of sub-encoder-layers in the encoder (default=6).462 num_decoder_layers: the number of sub-decoder-layers in the decoder (default=6).463 dim_feedforward: the dimension of the feedforward network model (default=2048).464 dropout: the dropout value (default=0.1).465 activation: the activation function of encoder/decoder intermediate layer, relu or gelu (default=relu).466 custom_encoder: custom encoder (default=None).467 custom_decoder: custom decoder (default=None).468 469 Examples::470 >>> transformer_model = nn.Transformer(nhead=16, num_encoder_layers=12)471 >>> src = torch.rand((10, 32, 512))472 >>> tgt = torch.rand((20, 32, 512))473 >>> out = transformer_model(src, tgt)474 475 Note: A full example to apply nn.Transformer module for the word language model is available in476 https://github.com/pytorch/examples/tree/master/word_language_model477 """478 479 def __init__(self, d_model=512, nhead=8, num_encoder_layers=6,480 num_decoder_layers=6, dim_feedforward=2048, dropout=0.1,481 activation="relu", custom_encoder=None, custom_decoder=None):482 super(Transformer, self).__init__()483 484 if custom_encoder is not None:485 self.encoder = custom_encoder486 else:487 encoder_layer = TransformerEncoderLayer(d_model, nhead, dim_feedforward, dropout, activation)488 encoder_norm = LayerNorm(d_model)489 self.encoder = TransformerEncoder(encoder_layer, num_encoder_layers, encoder_norm)490 491 if custom_decoder is not None:492 self.decoder = custom_decoder493 else:494 decoder_layer = TransformerDecoderLayer(d_model, nhead, dim_feedforward, dropout, activation)495 decoder_norm = LayerNorm(d_model)496 self.decoder = TransformerDecoder(decoder_layer, num_decoder_layers, decoder_norm)497 498 self._reset_parameters()499 500 self.d_model = d_model501 self.nhead = nhead502 503 def forward(self, src, tgt, src_mask=None, tgt_mask=None,504 memory_mask=None, src_key_padding_mask=None,505 tgt_key_padding_mask=None, memory_key_padding_mask=None):506 # type: (Tensor, Tensor, Optional[Tensor], Optional[Tensor], Optional[Tensor], Optional[Tensor], Optional[Tensor], Optional[Tensor]) -> Tensor # noqa507 r"""Take in and process masked source/target sequences.508 509 Args:510 src: the sequence to the encoder (required).511 tgt: the sequence to the decoder (required).512 src_mask: the additive mask for the src sequence (optional).513 tgt_mask: the additive mask for the tgt sequence (optional).514 memory_mask: the additive mask for the encoder output (optional).515 src_key_padding_mask: the ByteTensor mask for src keys per batch (optional).516 tgt_key_padding_mask: the ByteTensor mask for tgt keys per batch (optional).517 memory_key_padding_mask: the ByteTensor mask for memory keys per batch (optional).518 519 Shape:520 - src: :math:`(S, N, E)`.521 - tgt: :math:`(T, N, E)`.522 - src_mask: :math:`(S, S)`.523 - tgt_mask: :math:`(T, T)`.524 - memory_mask: :math:`(T, S)`.525 - src_key_padding_mask: :math:`(N, S)`.526 - tgt_key_padding_mask: :math:`(N, T)`.527 - memory_key_padding_mask: :math:`(N, S)`.528 529 Note: [src/tgt/memory]_mask ensures that position i is allowed to attend the unmasked530 positions. If a ByteTensor is provided, the non-zero positions are not allowed to attend531 while the zero positions will be unchanged. If a BoolTensor is provided, positions with ``True``532 are not allowed to attend while ``False`` values will be unchanged. If a FloatTensor533 is provided, it will be added to the attention weight. 534 [src/tgt/memory]_key_padding_mask provides specified elements in the key to be ignored by535 the attention. If a ByteTensor is provided, the non-zero positions will be ignored while the zero536 positions will be unchanged. If a BoolTensor is provided, the positions with the537 value of ``True`` will be ignored while the position with the value of ``False`` will be unchanged.538 539 - output: :math:`(T, N, E)`.540 541 Note: Due to the multi-head attention architecture in the transformer model,542 the output sequence length of a transformer is same as the input sequence543 (i.e. target) length of the decode.544 545 where S is the source sequence length, T is the target sequence length, N is the546 batch size, E is the feature number547 548 Examples:549 >>> output = transformer_model(src, tgt, src_mask=src_mask, tgt_mask=tgt_mask)550 """551 552 if src.size(1) != tgt.size(1):553 raise RuntimeError("the batch number of src and tgt must be equal")554 555 if src.size(2) != self.d_model or tgt.size(2) != self.d_model:556 raise RuntimeError("the feature number of src and tgt must be equal to d_model")557 558 memory = self.encoder(src, mask=src_mask, src_key_padding_mask=src_key_padding_mask)559 output = self.decoder(tgt, memory, tgt_mask=tgt_mask, memory_mask=memory_mask,560 tgt_key_padding_mask=tgt_key_padding_mask,561 memory_key_padding_mask=memory_key_padding_mask)562 return output563 564 def generate_square_subsequent_mask(self, sz):565 r"""Generate a square mask for the sequence. The masked positions are filled with float('-inf').566 Unmasked positions are filled with float(0.0).567 """568 mask = (torch.triu(torch.ones(sz, sz)) == 1).transpose(0, 1)569 mask = mask.float().masked_fill(mask == 0, float('-inf')).masked_fill(mask == 1, float(0.0))570 return mask571 572 def _reset_parameters(self):573 r"""Initiate parameters in the transformer model."""574 575 for p in self.parameters():576 if p.dim() > 1:577 xavier_uniform_(p)578 579 580class TransformerEncoder(Module):581 r"""TransformerEncoder is a stack of N encoder layers582 583 Args:584 encoder_layer: an instance of the TransformerEncoderLayer() class (required).585 num_layers: the number of sub-encoder-layers in the encoder (required).586 norm: the layer normalization component (optional).587 588 Examples::589 >>> encoder_layer = nn.TransformerEncoderLayer(d_model=512, nhead=8)590 >>> transformer_encoder = nn.TransformerEncoder(encoder_layer, num_layers=6)591 >>> src = torch.rand(10, 32, 512)592 >>> out = transformer_encoder(src)593 """594 __constants__ = ['norm']595 596 def __init__(self, encoder_layer, num_layers, norm=None):597 super(TransformerEncoder, self).__init__()598 self.layers = _get_clones(encoder_layer, num_layers)599 self.num_layers = num_layers600 self.norm = norm601 602 def forward(self, src, mask=None, src_key_padding_mask=None):603 # type: (Tensor, Optional[Tensor], Optional[Tensor]) -> Tensor604 r"""Pass the input through the encoder layers in turn.605 606 Args:607 src: the sequence to the encoder (required).608 mask: the mask for the src sequence (optional).609 src_key_padding_mask: the mask for the src keys per batch (optional).610 611 Shape:612 see the docs in Transformer class.613 """614 output = src615 616 for i, mod in enumerate(self.layers):617 output = mod(output, src_mask=mask, src_key_padding_mask=src_key_padding_mask)618 619 if self.norm is not None:620 output = self.norm(output)621 622 return output623 624 625class TransformerDecoder(Module):626 r"""TransformerDecoder is a stack of N decoder layers627 628 Args:629 decoder_layer: an instance of the TransformerDecoderLayer() class (required).630 num_layers: the number of sub-decoder-layers in the decoder (required).631 norm: the layer normalization component (optional).632 633 Examples::634 >>> decoder_layer = nn.TransformerDecoderLayer(d_model=512, nhead=8)635 >>> transformer_decoder = nn.TransformerDecoder(decoder_layer, num_layers=6)636 >>> memory = torch.rand(10, 32, 512)637 >>> tgt = torch.rand(20, 32, 512)638 >>> out = transformer_decoder(tgt, memory)639 """640 __constants__ = ['norm']641 642 def __init__(self, decoder_layer, num_layers, norm=None):643 super(TransformerDecoder, self).__init__()644 self.layers = _get_clones(decoder_layer, num_layers)645 self.num_layers = num_layers646 self.norm = norm647 648 def forward(self, tgt, memory, memory2=None, tgt_mask=None,649 memory_mask=None, memory_mask2=None, tgt_key_padding_mask=None,650 memory_key_padding_mask=None, memory_key_padding_mask2=None):651 # type: (Tensor, Tensor, Optional[Tensor], Optional[Tensor], Optional[Tensor], Optional[Tensor]) -> Tensor652 r"""Pass the inputs (and mask) through the decoder layer in turn.653 654 Args:655 tgt: the sequence to the decoder (required).656 memory: the sequence from the last layer of the encoder (required).657 tgt_mask: the mask for the tgt sequence (optional).658 memory_mask: the mask for the memory sequence (optional).659 tgt_key_padding_mask: the mask for the tgt keys per batch (optional).660 memory_key_padding_mask: the mask for the memory keys per batch (optional).661 662 Shape:663 see the docs in Transformer class.664 """665 output = tgt666 667 for mod in self.layers:668 output = mod(output, memory, memory2=memory2, tgt_mask=tgt_mask,669 memory_mask=memory_mask, memory_mask2=memory_mask2,670 tgt_key_padding_mask=tgt_key_padding_mask,671 memory_key_padding_mask=memory_key_padding_mask,672 memory_key_padding_mask2=memory_key_padding_mask2)673 674 if self.norm is not None:675 output = self.norm(output)676 677 return output678 679class TransformerEncoderLayer(Module):680 r"""TransformerEncoderLayer is made up of self-attn and feedforward network.681 This standard encoder layer is based on the paper "Attention Is All You Need".682 Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N Gomez,683 Lukasz Kaiser, and Illia Polosukhin. 2017. Attention is all you need. In Advances in684 Neural Information Processing Systems, pages 6000-6010. Users may modify or implement685 in a different way during application.686 687 Args:688 d_model: the number of expected features in the input (required).689 nhead: the number of heads in the multiheadattention models (required).690 dim_feedforward: the dimension of the feedforward network model (default=2048).691 dropout: the dropout value (default=0.1).692 activation: the activation function of intermediate layer, relu or gelu (default=relu).693 694 Examples::695 >>> encoder_layer = nn.TransformerEncoderLayer(d_model=512, nhead=8)696 >>> src = torch.rand(10, 32, 512)697 >>> out = encoder_layer(src)698 """699 700 def __init__(self, d_model, nhead, dim_feedforward=2048, dropout=0.1, 701 activation="relu", debug=False):702 super(TransformerEncoderLayer, self).__init__()703 self.debug = debug704 self.self_attn = MultiheadAttention(d_model, nhead, dropout=dropout)705 # Implementation of Feedforward model706 self.linear1 = Linear(d_model, dim_feedforward)707 self.dropout = Dropout(dropout)708 self.linear2 = Linear(dim_feedforward, d_model)709 710 self.norm1 = LayerNorm(d_model)711 self.norm2 = LayerNorm(d_model)712 self.dropout1 = Dropout(dropout)713 self.dropout2 = Dropout(dropout)714 715 self.activation = _get_activation_fn(activation)716 717 def __setstate__(self, state):718 if 'activation' not in state:719 state['activation'] = F.relu720 super(TransformerEncoderLayer, self).__setstate__(state)721 722 def forward(self, src, src_mask=None, src_key_padding_mask=None):723 # type: (Tensor, Optional[Tensor], Optional[Tensor]) -> Tensor724 r"""Pass the input through the encoder layer.725 726 Args:727 src: the sequence to the encoder layer (required).728 src_mask: the mask for the src sequence (optional).729 src_key_padding_mask: the mask for the src keys per batch (optional).730 731 Shape:732 see the docs in Transformer class.733 """734 src2, attn = self.self_attn(src, src, src, attn_mask=src_mask,735 key_padding_mask=src_key_padding_mask)736 if self.debug: self.attn = attn737 src = src + self.dropout1(src2)738 src = self.norm1(src)739 src2 = self.linear2(self.dropout(self.activation(self.linear1(src))))740 src = src + self.dropout2(src2)741 src = self.norm2(src)742 743 return src744 745 746class TransformerDecoderLayer(Module):747 r"""TransformerDecoderLayer is made up of self-attn, multi-head-attn and feedforward network.748 This standard decoder layer is based on the paper "Attention Is All You Need".749 Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N Gomez,750 Lukasz Kaiser, and Illia Polosukhin. 2017. Attention is all you need. In Advances in751 Neural Information Processing Systems, pages 6000-6010. Users may modify or implement752 in a different way during application.753 754 Args:755 d_model: the number of expected features in the input (required).756 nhead: the number of heads in the multiheadattention models (required).757 dim_feedforward: the dimension of the feedforward network model (default=2048).758 dropout: the dropout value (default=0.1).759 activation: the activation function of intermediate layer, relu or gelu (default=relu).760 761 Examples::762 >>> decoder_layer = nn.TransformerDecoderLayer(d_model=512, nhead=8)763 >>> memory = torch.rand(10, 32, 512)764 >>> tgt = torch.rand(20, 32, 512)765 >>> out = decoder_layer(tgt, memory)766 """767 768 def __init__(self, d_model, nhead, dim_feedforward=2048, dropout=0.1, 769 activation="relu", self_attn=True, siamese=False, debug=False):770 super(TransformerDecoderLayer, self).__init__()771 self.has_self_attn, self.siamese = self_attn, siamese772 self.debug = debug773 if self.has_self_attn:774 self.self_attn = MultiheadAttention(d_model, nhead, dropout=dropout)775 self.norm1 = LayerNorm(d_model)776 self.dropout1 = Dropout(dropout)777 self.multihead_attn = MultiheadAttention(d_model, nhead, dropout=dropout)778 # Implementation of Feedforward model779 self.linear1 = Linear(d_model, dim_feedforward)780 self.dropout = Dropout(dropout)781 self.linear2 = Linear(dim_feedforward, d_model)782 783 self.norm2 = LayerNorm(d_model)784 self.norm3 = LayerNorm(d_model)785 self.dropout2 = Dropout(dropout)786 self.dropout3 = Dropout(dropout)787 if self.siamese:788 self.multihead_attn2 = MultiheadAttention(d_model, nhead, dropout=dropout)789 790 self.activation = _get_activation_fn(activation)791 792 def __setstate__(self, state):793 if 'activation' not in state:794 state['activation'] = F.relu795 super(TransformerDecoderLayer, self).__setstate__(state)796 797 def forward(self, tgt, memory, tgt_mask=None, memory_mask=None,798 tgt_key_padding_mask=None, memory_key_padding_mask=None,799 memory2=None, memory_mask2=None, memory_key_padding_mask2=None):800 # type: (Tensor, Tensor, Optional[Tensor], Optional[Tensor], Optional[Tensor], Optional[Tensor]) -> Tensor801 r"""Pass the inputs (and mask) through the decoder layer.802 803 Args:804 tgt: the sequence to the decoder layer (required).805 memory: the sequence from the last layer of the encoder (required).806 tgt_mask: the mask for the tgt sequence (optional).807 memory_mask: the mask for the memory sequence (optional).808 tgt_key_padding_mask: the mask for the tgt keys per batch (optional).809 memory_key_padding_mask: the mask for the memory keys per batch (optional).810 811 Shape:812 see the docs in Transformer class.813 """814 if self.has_self_attn:815 tgt2, attn = self.self_attn(tgt, tgt, tgt, attn_mask=tgt_mask,816 key_padding_mask=tgt_key_padding_mask)817 tgt = tgt + self.dropout1(tgt2)818 tgt = self.norm1(tgt)819 if self.debug: self.attn = attn820 tgt2, attn2 = self.multihead_attn(tgt, memory, memory, attn_mask=memory_mask,821 key_padding_mask=memory_key_padding_mask)822 if self.debug: self.attn2 = attn2823 824 if self.siamese:825 tgt3, attn3 = self.multihead_attn2(tgt, memory2, memory2, attn_mask=memory_mask2,826 key_padding_mask=memory_key_padding_mask2)827 tgt = tgt + self.dropout2(tgt3)828 if self.debug: self.attn3 = attn3829 830 tgt = tgt + self.dropout2(tgt2)831 tgt = self.norm2(tgt)832 tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt))))833 tgt = tgt + self.dropout3(tgt2)834 tgt = self.norm3(tgt)835 836 return tgt837 838 839def _get_clones(module, N):840 return ModuleList([copy.deepcopy(module) for i in range(N)])841 842 843def _get_activation_fn(activation):844 if activation == "relu":845 return F.relu846 elif activation == "gelu":847 return F.gelu848 849 raise RuntimeError("activation should be relu/gelu, not {}".format(activation))850 851 852class PositionalEncoding(nn.Module):853 r"""Inject some information about the relative or absolute position of the tokens854 in the sequence. The positional encodings have the same dimension as855 the embeddings, so that the two can be summed. Here, we use sine and cosine856 functions of different frequencies.857 .. math::858 \text{PosEncoder}(pos, 2i) = sin(pos/10000^(2i/d_model))859 \text{PosEncoder}(pos, 2i+1) = cos(pos/10000^(2i/d_model))860 \text{where pos is the word position and i is the embed idx)861 Args:862 d_model: the embed dim (required).863 dropout: the dropout value (default=0.1).864 max_len: the max. length of the incoming sequence (default=5000).865 Examples:866 >>> pos_encoder = PositionalEncoding(d_model)867 """868 869 def __init__(self, d_model, dropout=0.1, max_len=5000):870 super(PositionalEncoding, self).__init__()871 self.dropout = nn.Dropout(p=dropout)872 873 pe = torch.zeros(max_len, d_model)874 position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)875 div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))876 pe[:, 0::2] = torch.sin(position * div_term)877 pe[:, 1::2] = torch.cos(position * div_term)878 pe = pe.unsqueeze(0).transpose(0, 1)879 self.register_buffer('pe', pe)880 881 def forward(self, x):882 r"""Inputs of forward function883 Args:884 x: the sequence fed to the positional encoder model (required).885 Shape:886 x: [sequence length, batch size, embed dim]887 output: [sequence length, batch size, embed dim]888 Examples:889 >>> output = pos_encoder(x)890 """891 892 x = x + self.pe[:x.size(0), :]893 return self.dropout(x)894 895 896if __name__ == '__main__':897 transformer_model = Transformer(nhead=16, num_encoder_layers=12)898 src = torch.rand((10, 32, 512))899 tgt = torch.rand((20, 32, 512))900 out = transformer_model(src, tgt)901 print(out)902 