In that case I guess your custom init method might yield a bad initialization, as using e.g. torch.randn works fine and creates valid gradients:
def custom_weight_fn(shape):
    return torch.randn(shape)


def init_weights(m):
  with torch.no_grad():
    if type(m) == nn.Linear or type(m) == nn.Conv2d:
      m.weight = nn.Parameter(custom_weight_fn(m.weight.shape))
      m.bias = nn.Parameter(custom_weight_fn(m.bias.shape))

channel_1 = 3
channel_2 = 3
model = nn.Sequential(
    nn.Conv2d(3, channel_1, 5, padding=2),
    nn.ReLU(),
    nn.Conv2d(channel_1, channel_2, 3, padding=1),
    nn.ReLU(),
    nn.Flatten(),
    nn.Linear(32*32*channel_2, 10)
)

model.apply(init_weights) 

out = model(torch.randn(1, 3, 32, 32))
out.mean().backward()

for name, param in model.named_parameters():
    print('{}, grad.abs().max(): {}'.format(name, param.grad.abs().max()))