How to construct a search space?ΒΆ
In this tutorial, we will show how to define a search space. Basically, a search space is
a huge DNN model that contains many different candidate layers, which can be selected
or dropped from the network by adjusting the architecture parameters. In NNablaNAS,
a search space therefore is defined as a Model
class,
inherits the API from the class nnabla_nas.contrib.model.Model
.
The base API of the Model
class has four methods,
get_arch_parameters()
, get_net_parameters()
, loss()
and
metrics()
, that return the architecture parameters and model parameters, a loss value and
evaluation metrics for a model, respectively. The following example shows how
you can define a simple search space that contains three different layers, namely
a convolutional, a maximum pooling and an identity layer, that can be selected by the
architecture search algorithm. The candidate layers are followed by a global average pooling
and a linear classification layer.
from collections import OrderedDict
from nnabla_nas import module as Mo
from nnabla_nas.contrib.model import Model
import nnabla.functions as F
class MyModel(Model):
def __init__(self):
self._block = Mo.MixedOp(
operators=[
Mo.Conv(in_channels=3, out_channels=3, kernel=(3, 3), pad=(1, 1)),
Mo.MaxPool(kernel=(3, 3), stride=(1, 1), pad=(1, 1)),
Mo.Identity()
],
mode='full'
)
self._classifier = Mo.Sequential(
Mo.ReLU(),
Mo.GlobalAvgPool(),
Mo.Linear(3, 10)
)
def call(self, input):
out = self._block(input)
out = self._classifier(out)
return out
def get_arch_parameters(self, grad_only=False):
r"""Returns an `OrderedDict` containing architecture parameters."""
p = self.get_parameters(grad_only)
return OrderedDict([(k, v) for k, v in p.items() if 'alpha' in k])
def get_net_parameters(self, grad_only=False):
r"""Returns an `OrderedDict` containing model parameters."""
p = self.get_parameters(grad_only)
return OrderedDict([(k, v) for k, v in p.items() if 'alpha' not in k])
def loss(self, outputs, targets, loss_weights=None, *args):
assert len(outputs) == 1 and len(targets) == 1
return F.mean(F.softmax_cross_entropy(outputs[0], targets[0]))
def metrics(self, outputs, targets):
assert len(targets) == 1
return {"error": F.mean(F.top_n_error(outputs[0], targets[0]))}
if __name__ == '__main__':
net = MyModel()
print(net)