def AccumulateConvDeriv(layer, edge, deriv):

  if layer.dirty:  # If some derivatives have already been received.
    raise Exception('Not implemented.')
  layer.dirty = True
  w = edge.params['weight']
  conv = edge.conv_params
  size = conv.size
  stride = conv.stride
  padding = conv.padding
  num_filters = conv.num_filters
  num_colors = conv.num_colors

  input_t = edge.input_t
  numImages, numdims = input_t.shape

  assert numdims % num_colors == 0
  x = int(math.sqrt(numdims / num_colors))
  assert x**2 == numdims/num_colors

  n_locs = (x + 2 * padding - size) / stride + 1

  # Incoming gradient.
  deriv.transpose(edge.output_t2)
  input_grads = edge.output_t2

  # Output activation (after conv + pool? + norm?)
  output_acts = edge.output_t

  if conv.rnorm:

    # ResponseNormUndo overwrites input_acts, so make a copy.
    input_acts = edge.rnorm_temp1
    input_acts.assign(edge.unrnormalized_layer)

    output_grads = edge.rnorm_temp2
    denoms = edge.denoms

    sizeX = conv.norm_size
    pow_scale = conv.pow_scale
    add_scale = conv.add_scale
    cc.ResponseNormUndo(input_grads, denoms, output_acts, input_acts,
                        output_grads, num_filters, sizeX, add_scale,
                        pow_scale)
    input_grads = output_grads
    output_acts = edge.unrnormalized_layer

  if conv.max_pool:
    input_acts = edge.unpooled_layer
    output_grads = edge.unpooled_layer
    # It's OK to overwrite input_acts because we don't need it later.

    n_pool_locs = (n_locs - conv.pool_size) / conv.pool_stride + 1
    sizeX = conv.pool_size
    strideX = conv.pool_stride
    cc.MaxPoolUndo(output_grads, input_acts, input_grads, output_acts, sizeX,
                   0, strideX, n_pool_locs)
    input_grads = output_grads
    output_acts = input_acts
  if layer.is_input:
    return

  output_grads = edge.input_t2
  if edge.conv:
    cc.convDown(input_grads, w, output_grads, n_locs, padding, stride, size, x, num_colors)
  else:
    cc.localDown(input_grads, w, output_grads, n_locs, padding, stride, size, x, num_colors)
  output_grads.transpose(layer.deriv)
Accumulate the derivative w.r.t the outputs of this layer.
dataset/ETHPy150Open nitishsrivastava/deepnet/deepnet/convolutions.py/AccumulateConvDeriv