code: def backward(self, indexes, grad_outputs):
      x, W, gy = self.get_retained_inputs()
  
      device = backend.get_device_from_array(x.data)
      xp = device.xp
  
      if 0 in indexes:
          gx = chainer.Variable(xp.zeros_like(x.data))
      if 1 in indexes:
          gW = chainer.Variable(xp.zeros_like(W.data))
      if 2 in indexes:
          ggy = chainer.Variable(xp.zeros_like(gy.data))
  
      ggx, _, ggW = grad_outputs
  
      pos_neg_mask = xp.ones(self.sample_size + 1)
      pos_neg_mask[0] *= -1
  
      with chainer.using_device(device):
          arange = xp.arange(len(self.ignore_mask))
      for i in arange[self.ignore_mask]:
          # Partial forward pass to obtain intermediate `Variable`s
          ix = x[i]
          k = self.samples[i]
  
          if self.reduce == "sum":
              igy = gy
          else:
              igy = gy[i]
  
          w = W[k]
          f = (
              chainer.functions.flatten(
                  chainer.functions.matmul(w, ix[:, None])
              )
              * pos_neg_mask
          )
          sigf = chainer.functions.sigmoid(f)
          g = (
              chainer.functions.broadcast_to(igy, f.shape)
              * sigf
              * pos_neg_mask
          )
  
          dgW_dg = (
              chainer.functions.flatten(
                  chainer.functions.matmul(ggW[k], ix[:, None])
              )
              * pos_neg_mask
          )
          dgW_df = (
              chainer.functions.broadcast_to(igy, f.shape)
              * _sigmoid_grad(f, sigf, dgW_dg)
              * pos_neg_mask
          )
          dgx_dg = chainer.functions.flatten(
              chainer.functions.matmul(ggx[i][None, :], w, transb=True)
          )
          dgx_df = chainer.functions.broadcast_to(
              igy, f.shape
          ) * _sigmoid_grad(f, sigf, dgx_dg)
  
          if 0 in indexes:
              # derivative of gx
              dgx = chainer.functions.matmul(
                  w, dgx_df[:, None], transa=True
              )
  
              # derivative of gW
              dgx += chainer.functions.matmul(g[None, :], ggW[k]).T
              dgx += chainer.functions.matmul(
                  w, dgW_df[:, None], transa=True
              )
  
              gx = chainer.functions.scatter_add(
                  gx, i, chainer.functions.flatten(dgx)
              )
  
          if 1 in indexes:
              # derivative of gx
              shape = ggx[i].shape
              for ik, ig, idgx_df in six.moves.zip(k, g, dgx_df):
                  ig = chainer.functions.broadcast_to(ig, shape)
                  idgx_df = chainer.functions.broadcast_to(
                      idgx_df, shape
                  )
                  gW = chainer.functions.scatter_add(
                      gW, ik, ig * ggx[i] + idgx_df * ix
                  )
  
              # derivative of gW
              gW = chainer.functions.scatter_add(
                  gW,
                  k,
                  chainer.functions.matmul(
                      dgW_df[:, None], ix[None, :]
                  ),
              )
  
          if 2 in indexes:
              dgx_dg *= pos_neg_mask
              dggy = chainer.functions.sum((dgx_dg + dgW_dg) * sigf)
              if self.reduce == "sum":
                  ggy += dggy
              else:
                  ggy = chainer.functions.scatter_add(ggy, i, dggy)
  
      ret = []
      if 0 in indexes:
          ret.append(gx)
      if 1 in indexes:
          ret.append(gW)
      if 2 in indexes:
          ret.append(ggy)
      return ret
  
imports: import numpy
  import six
  import chainer
  from chainer import backend
  from chainer.backends import cuda
  from chainer import function_node
  from chainer import utils
  from chainer.utils import argument
  from chainer.utils import precision
  from chainer.utils import type_check
label_desc: Use image node_id 4 for calling the NegativeSamplingFunctionGrad obj's underlying member method code with example usage: obj.backward(indexes, grad_outputs) and returns: ret