def max_pool_backward_im2col(dout, cache):
    "\n  An implementation of the backward pass for max pooling based on im2col.\n\n  This isn't much faster than the naive version, so it should be avoided if\n  possible.\n  "
    (x, x_cols, x_cols_argmax, pool_param) = cache
    (N, C, H, W) = x.shape
    (pool_height, pool_width) = (pool_param['pool_height'], pool_param['pool_width'])
    stride = pool_param['stride']
    dout_reshaped = dout.transpose(2, 3, 0, 1).flatten()
    dx_cols = np.zeros_like(x_cols)
    dx_cols[(x_cols_argmax, np.arange(dx_cols.shape[1]))] = dout_reshaped
    dx = col2im_indices(dx_cols, ((N * C), 1, H, W), pool_height, pool_width, padding=0, stride=stride)
    dx = dx.reshape(x.shape)
    return dx
An implementation of the backward pass for max pooling based on im2col.

This isn't much faster than the naive version, so it should be avoided if
possible.
def max_pool_backward_im2col(dout, cache):
    "\n  An implementation of the backward pass for max pooling based on im2col.\n\n  This isn't much faster than the naive version, so it should be avoided if\n  possible.\n  "
    (x, x_cols, x_cols_argmax, pool_param) = cache
    (N, C, H, W) = x.shape
    (pool_height, pool_width) = (pool_param['pool_height'], pool_param['pool_width'])
    stride = pool_param['stride']
    dout_reshaped = dout.transpose(2, 3, 0, 1).flatten()
    dx_cols = np.zeros_like(x_cols)
    dx_cols[(x_cols_argmax, np.arange(dx_cols.shape[1]))] = dout_reshaped
    dx = col2im_indices(dx_cols, ((N * C), 1, H, W), pool_height, pool_width, padding=0, stride=stride)
    dx = dx.reshape(x.shape)
    return dx