Sorry I missed your conv2d as a static function, my bad.
Few details:

You nn.Module does not work for me and through the not implemented error from _conv_forward

You should never call the .forward() of the nn.Module directly. You should use the __call__ on it as  result = layer(image).
You don’t need to wrap things in Variables anymore. You can just use regular Tensors: image = torch.from_numpy(image).requires_grad_().

By removing the custom module, it runs.
This is a know issue and if you use the nightly build, you will see the following warning:
“”"
…/torch/csrc/autograd/variable.cpp:421: UserWarning: Output 0 of _Conv2dCustomBackward is a view and its base or another view of its base has been modified inplace. This view was created inside a custom Function (or because an input was returned as-is) and the autograd logic to handle view+inplace would override the custom backward associated with the custom Function, leading to incorrect gradients. This behavior is deprecated and will be forbidden starting version 1.6. You can remove this warning by cloning the output of the custom Function.
“”"
As it states, the fact that your custom Function returns a view and that you modify it inplace in when adding the bias break some internal autograd assumptions.
You should either change _conv2d to return output.clone() to avoid returning a view. Or change your bias update to output = output + bias.view(-1, 1, 1) to avoid the inplace operations.