I want to create a HybridBlock with some non-sequential blocks inside it, like this:
class Net1(gluon.HybridBlock):
def __init__(self, **kwargs):
super(Net1, self).__init__(**kwargs)
with self.name_scope():
self.conv1 = nn.Conv2D(3, kernel_size=5)
self.conv2 = nn.Conv2D(3, kernel_size=5)
def hybrid_forward(self, F, x):
x1 = self.conv1(x)
x2 = self.conv2(x)
return x1 + x2
The above example works. But I want to be able to pass in num_convs into init and declare the convolutional units inside a for loop. This fails (below). How can I create a dynamic number of non-sequential blocks in the init of this block?
>>> import mxnet as mx
>>> from mxnet import gluon
>>> from mxnet.gluon import nn
>>>
>>> # fails
... class Net2(gluon.HybridBlock):
... def __init__(self, **kwargs):
... super(Net2, self).__init__(**kwargs)
... with self.name_scope():
... self.convs = [nn.Conv2D(3, kernel_size=5), nn.Conv2D(3, kernel_size=5)]
... def hybrid_forward(self, F, x):
... x1 = self.convs[0](x)
... x2 = self.convs[1](x)
... return x1 + x2
...
>>> net2 = Net2()
>>> net2.initialize()
/home/local/ANT/gautierp/anaconda3/lib/python3.6/site-packages/mxnet/gluon/block.py:228: UserWarning: "Net2.convs" is a container with Blocks. Note that Blocks inside the list, tuple or dict will not be registered automatically. Make sure to register them using register_child() or switching to nn.Sequential/nn.HybridSequential instead.
.format(name=self.__class__.__name__ + "." + k))
>>> net2.collect_params()
net20_ (
)
>>> x = mx.nd.random_normal(shape=(16, 3, 28, 28))
>>> y = net2(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/local/ANT/gautierp/anaconda3/lib/python3.6/site-packages/mxnet/gluon/block.py", line 360, in __call__
return self.forward(*args)
File "/home/local/ANT/gautierp/anaconda3/lib/python3.6/site-packages/mxnet/gluon/block.py", line 575, in forward
return self.hybrid_forward(ndarray, x, *args, **params)
File "<stdin>", line 8, in hybrid_forward
File "/home/local/ANT/gautierp/anaconda3/lib/python3.6/site-packages/mxnet/gluon/block.py", line 360, in __call__
return self.forward(*args)
File "/home/local/ANT/gautierp/anaconda3/lib/python3.6/site-packages/mxnet/gluon/block.py", line 568, in forward
params = {i: j.data(ctx) for i, j in self._reg_params.items()}
File "/home/local/ANT/gautierp/anaconda3/lib/python3.6/site-packages/mxnet/gluon/block.py", line 568, in <dictcomp>
params = {i: j.data(ctx) for i, j in self._reg_params.items()}
File "/home/local/ANT/gautierp/anaconda3/lib/python3.6/site-packages/mxnet/gluon/parameter.py", line 389, in data
return self._check_and_get(self._data, ctx)
File "/home/local/ANT/gautierp/anaconda3/lib/python3.6/site-packages/mxnet/gluon/parameter.py", line 189, in _check_and_get
"nested child Blocks"%(self.name))
RuntimeError: Parameter net20_conv0_weight has not been initialized. Note that you should initialize parameters and create Trainer with Block.collect_params() instead of Block.params because the later does not include Parameters of nested child Blocks