class_docstr: Args:
      out_channels (int): Output class number.
      enc_bi_rnn (bool): If True, use bidirectional RNN in encoder.
      dec_bi_rnn (bool): If True, use bidirectional RNN in decoder.
      dec_drop_rnn (float): Dropout of RNN layer in decoder.
      dec_gru (bool): If True, use GRU, else LSTM in decoder.
      d_model (int): Dim of channels from backbone.
      d_enc (int): Dim of encoder RNN layer.
      d_k (int): Dim of channels of attention module.
      pred_dropout (float): Dropout probability of prediction layer.
      max_seq_len (int): Maximum sequence length for decoding.
      mask (bool): If True, mask padding in feature map.
      start_idx (int): Index of start token.
      padding_idx (int): Index of padding token.
      pred_concat (bool): If True, concat glimpse feature from
          attention with holistic feature and hidden state.
class_docstr_tok: ["Args",":","out_channels","(","int",")",":","Output","class","number",".","enc_bi_rnn","(","bool",")",":","If","True",",","use","bidirectional","RNN","in","encoder",".","dec_bi_rnn","(","bool",")",":","If","True",",","use","bidirectional","RNN","in","decoder",".","dec_drop_rnn","(","float",")",":","Dropout","of","RNN","layer","in","decoder",".","dec_gru","(","bool",")",":","If","True",",","use","GRU",",","else","LSTM","in","decoder",".","d_model","(","int",")",":","Dim","of","channels","from","backbone",".","d_enc","(","int",")",":","Dim","of","encoder","RNN","layer",".","d_k","(","int",")",":","Dim","of","channels","of","attention","module",".","pred_dropout","(","float",")",":","Dropout","probability","of","prediction","layer",".","max_seq_len","(","int",")",":","Maximum","sequence","length","for","decoding",".","mask","(","bool",")",":","If","True",",","mask","padding","in","feature","map",".","start_idx","(","int",")",":","Index","of","start","token",".","padding_idx","(","int",")",":","Index","of","padding","token",".","pred_concat","(","bool",")",":","If","True",",","concat","glimpse","feature","from","attention","with","holistic","feature","and","hidden","state","."]
code: def _2d_attention(
      self, decoder_input, feat, holistic_feat, valid_ratios=None
  ):
      y = self.rnn_decoder(decoder_input)[0]
      # y: bsz * (seq_len + 1) * hidden_size
  
      attn_query = self.conv1x1_1(y)  # bsz * (seq_len + 1) * attn_size
      bsz, seq_len, attn_size = attn_query.shape
      attn_query = paddle.unsqueeze(attn_query, axis=[3, 4])
      # (bsz, seq_len + 1, attn_size, 1, 1)
  
      attn_key = self.conv3x3_1(feat)
      # bsz * attn_size * h * w
      attn_key = attn_key.unsqueeze(1)
      # bsz * 1 * attn_size * h * w
  
      attn_weight = paddle.tanh(paddle.add(attn_key, attn_query))
  
      # bsz * (seq_len + 1) * attn_size * h * w
      attn_weight = paddle.transpose(attn_weight, perm=[0, 1, 3, 4, 2])
      # bsz * (seq_len + 1) * h * w * attn_size
      attn_weight = self.conv1x1_2(attn_weight)
      # bsz * (seq_len + 1) * h * w * 1
      bsz, T, h, w, c = paddle.shape(attn_weight)
      assert c == 1
  
      if valid_ratios is not None:
          # cal mask of attention weight
          for i in range(paddle.shape(valid_ratios)[0]):
              valid_width = paddle.minimum(
                  w, paddle.ceil(valid_ratios[i] * w).astype("int32")
              )
              if valid_width < w:
                  attn_weight[i, :, :, valid_width:, :] = float("-inf")
  
      attn_weight = paddle.reshape(attn_weight, [bsz, T, -1])
      attn_weight = F.softmax(attn_weight, axis=-1)
  
      attn_weight = paddle.reshape(attn_weight, [bsz, T, h, w, c])
      attn_weight = paddle.transpose(attn_weight, perm=[0, 1, 4, 2, 3])
      # attn_weight: bsz * T * c * h * w
      # feat: bsz * c * h * w
      attn_feat = paddle.sum(
          paddle.multiply(feat.unsqueeze(1), attn_weight),
          (3, 4),
          keepdim=False,
      )
      # bsz * (seq_len + 1) * C
  
      # Linear transformation
      if self.pred_concat:
          hf_c = holistic_feat.shape[-1]
          holistic_feat = paddle.expand(
              holistic_feat, shape=[bsz, seq_len, hf_c]
          )
          y = self.prediction(
              paddle.concat(
                  (
                      y,
                      attn_feat.astype(y.dtype),
                      holistic_feat.astype(y.dtype),
                  ),
                  2,
              )
          )
      else:
          y = self.prediction(attn_feat)
      # bsz * (seq_len + 1) * num_classes
      if self.train_mode:
          y = self.pred_dropout(y)
  
      return y
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import math
  import paddle
  from paddle import ParamAttr
  import paddle.nn
  import paddle.nn.functional
label_desc: Use image node_id 2 for calling the ParallelSARDecoder obj's underlying member method code with example usage: obj._2d_attention(decoder_input, feat, holistic_feat, valid_ratios) and returns: y