code: def _read_by_weight(self, F, att_weights, value):
          
          output = F.batch_dot(att_weights, value)
          return output
docs: Read from the value matrix given the attention weights.
  
          Parameters
          ----------
          F : symbol or ndarray
          att_weights : Symbol or NDArray
              Attention weights.
              For single-head attention,
                  Shape (batch_size, query_length, memory_length).
              For multi-head attention,
                  Shape (batch_size, num_heads, query_length, memory_length).
          value : Symbol or NDArray
              Value of the memory. Shape (batch_size, memory_length, total_value_dim)
  
          Returns
          -------
          context_vec: Symbol or NDArray
              Shape (batch_size, query_length, context_vec_dim)