Thanks for the update. I was wondering if the original poster was still around years later (certainly the problem still is). With the extra information I improved on the annotated code. After your description it makes more sense now. What seems less reasonable is the way WL neural nets handle this use case. I hadn't seen that ResizeLayer
also has the drawback of being unable to work on 4D arrays much like DeconvolutionLayer
s. Excellent job figuring all this out. Your new version looks like a type of Progressive Growth GAN where the steps are mixed as its upsampled.
ResizeLayer3D[n_, {dimInx_, dimIny_, dimInz_}] :=
Block[{sc = 2},
NetChain[{
(* Flattens the first two levels so because the next layer only \
works on 2D arrays *)
FlattenLayer[1, "Input" -> {n sc, dimInx, dimIny, dimInz}],
(* Doubles the size of the last two dimensions *)
ResizeLayer[{Scaled[sc], Scaled[sc]}],
(* Reshapes the array back to its original order but with the \
last two dimensions scaled up from previous layer *)
ReshapeLayer[{n sc, dimInx, sc dimIny, sc dimInz}],
(* Transposes 2nd and 3rd dimensions so that previously unscaled \
dimension can be actioned *)
TransposeLayer[2 <-> 3],
(* Again flatten array a level so that the next later can \
actually action it *)
FlattenLayer[1],
(* Scale only the dimension that hasn't been actioned yet *)
ResizeLayer[{Scaled[sc], Scaled[1]}],
(* reshape back to original structure but the array now has been \
scaled up *)
ReshapeLayer[{n sc, sc dimIny, sc dimInx, sc dimInz}],
(* importantly, transpose the dimensions back to their original order since it was \
changed above*)
TransposeLayer[2 <-> 3],
(* Now a convolution can be applied to the upsampled up data *)
ConvolutionLayer[n, 1]}
]
]