# Cell [![View Source On Gitee](https://gitee.com/mindspore/docs/raw/r1.3/resource/_static/logo_source.png)](https://gitee.com/mindspore/docs/blob/r1.3/docs/mindspore/programming_guide/source_en/cell.md) ## Overview The `Cell` class of MindSpore is the base class for building all networks and the basic unit of a network. When you need to customize a network, you need to inherit the `Cell` class and override the `__init__` and `construct` methods. Loss functions, optimizers, and model layers are parts of the network structure and can be implemented only by inheriting the `Cell` class. You can also customize them based on service requirements. The following describes the key member functions of the `Cell` class, "Building a network" will introduce the built-in loss functions, optimizers, and model layers of MindSpore implemented based on the `Cell` class, and how to use them, as well as describes how to use the `Cell` class to build a customized network. ## Key Member Functions ### construct The `Cell` class overrides the `__call__` method. When the `Cell` class instance is called, the `construct` method is executed. The network structure is defined in the `construct` method. In the following example, a simple network is built to implement the convolution computing function. The operators in the network are defined in `__init__` and used in the `construct` method. The network structure of the case is as follows: `Conv2d` -> `BiasAdd`. In the `construct` method, `x` is the input data, and `output` is the result obtained after the network structure computation. ```python import mindspore.nn as nn import mindspore.ops as ops from mindspore import Parameter from mindspore.common.initializer import initializer class Net(nn.Cell): def __init__(self, in_channels=10, out_channels=20, kernel_size=3): super(Net, self).__init__() self.conv2d = ops.Conv2D(out_channels, kernel_size) self.bias_add = ops.BiasAdd() self.weight = Parameter(initializer('normal', [out_channels, in_channels, kernel_size, kernel_size])) def construct(self, x): output = self.conv2d(x, self.weight) output = self.bias_add(output, self.bias) return output ``` ### parameters_dict The `parameters_dict` method is used to identify all parameters in the network structure and return `OrderedDict` with key as the parameter name and value as the parameter value. There are many other methods for returning parameters in the `Cell` class, such as `get_parameters` and `trainable_params`. For details, see [mindspore API](https://www.mindspore.cn/docs/api/en/r1.3/api_python/nn/mindspore.nn.Cell.html). A code example is as follows: ```python net = Net() result = net.parameters_dict() print(result.keys()) print(result['weight']) ``` The following information is displayed: ```text odict_keys(['weight']) Parameter (name=weight, shape=(20, 10, 3, 3), dtype=Float32, requires_grad=True) ``` In the example, `Net` uses the preceding network building case to print names of all parameters on the network and the result of the `weight` parameter. ### cells_and_names The `cells_and_names` method is an iterator that returns the name and content of each `Cell` on the network. The case simply implements the function of obtaining and printing the name of each `Cell`. According to the network structure, there is a `Cell` whose name is `nn.Conv2d`. `nn.Conv2d` is a convolutional layer encapsulated by MindSpore using `Cell` as the base class. For details, see "Model Layers". A code example is as follows: ```python import mindspore.nn as nn class Net1(nn.Cell): def __init__(self): super(Net1, self).__init__() self.conv = nn.Conv2d(3, 64, 3, has_bias=False, weight_init='normal') def construct(self, x): out = self.conv(x) return out net = Net1() names = [] for m in net.cells_and_names(): print(m) names.append(m[0]) if m[0] else None print('-------names-------') print(names) ``` ```text ('', Net1< (conv): Conv2d >) ('conv', Conv2d) -------names------- ['conv'] ``` ### set_grad The `set_grad` API is used to construct a backward network. If no parameter is transferred for calling the API, the default value of `requires_grad` is True. This API needs to be used in the scenario where the backward network is computed. Take `TrainOneStepCell` as an example. Its API function is to perform single-step training on the network. The backward network needs to be computed. Therefore, `set_grad` needs to be used in the initialization method. A part of the `TrainOneStepCell` code is as follows: ```python class TrainOneStepCell(Cell): def __init__(self, network, optimizer, sens=1.0): super(TrainOneStepCell, self).__init__(auto_prefix=False) self.network = network self.network.set_grad() ...... ``` If using similar APIs such as `TrainOneStepCell`, you do not need to use `set_grad`. The internal encapsulation is implemented. If you need to customize APIs of this training function, call APIs internally or set `network.set_grad` externally. ## Relationship Between the nn Module and the ops Module The nn module of MindSpore is a model component implemented by Python. It encapsulates low-level APIs, including various model layers, loss functions, and optimizers. In addition, nn provides some APIs with the same name as the `Primitive` operator to further encapsulate the `Primitive` operator and provide more friendly APIs. Reanalyze the case of the `construct` method described above. This case is the simplified content of the `nn.Conv2d` source code of MindSpore, and `ops.Conv2D` is internally called. The `nn.Conv2d` convolution API adds the input parameter validation function and determines whether `bias` is used. It is an advanced encapsulated model layer. ```python import mindspore.nn as nn import mindspore.ops as ops from mindspore import Parameter from mindspore.common.initializer import initializer class Net(nn.Cell): def __init__(self, in_channels=10, out_channels=20, kernel_size=3): super(Net, self).__init__() self.conv2d = ops.Conv2D(out_channels, kernel_size) self.bias_add = ops.BiasAdd() self.weight = Parameter(initializer('normal', [out_channels, in_channels, kernel_size, kernel_size])) def construct(self, x): output = self.conv2d(x, self.weight) output = self.bias_add(output, self.bias) return output ```