Growing Cellular Automata

Differentiable Model of Morphogenesis
So I have a goal of implementing this work in Mathematica.
I’ll use the lizard image used in paper :
In[]:=
lizard=
;
In[]:=
//ImageDimensions
Out[]=
{1024,1024}
I create a function for building multi-channel convolution layers of arbitrary depth and kernel.
In[]:=
convolution[kernel_,depth_Integer,bias_]:=ConvolutionLayer​​depth,3,​​"Weights"TableRotateRightAppendConstantArray
0
0
0
0
0
0
0
0
0
,depth-1,kernel,i,{i,depth},​​"Biases"ConstantArray[bias,depth],​​PaddingSize1​​
I build the neural network for a single step evolution. It must only consist of convolutional or element-wise layers, as the rule for the evolution of the state of a cell must depend only on the state of the cell itself or of the state of its immediate neighbors.
In[]:=
step[​​numberOfStates_Integer:16,​​hiddenConvolutionLayerSize_Integer:128​​]:=NetGraph​​<|​​"P"CatenateLayer[],​​"Σ"TotalLayer[],​​"∇x"convolution
1
4
-1
0
1
-2
0
2
-1
0
1
,numberOfStates,.5,​​"∇y"convolution
1
4
-1
-2
-1
0
0
0
1
2
1
,numberOfStates,.5,​​"I"convolution
0
0
0
0
1
0
0
0
0
,numberOfStates,0.,​​"D1"ConvolutionLayer[hiddenConvolutionLayerSize,1],​​"ReLU"Ramp,​​"D2"ConvolutionLayer[​​numberOfStates,1,​​"Weights"ConstantArray[0.,{numberOfStates,hiddenConvolutionLayerSize,1,1}],​​"Biases"ConstantArray[0.,numberOfStates]​​]​​|>,​​{​​NetPort["Input"]{"∇x","∇y","I","Σ"},​​"∇x"NetPort["P",1],​​"∇y"NetPort["P",2],​​"I"NetPort["P",3],​​"P""D1""ReLU""D2"->"Σ"​​}​​
In[]:=
NetChain[{​​step[3]//NetInitialize​​},​​"Input"NetEncoder[{"Image",ColorSpace"RGB"}],​​"Output"NetDecoder["Image"]​​]@
Out[]=
In[]:=
net=NetChain[​​{​​NetNestOperator[step[16]//NetInitialize,10],​​PartLayer[1;;3]​​},​​"Output"NetDecoder["Image"]​​]
Out[]=
NetChain
Input port:
array (size: 16××)
Output port:
image

In[]:=
randomInput[]:=Array[CenterArray[RandomReal[],{#,#}&@128]&,16]
In[]:=
input=Array[randomInput[]&,100];​​output=ConstantArrayImageResize
,128,100;
Try the command below if you dare :
net=NetTrain[net,(inputoutput)]
In[]:=
net@randomInput[]
Out[]=