code: def binary_weight_convolution(
      inp,
      outmaps,
      kernel,
      pad=None,
      stride=None,
      dilation=None,
      group=1,
      quantize_zero_to=1.0,
      w_init=None,
      wb_init=None,
      b_init=None,
      base_axis=1,
      fix_parameters=False,
      rng=None,
      with_bias=True,
  ):
      """Binary Weight Convolution, multiplier-less inner-product with a scale factor.
  
      Binary Weight Convolution is the convolution function, but the
      inner product in this function is the following,
  
      .. math::
  
          y_{n, a, b} = \\frac{1}{\\|\\mathbf{w}_n\\|_{\\ell_1}} \sum_{m} \sum_{i} \sum_{j} sign(w_{n, m, i, j}) x_{m, a + i, b + j}.
  
  
      Therefore :math:`sign(w_{n, m, i, j})`  is either :math:`1` or :math:`-1` and the inner product
      simplifies to addition followed by scaling factor :math:`\\alpha = \\frac{1}{\\|\\mathbf{w}_n\\|_{\\ell_1}}`.
      The number of :math:`n` is the number of outmaps of the convolution
      function.
  
      References:
  
          Rastegari, Mohammad, et al. "XNOR-Net: ImageNet Classification Using
          Binary Convolutional Neural Networks." arXiv preprint
          arXiv:1603.05279 (2016).
  
      .. note::
  
          1) if you would like to share weights between some layers, please
          make sure to share the standard, floating value weights (`weight`)
          and not the binarized weights (`binary_weight`)
  
          2) The weights and the binary weights become synced only after :func:`~nnabla._variable.Variable.forward` is called,
          and not after a call to :func:`~nnabla._variable.Variable.backward`.
          To access the parameters of the network, remember to call :func:`~nnabla._variable.Variable.forward` once before doing so, otherwise the
          float weights and the binary weights will not be in sync.
  
          3) Quantized values are stored as floating point number for `binary_weight`,
          since this function is only for simulation purposes.
  
      Args:
          inp (~nnabla.Variable): N-D array.
          outmaps (int): Number of convolution kernels (which is equal to the number of output channels). For example, to apply convolution on an input with 16 types of filters, specify 16.
          kernel (:obj:`tuple` of :obj:`int`): Convolution kernel size. For example, to apply convolution on an image with a 3 (height) by 5 (width) two-dimensional kernel, specify (3,5).
          pad (:obj:`tuple` of :obj:`int`): Padding sizes for dimensions.
          stride (:obj:`tuple` of :obj:`int`): Stride sizes for dimensions.
          dilation (:obj:`tuple` of :obj:`int`): Dilation sizes for dimensions.
          group (int): Number of groups of channels. This makes connections across channels sparser by grouping connections along map direction.
          quantize_zero_to (float): Input value at zero is quantized to this value.
          w_init (:obj:`nnabla.initializer.BaseInitializer` or :obj:`numpy.ndarray`): Initializer for weight. By default, it is initialized with :obj:`nnabla.initializer.UniformInitializer` within the range determined by :obj:`nnabla.initializer.calc_uniform_lim_glorot`.
          wb_init (:obj:`nnabla.initializer.BaseInitializer` or :obj:`numpy.ndarray`): Initializer for binary weight. By default, it is initialized with :obj:`nnabla.initializer.UniformInitializer` within the range determined by :obj:`nnabla.initializer.calc_uniform_lim_glorot`.
          b_init (:obj:`nnabla.initializer.BaseInitializer` or :obj:`numpy.ndarray`): Initializer for bias. By default, it is initialized with zeros if `with_bias` is `True`.
          base_axis (int): Dimensions up to `base_axis` are treated as the sample dimensions.
          fix_parameters (bool): When set to `True`, the weights and biases will not be updated.
          rng (numpy.random.RandomState): Random generator for Initializer.
          with_bias (bool): Specify whether to include the bias term.
  
      Returns:
          :class:`~nnabla.Variable`
  
      """
      if w_init is None:
          w_init = UniformInitializer(
              calc_uniform_lim_glorot(
                  inp.shape[base_axis], outmaps, tuple(kernel)
              ),
              rng=rng,
          )
      if wb_init is None:
          wb_init = UniformInitializer(
              calc_uniform_lim_glorot(
                  inp.shape[base_axis], outmaps, tuple(kernel)
              ),
              rng=rng,
          )
      if b_init is None:
          b_init = ConstantInitializer()
      w = get_parameter_or_create(
          "W",
          (outmaps, inp.shape[base_axis]) + tuple(kernel),
          w_init,
          True,
          not fix_parameters,
      )
      wb = get_parameter_or_create(
          "Wb",
          (outmaps, inp.shape[base_axis]) + tuple(kernel),
          wb_init,
          False,
      )
      alpha = get_parameter_or_create(
          "alpha", (outmaps,), ConstantInitializer(0), False
      )
      b = None
      if with_bias:
          b = get_parameter_or_create(
              "b", (outmaps,), b_init, True, not fix_parameters
          )
      return F.binary_weight_convolution(
          inp,
          w,
          wb,
          alpha,
          b,
          base_axis,
          pad,
          stride,
          dilation,
          group,
          quantize_zero_to,
      )
  
imports: from six import exec_
  import numpy
  import nnabla
  import nnabla.functions
  from nnabla.parameter import get_parameter_or_create, get_parameter
  from nnabla.initializer import calc_uniform_lim_glorot, ConstantInitializer, NormalInitializer, UniformInitializer, WeightNormalizationScaleInitializer
label_desc: Use image node_id 11 for calling a global function with example usage: binary_weight_convolution(inp, outmaps, kernel, pad, stride, dilation, group, quantize_zero_to, w_init, wb_init, b_init, base_axis, fix_parameters, rng, with_bias) and returns: F