Thanks for the code update.
The first few operations in your PyTorch model:
    conv1 = self.dconv_down1(x)
    x = self.dconv_down11(conv1)
    x += conv1
    x = self.relu(x)
    x = self.maxpool(x)

would yield the following execution order:
x -> conv -> bn -> relu -> conv -> bn -> relu -> out -> conv -> bn -> relu - > conv -> bn -> x
x += out

While in Keras the execution order would be:
x -> conv -> out -> relu -> bn -> conv -> bn -> relu -> conv -> bn -> x
x += out

E.g. one difference is that in the Keras model you are using the output of the first conv layer as the residual connection in residual_block, while you are using the output of the first double_conv block as the residual connection in PyTorch.
if I’m not mistaken.