code: def unpack_weights(self, args):
          
          args = args.copy()
          if not self._gate_names:
              return args
          h = self._num_hidden
          for group_name in ['i2h', 'h2h']:
              weight = args.pop('%s%s_weight'%(self._prefix, group_name))
              bias = args.pop('%s%s_bias' % (self._prefix, group_name))
              for j, gate in enumerate(self._gate_names):
                  wname = '%s%s%s_weight' % (self._prefix, group_name, gate)
                  args[wname] = weight[j*h:(j+1)*h].copy()
                  bname = '%s%s%s_bias' % (self._prefix, group_name, gate)
                  args[bname] = bias[j*h:(j+1)*h].copy()
          return args
docs: Unpack fused weight matrices into separate
          weight matrices.
  
          For example, say you use a module object `mod` to run a network that has an lstm cell.
          In `mod.get_params()[0]`, the lstm parameters are all represented as a single big vector.
          `cell.unpack_weights(mod.get_params()[0])` will unpack this vector into a dictionary of
          more readable lstm parameters - c, f, i, o gates for i2h (input to hidden) and
          h2h (hidden to hidden) weights.
  
          Parameters
          ----------
          args : dict of str -> NDArray
              Dictionary containing packed weights.
              usually from `Module.get_params()[0]`.
  
          Returns
          -------
          args : dict of str -> NDArray
              Dictionary with unpacked weights associated with
              this cell.
  
          See Also
          --------
          pack_weights: Performs the reverse operation of this function.