class_docstr: Variational Dropout RNN 实现.
  
  论文参考: `A Theoretically Grounded Application of Dropout in Recurrent Neural Networks (Yarin Gal and Zoubin Ghahramani, 2016)
  https://arxiv.org/abs/1512.05287`.
class_docstr_tok: ["Variational","Dropout","RNN","\u5b9e\u73b0",".","\u8bba\u6587\u53c2\u8003",":","`","A","Theoretically","Grounded","Application","of","Dropout","in","Recurrent","Neural","Networks","(","Yarin","Gal","and","Zoubin","Ghahramani",",","2016",")","https",":","\/\/arxiv.org\/abs\/1512.05287","`","."]
docstr: :param x: [batch, seq_len, input_size] 输入序列
  :param hx: [batch, hidden_size] 初始隐状态, 若为 ``None`` , 设为全1向量. Default: ``None``
  :return (output, ht): [batch, seq_len, hidden_size*num_direction] 输出序列
      和 [batch, hidden_size*num_direction] 最后时刻隐状态
docstr_tok: [":","param","x",":","[","batch",",","seq_len",",","input_size","]","\u8f93\u5165\u5e8f\u5217",":","param","hx",":","[","batch",",","hidden_size","]","\u521d\u59cb\u9690\u72b6\u6001",",","\u82e5\u4e3a","``","None","``",",","\u8bbe\u4e3a\u51681\u5411\u91cf",".","Default",":","``","None","``",":","return","(","output",",","ht",")",":","[","batch",",","seq_len",",","hidden_size","*","num_direction","]","\u8f93\u51fa\u5e8f\u5217","\u548c","[","batch",",","hidden_size","*","num_direction","]","\u6700\u540e\u65f6\u523b\u9690\u72b6\u6001"]
code: def forward(self, x, hx=None):
      r"""
  
      :param x: [batch, seq_len, input_size] 输入序列
      :param hx: [batch, hidden_size] 初始隐状态, 若为 ``None`` , 设为全1向量. Default: ``None``
      :return (output, ht): [batch, seq_len, hidden_size*num_direction] 输出序列
          和 [batch, hidden_size*num_direction] 最后时刻隐状态
      """
      is_lstm = self.is_lstm
      is_packed = isinstance(x, PackedSequence)
      if not is_packed:
          seq_len = x.size(1) if self.batch_first else x.size(0)
          max_batch_size = x.size(0) if self.batch_first else x.size(1)
          seq_lens = torch.LongTensor(
              [seq_len for _ in range(max_batch_size)]
          )
          x = pack_padded_sequence(
              x, seq_lens, batch_first=self.batch_first
          )
      else:
          max_batch_size = int(x.batch_sizes[0])
      x, batch_sizes = x.data, x.batch_sizes
  
      if hx is None:
          hx = x.new_zeros(
              self.num_layers * self.num_directions,
              max_batch_size,
              self.hidden_size,
              requires_grad=True,
          )
          if is_lstm:
              hx = (hx, hx.new_zeros(hx.size(), requires_grad=True))
  
      mask_x = x.new_ones((max_batch_size, self.input_size))
      mask_out = x.new_ones(
          (max_batch_size, self.hidden_size * self.num_directions)
      )
      mask_h_ones = x.new_ones((max_batch_size, self.hidden_size))
      nn.functional.dropout(
          mask_x,
          p=self.input_dropout,
          training=self.training,
          inplace=True,
      )
      nn.functional.dropout(
          mask_out,
          p=self.hidden_dropout,
          training=self.training,
          inplace=True,
      )
  
      hidden = x.new_zeros(
          (
              self.num_layers * self.num_directions,
              max_batch_size,
              self.hidden_size,
          )
      )
      if is_lstm:
          cellstate = x.new_zeros(
              (
                  self.num_layers * self.num_directions,
                  max_batch_size,
                  self.hidden_size,
              )
          )
      for layer in range(self.num_layers):
          output_list = []
          input_seq = PackedSequence(x, batch_sizes)
          mask_h = nn.functional.dropout(
              mask_h_ones,
              p=self.hidden_dropout,
              training=self.training,
              inplace=False,
          )
          for direction in range(self.num_directions):
              output_x, hidden_x = self._forward_one(
                  layer,
                  direction,
                  input_seq,
                  hx,
                  mask_x if layer == 0 else mask_out,
                  mask_h,
              )
              output_list.append(output_x.data)
              idx = self.num_directions * layer + direction
              if is_lstm:
                  hidden[idx] = hidden_x[0]
                  cellstate[idx] = hidden_x[1]
              else:
                  hidden[idx] = hidden_x
          x = torch.cat(output_list, dim=-1)
  
      if is_lstm:
          hidden = (hidden, cellstate)
  
      if is_packed:
          output = PackedSequence(x, batch_sizes)
      else:
          x = PackedSequence(x, batch_sizes)
          output, _ = pad_packed_sequence(
              x, batch_first=self.batch_first
          )
  
      return output, hidden
  
imports: import torch
  import torch.nn
  from torch.nn.utils.rnn import PackedSequence, pack_padded_sequence, pad_packed_sequence
label_desc: Use image node_id 3 for calling the VarRNNBase obj's underlying member method code with example usage: obj.forward(x, hx) and returns: output,  hidden