class_docstr: Reshapes the input as a 2D tensor where each row is an pooling
  example.
  
  Parameters
  ----------
  mode : {'valid', 'ignore_borders', 'wrap_centered'}
      - 'valid' :
          Requires an input that is a multiple of the pooling factor
          (in each direction).
      - 'half' :
          Equivalent to 'valid' if we pre-pad with zeros the input on
          each side by (neib_shape[0]//2, neib_shape[1]//2)
      - 'full' :
          Equivalent to 'valid' if we pre-pad with zeros the input on
          each side by (neib_shape[0] - 1, neib_shape[1] - 1)
      - 'ignore_borders' :
          Same as valid, but will ignore the borders if the shape(s)
          of the input is not a multiple of the pooling factor(s).
      - 'wrap_centered' :
          ?? TODO comment
class_docstr_tok: ["Reshapes","the","input","as","a","2D","tensor","where","each","row","is","an","pooling","example",".","Parameters","--","--","--","--","--","mode",":","{","'valid","'",",","'ignore_borders","'",",","'wrap_centered","'","}","-","'valid","'",":","Requires","an","input","that","is","a","multiple","of","the","pooling","factor","(","in","each","direction",")",".","-","'half","'",":","Equivalent","to","'valid","'","if","we","pre-pad","with","zeros","the","input","on","each","side","by","(","neib_shape","[","0","]","\/\/2",",","neib_shape","[","1","]","\/\/2",")","-","'full","'",":","Equivalent","to","'valid","'","if","we","pre-pad","with","zeros","the","input","on","each","side","by","(","neib_shape","[","0","]","-","1",",","neib_shape","[","1","]","-","1",")","-","'ignore_borders","'",":","Same","as","valid",",","but","will","ignore","the","borders","if","the","shape","(","s",")","of","the","input","is","not","a","multiple","of","the","pooling","factor","(","s",")",".","-","'wrap_centered","'",":","?","?","TODO","comment"]
code: def infer_shape(self, node, input_shape):
      in_shape = input_shape[0]
      c, d = node.inputs[1]
      step_x, step_y = node.inputs[2]
      if self.mode == "wrap_centered":
          grid_c = T.ceil_intdiv(in_shape[2], step_x)
          grid_d = T.ceil_intdiv(in_shape[3], step_y)
      elif self.mode == "valid":
          grid_c = 1 + ((in_shape[2] - c) // step_x)
          grid_d = 1 + ((in_shape[3] - d) // step_y)
      elif self.mode == "ignore_borders":
          grid_c = 1 + ((in_shape[2] - c) // step_x)
          grid_d = 1 + ((in_shape[3] - d) // step_y)
      elif self.mode == "half":
          grid_c = 1 + ((in_shape[2] - (c % 2)) // step_x)
          grid_d = 1 + ((in_shape[3] - (d % 2)) // step_y)
      elif self.mode == "full":
          grid_c = 1 + ((in_shape[2] + c - 2) // step_x)
          grid_d = 1 + ((in_shape[3] + d - 2) // step_y)
      else:
          raise TypeError("Images2Neibs: unknow mode '%s'" % self.mode)
      z_dim0 = grid_c * grid_d * in_shape[1] * in_shape[0]
      z_dim1 = c * d
      return [(z_dim0, z_dim1)]
  
imports: from __future__ import absolute_import, print_function, division
  import numpy
  import theano
  from theano import Op, Apply
  from theano.gof import EnumList
  import theano.tensor
  from theano.gradient import grad_not_implemented
  from theano.gradient import grad_undefined
label_desc: Use image node_id 9 for calling the Images2Neibs obj's underlying member method code with example usage: obj.infer_shape(node, input_shape) and returns: list