# model_constructor
> Constructor to create pytorch model.
## Install
`pip install model-constructor`
Or install from repo:
`pip install git+https://github.com/ayasyrev/model_constructor.git`
## How to use
First import constructor class, then create model constructor object.
Now you can change every part of model.
```python
from model_constructor import ModelConstructor
```
```python
mc = ModelConstructor()
```
Check base parameters:
```python
mc
```
<details open> <summary>output</summary>
<pre>ModelConstructor
in_chans: 3, num_classes: 1000
expansion: 1, groups: 1, dw: False, div_groups: None
act_fn: ReLU, sa: False, se: False
stem sizes: [64], stride on 0
body sizes [64, 128, 256, 512]
layers: [2, 2, 2, 2]</pre>
</details>
Check all parameters with `print_cfg` method:
```python
mc.print_cfg()
```
<details open> <summary>output</summary>
<pre>ModelConstructor(
in_chans=3
num_classes=1000
block='BasicBlock'
conv_layer='ConvBnAct'
block_sizes=[64, 128, 256, 512]
layers=[2, 2, 2, 2]
norm='BatchNorm2d'
act_fn='ReLU'
expansion=1
groups=1
bn_1st=True
zero_bn=True
stem_sizes=[64]
stem_pool="MaxPool2d {'kernel_size': 3, 'stride': 2, 'padding': 1}"
init_cnn='init_cnn'
make_stem='make_stem'
make_layer='make_layer'
make_body='make_body'
make_head='make_head')
</pre>
</details>
Now we have model constructor, default setting as resnet18. And we can get model after call it.
```python
model = mc()
model
```
<details> <summary>output</summary>
<pre>ModelConstructor(
(stem): Sequential(
(conv_1): ConvBnAct(
(conv): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(stem_pool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
)
(body): Sequential(
(l_0): Sequential(
(bl_0): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_1): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
)
(l_1): Sequential(
(bl_0): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(id_conv): Sequential(
(id_conv): ConvBnAct(
(conv): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_1): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
)
(l_2): Sequential(
(bl_0): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(id_conv): Sequential(
(id_conv): ConvBnAct(
(conv): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_1): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
)
(l_3): Sequential(
(bl_0): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(id_conv): Sequential(
(id_conv): ConvBnAct(
(conv): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_1): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
)
)
(head): Sequential(
(pool): AdaptiveAvgPool2d(output_size=1)
(flat): Flatten(start_dim=1, end_dim=-1)
(fc): Linear(in_features=512, out_features=1000, bias=True)
)
)</pre>
</details>
If you want to change model, just change constructor parameters.
Lets create resnet50.
```python
mc.expansion = 4
mc.layers = [3,4,6,3]
```
We can check, what we changed (compare to default constructor).
```python
mc.changed_fields
```
<details open> <summary>output</summary>
<pre>{'layers': [3, 4, 6, 3], 'expansion': 4}</pre>
</details>
```python
mc.print_changed_fields()
```
<details open> <summary>output</summary>
<pre>Changed fields:
layers: [3, 4, 6, 3]
expansion: 4
</pre>
</details>
We can compare changed with defaults.
```python
mc.print_changed_fields(show_default=True)
```
<details open> <summary>output</summary>
<pre>Changed fields:
layers: [3, 4, 6, 3] | [2, 2, 2, 2]
expansion: 4 | 1
</pre>
</details>
Now we can look at model parts - stem, body, head.
```python
mc.body
```
<details> <summary>output</summary>
<pre>Sequential(
(l_0): Sequential(
(bl_0): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_1): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_2): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
)
(l_1): Sequential(
(bl_0): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(id_conv): Sequential(
(id_conv): ConvBnAct(
(conv): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_1): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_2): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_3): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
)
(l_2): Sequential(
(bl_0): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(id_conv): Sequential(
(id_conv): ConvBnAct(
(conv): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_1): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_2): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_3): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_4): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_5): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
)
(l_3): Sequential(
(bl_0): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(id_conv): Sequential(
(id_conv): ConvBnAct(
(conv): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_1): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
(bl_2): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): ReLU(inplace=True)
)
)
)</pre>
</details>
## Create constructor from config.
Alternative we can create config first and than create constructor from it.
```python
from model_constructor import ModelCfg
```
```python
cfg = ModelCfg(
num_classes=10,
act_fn=nn.Mish,
)
print(cfg)
```
<details open> <summary>output</summary>
<pre>ModelCfg(
in_chans=3
num_classes=10
block='BasicBlock'
conv_layer='ConvBnAct'
block_sizes=[64, 128, 256, 512]
layers=[2, 2, 2, 2]
norm='BatchNorm2d'
act_fn='Mish'
expansion=1
groups=1
bn_1st=True
zero_bn=True
stem_sizes=[64]
stem_pool="MaxPool2d {'kernel_size': 3, 'stride': 2, 'padding': 1}")
</pre>
</details>
When creating config or constructor we can use string annotation for nn.Modules - it useful when creating model from config files.
```python
cfg = ModelCfg(
num_classes=10,
act_fn="nn.SELU",
)
print(cfg.act_fn)
```
<details open> <summary>output</summary>
<pre>class 'torch.nn.modules.activation.SELU'</pre>
</details>
Now we can create constructor from config:
```python
mc = ModelConstructor.from_cfg(cfg)
mc
```
<details open> <summary>output</summary>
<pre>ModelConstructor
in_chans: 3, num_classes: 10
expansion: 1, groups: 1, dw: False, div_groups: None
act_fn: SELU, sa: <class 'model_constructor.layers.SimpleSelfAttention'>, se: SEModule
stem sizes: [64], stride on 0
body sizes [64, 128, 256, 512]
layers: [2, 2, 2, 2]</pre>
</details>
## More modification.
Main purpose of this module - fast and easy modify model.
And here is the link to more modification to beat Imagenette leaderboard with add MaxBlurPool and modification to ResBlock [notebook](https://github.com/ayasyrev/imagenette_experiments/blob/master/ResnetTrick_create_model_fit.ipynb)
But now lets create model as mxresnet50 from [fastai forums tread](https://forums.fast.ai/t/how-we-beat-the-5-epoch-imagewoof-leaderboard-score-some-new-techniques-to-consider)
Lets create mxresnet constructor.
```python
mc = ModelConstructor(name='MxResNet')
```
Then lets modify stem.
```python
from model_constructor.xresnet import xresnet_stem
```
```python
mc.make_stem = xresnet_stem
mc.stem_sizes = [3,32,64,64]
```
Now lets change activation function to Mish.
Here is link to [forum discussion](https://forums.fast.ai/t/meet-mish-new-activation-function-possible-successor-to-relu)
We'v got Mish is in model_constructor.activations, but from pytorch 1.9 take it from torch:
```python
from torch.nn import Mish
```
```python
mc.act_fn = Mish
```
```python
mc
```
<details open> <summary>output</summary>
<pre>MxResNet
in_chans: 3, num_classes: 1000
expansion: 1, groups: 1, dw: False, div_groups: None
act_fn: Mish, sa: False, se: False
stem sizes: [3, 32, 64, 64], stride on 0
body sizes [64, 128, 256, 512]
layers: [2, 2, 2, 2]</pre>
</details>
```python
mc.print_changed_fields()
```
<details open> <summary>output</summary>
<pre>Changed fields:
name: MxResNet
act_fn: Mish
stem_sizes: [3, 32, 64, 64]
make_stem: xresnet_stem
</pre>
</details>
Here is model:
```python
mc()
```
<details> <summary>output</summary>
<pre>MxResNet(
act_fn: Mish, stem_sizes: [3, 32, 64, 64], make_stem: xresnet_stem
(stem): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(3, 3, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(conv_2): ConvBnAct(
(conv): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(conv_3): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(stem_pool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
)
(body): Sequential(
(l_0): Sequential(
(bl_0): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): Mish(inplace=True)
)
(bl_1): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): Mish(inplace=True)
)
)
(l_1): Sequential(
(bl_0): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(id_conv): Sequential(
(id_conv): ConvBnAct(
(conv): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): Mish(inplace=True)
)
(bl_1): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): Mish(inplace=True)
)
)
(l_2): Sequential(
(bl_0): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(id_conv): Sequential(
(id_conv): ConvBnAct(
(conv): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): Mish(inplace=True)
)
(bl_1): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): Mish(inplace=True)
)
)
(l_3): Sequential(
(bl_0): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(id_conv): Sequential(
(id_conv): ConvBnAct(
(conv): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): Mish(inplace=True)
)
(bl_1): BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): Mish(inplace=True)
)
)
)
(head): Sequential(
(pool): AdaptiveAvgPool2d(output_size=1)
(flat): Flatten(start_dim=1, end_dim=-1)
(fc): Linear(in_features=512, out_features=1000, bias=True)
)
)</pre>
</details>
## MXResNet50
Now lets make MxResNet50
```python
mc.expansion = 4
mc.layers = [3,4,6,3]
mc.name = "mxresnet50"
```
```python
mc.print_changed_fields()
```
<details open> <summary>output</summary>
<pre>Changed fields:
name: mxresnet50
layers: [3, 4, 6, 3]
act_fn: Mish
expansion: 4
stem_sizes: [3, 32, 64, 64]
make_stem: xresnet_stem
</pre>
</details>
Now we have mxresnet50 constructor.
We can inspect every parts of it.
And after call it we got model.
```python
mc
```
<details open> <summary>output</summary>
<pre>mxresnet50
in_chans: 3, num_classes: 1000
expansion: 4, groups: 1, dw: False, div_groups: None
act_fn: Mish, sa: False, se: False
stem sizes: [3, 32, 64, 64], stride on 0
body sizes [64, 128, 256, 512]
layers: [3, 4, 6, 3]</pre>
</details>
```python
mc.stem.conv_1
```
<details> <summary>output</summary>
<pre>ConvBnAct(
(conv): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)</pre>
</details>
```python
mc.body.l_0.bl_0
```
<details> <summary>output</summary>
<pre>BasicBlock(
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): Mish(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(act_fn): Mish(inplace=True)
)</pre>
</details>
We can get model direct way:
```python
mc = ModelConstructor(
name="MxResNet",
act_fn=Mish,
layers=[3,4,6,3],
expansion=4,
make_stem=xresnet_stem,
stem_sizes=[32,64,64]
)
model = mc()
```
Another way:
```python
model = ModelConstructor.create_model(
name="MxResNet",
act_fn=Mish,
layers=[3,4,6,3],
expansion=4,
make_stem=xresnet_stem,
stem_sizes=[32,64,64]
)
```
## YaResNet
Now lets change Resblock to YaResBlock (Yet another ResNet, former NewResBlock) is in lib from version 0.1.0
```python
from model_constructor.yaresnet import YaBasicBlock
```
```python
mc = ModelConstructor(name="YaResNet")
mc.block = YaBasicBlock
```
Or in one line:
```python
mc = ModelConstructor(name="YaResNet", block=YaBasicBlock)
```
That all. Now we have YaResNet constructor
```python
mc.print_cfg()
```
<details> <summary>output</summary>
<pre>ModelConstructor(
name='YaResNet'
in_chans=3
num_classes=1000
block='YaBasicBlock'
conv_layer='ConvBnAct'
block_sizes=[64, 128, 256, 512]
layers=[2, 2, 2, 2]
norm='BatchNorm2d'
act_fn='ReLU'
expansion=1
groups=1
bn_1st=True
zero_bn=True
stem_sizes=[64]
stem_pool="MaxPool2d {'kernel_size': 3, 'stride': 2, 'padding': 1}"
init_cnn='init_cnn'
make_stem='make_stem'
make_layer='make_layer'
make_body='make_body'
make_head='make_head')
</pre>
</details>
Let see what we have.
```python
mc.body.l_1.bl_0
```
<details> <summary>output</summary>
<pre>YaBasicBlock(
(reduce): ConvBnAct(
(conv): Conv2d(64, 64, kernel_size=(1, 1), stride=(2, 2), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(convs): Sequential(
(conv_0): ConvBnAct(
(conv): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act_fn): ReLU(inplace=True)
)
(conv_1): ConvBnAct(
(conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
(id_conv): ConvBnAct(
(conv): Conv2d(64, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
(merge): ReLU(inplace=True)
)</pre>
</details>
Lets create `xResnet34` like model constructor:
```python
from typing import Callable
from model_constructor.helpers import ModSeq
class YaResnet34(ModelConstructor):
block: type[nn.Module] = YaBasicBlock
layers: list[int] = [3, 4, 6, 3]
make_stem: Callable[[ModelCfg], ModSeq] = xresnet_stem
```
```python
mc = YaResnet34()
mc.print_cfg()
```
<details open> <summary>output</summary>
<pre>YaResnet34(
in_chans=3
num_classes=1000
block='YaBasicBlock'
conv_layer='ConvBnAct'
block_sizes=[64, 128, 256, 512]
layers=[3, 4, 6, 3]
norm='BatchNorm2d'
act_fn='ReLU'
expansion=1
groups=1
bn_1st=True
zero_bn=True
stem_sizes=[64]
stem_pool="MaxPool2d {'kernel_size': 3, 'stride': 2, 'padding': 1}"
init_cnn='init_cnn'
make_stem='xresnet_stem'
make_layer='make_layer'
make_body='make_body'
make_head='make_head')
</pre>
</details>
And `xResnet50` like model can be inherited from `YaResnet34`:
```python
class YaResnet50(YaResnet34):
expansion: int = 4
```
```python
mc = YaResnet50()
mc
```
<details open> <summary>output</summary>
<pre>YaResnet50
in_chans: 3, num_classes: 1000
expansion: 4, groups: 1, dw: False, div_groups: None
act_fn: ReLU, sa: False, se: False
stem sizes: [64], stride on 0
body sizes [64, 128, 256, 512]
layers: [3, 4, 6, 3]</pre>
</details>
Raw data
{
"_id": null,
"home_page": "https://github.com/ayasyrev/model_constructor",
"name": "model-constructor",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "pytorch models",
"author": "Yasyrev Andrei",
"author_email": "a.yasyrev@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/c4/8f/05d789190040948ad7c2300ebef03c50dc710c03988a605deab3ea8cda99/model_constructor-0.4.1.tar.gz",
"platform": null,
"description": "# model_constructor\n\n> Constructor to create pytorch model. \n\n## Install\n\n`pip install model-constructor`\n\nOr install from repo:\n\n`pip install git+https://github.com/ayasyrev/model_constructor.git`\n\n## How to use\n\nFirst import constructor class, then create model constructor object.\n\nNow you can change every part of model.\n\n\n```python\nfrom model_constructor import ModelConstructor\n```\n\n\n```python\nmc = ModelConstructor()\n```\n\nCheck base parameters:\n\n\n```python\nmc\n```\n<details open> <summary>output</summary> \n <pre>ModelConstructor\n in_chans: 3, num_classes: 1000\n expansion: 1, groups: 1, dw: False, div_groups: None\n act_fn: ReLU, sa: False, se: False\n stem sizes: [64], stride on 0\n body sizes [64, 128, 256, 512]\n layers: [2, 2, 2, 2]</pre>\n</details>\n\n\n\nCheck all parameters with `print_cfg` method:\n\n\n```python\nmc.print_cfg()\n```\n<details open> <summary>output</summary> \n <pre>ModelConstructor(\n in_chans=3\n num_classes=1000\n block='BasicBlock'\n conv_layer='ConvBnAct'\n block_sizes=[64, 128, 256, 512]\n layers=[2, 2, 2, 2]\n norm='BatchNorm2d'\n act_fn='ReLU'\n expansion=1\n groups=1\n bn_1st=True\n zero_bn=True\n stem_sizes=[64]\n stem_pool=\"MaxPool2d {'kernel_size': 3, 'stride': 2, 'padding': 1}\"\n init_cnn='init_cnn'\n make_stem='make_stem'\n make_layer='make_layer'\n make_body='make_body'\n make_head='make_head')\n </pre>\n</details>\n\nNow we have model constructor, default setting as resnet18. And we can get model after call it.\n\n\n```python\n\nmodel = mc()\nmodel\n```\n<details> <summary>output</summary> \n <pre>ModelConstructor(\n (stem): Sequential(\n (conv_1): ConvBnAct(\n (conv): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (stem_pool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)\n )\n (body): Sequential(\n (l_0): Sequential(\n (bl_0): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_1): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n )\n (l_1): Sequential(\n (bl_0): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (id_conv): Sequential(\n (id_conv): ConvBnAct(\n (conv): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_1): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n )\n (l_2): Sequential(\n (bl_0): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (id_conv): Sequential(\n (id_conv): ConvBnAct(\n (conv): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_1): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n )\n (l_3): Sequential(\n (bl_0): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (id_conv): Sequential(\n (id_conv): ConvBnAct(\n (conv): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_1): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n )\n )\n (head): Sequential(\n (pool): AdaptiveAvgPool2d(output_size=1)\n (flat): Flatten(start_dim=1, end_dim=-1)\n (fc): Linear(in_features=512, out_features=1000, bias=True)\n )\n )</pre>\n</details>\n\n\n\nIf you want to change model, just change constructor parameters. \nLets create resnet50.\n\n\n```python\nmc.expansion = 4\nmc.layers = [3,4,6,3]\n```\n\nWe can check, what we changed (compare to default constructor).\n\n\n```python\nmc.changed_fields\n```\n<details open> <summary>output</summary> \n <pre>{'layers': [3, 4, 6, 3], 'expansion': 4}</pre>\n</details>\n\n\n\n\n```python\nmc.print_changed_fields()\n```\n<details open> <summary>output</summary> \n <pre>Changed fields:\n layers: [3, 4, 6, 3]\n expansion: 4\n </pre>\n</details>\n\nWe can compare changed with defaults.\n\n\n```python\nmc.print_changed_fields(show_default=True)\n```\n<details open> <summary>output</summary> \n <pre>Changed fields:\n layers: [3, 4, 6, 3] | [2, 2, 2, 2]\n expansion: 4 | 1\n </pre>\n</details>\n\nNow we can look at model parts - stem, body, head. \n\n\n```python\n\nmc.body\n```\n<details> <summary>output</summary> \n <pre>Sequential(\n (l_0): Sequential(\n (bl_0): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_1): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_2): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n )\n (l_1): Sequential(\n (bl_0): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (id_conv): Sequential(\n (id_conv): ConvBnAct(\n (conv): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_1): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_2): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_3): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n )\n (l_2): Sequential(\n (bl_0): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (id_conv): Sequential(\n (id_conv): ConvBnAct(\n (conv): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_1): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_2): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_3): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_4): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_5): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n )\n (l_3): Sequential(\n (bl_0): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (id_conv): Sequential(\n (id_conv): ConvBnAct(\n (conv): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_1): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n (bl_2): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): ReLU(inplace=True)\n )\n )\n )</pre>\n</details>\n\n\n\n## Create constructor from config.\n\nAlternative we can create config first and than create constructor from it. \n\n\n```python\nfrom model_constructor import ModelCfg\n```\n\n\n```python\ncfg = ModelCfg(\n num_classes=10,\n act_fn=nn.Mish,\n)\nprint(cfg)\n```\n<details open> <summary>output</summary> \n <pre>ModelCfg(\n in_chans=3\n num_classes=10\n block='BasicBlock'\n conv_layer='ConvBnAct'\n block_sizes=[64, 128, 256, 512]\n layers=[2, 2, 2, 2]\n norm='BatchNorm2d'\n act_fn='Mish'\n expansion=1\n groups=1\n bn_1st=True\n zero_bn=True\n stem_sizes=[64]\n stem_pool=\"MaxPool2d {'kernel_size': 3, 'stride': 2, 'padding': 1}\")\n </pre>\n</details>\n\nWhen creating config or constructor we can use string annotation for nn.Modules - it useful when creating model from config files.\n\n\n```python\ncfg = ModelCfg(\n num_classes=10,\n act_fn=\"nn.SELU\",\n)\nprint(cfg.act_fn)\n```\n<details open> <summary>output</summary> \n <pre>class 'torch.nn.modules.activation.SELU'</pre>\n</details>\n\nNow we can create constructor from config:\n\n\n```python\nmc = ModelConstructor.from_cfg(cfg)\nmc\n```\n<details open> <summary>output</summary> \n <pre>ModelConstructor\n in_chans: 3, num_classes: 10\n expansion: 1, groups: 1, dw: False, div_groups: None\n act_fn: SELU, sa: <class 'model_constructor.layers.SimpleSelfAttention'>, se: SEModule\n stem sizes: [64], stride on 0\n body sizes [64, 128, 256, 512]\n layers: [2, 2, 2, 2]</pre>\n</details>\n\n\n\n## More modification.\n\nMain purpose of this module - fast and easy modify model.\nAnd here is the link to more modification to beat Imagenette leaderboard with add MaxBlurPool and modification to ResBlock [notebook](https://github.com/ayasyrev/imagenette_experiments/blob/master/ResnetTrick_create_model_fit.ipynb) \n\nBut now lets create model as mxresnet50 from [fastai forums tread](https://forums.fast.ai/t/how-we-beat-the-5-epoch-imagewoof-leaderboard-score-some-new-techniques-to-consider) \n\n\nLets create mxresnet constructor.\n\n\n```python\nmc = ModelConstructor(name='MxResNet')\n```\n\nThen lets modify stem.\n\n\n```python\nfrom model_constructor.xresnet import xresnet_stem\n```\n\n\n```python\nmc.make_stem = xresnet_stem\nmc.stem_sizes = [3,32,64,64]\n```\n\nNow lets change activation function to Mish.\nHere is link to [forum discussion](https://forums.fast.ai/t/meet-mish-new-activation-function-possible-successor-to-relu) \nWe'v got Mish is in model_constructor.activations, but from pytorch 1.9 take it from torch:\n\n\n```python\nfrom torch.nn import Mish\n```\n\n\n```python\nmc.act_fn = Mish\n```\n\n\n```python\nmc\n```\n<details open> <summary>output</summary> \n <pre>MxResNet\n in_chans: 3, num_classes: 1000\n expansion: 1, groups: 1, dw: False, div_groups: None\n act_fn: Mish, sa: False, se: False\n stem sizes: [3, 32, 64, 64], stride on 0\n body sizes [64, 128, 256, 512]\n layers: [2, 2, 2, 2]</pre>\n</details>\n\n\n\n\n```python\nmc.print_changed_fields()\n```\n<details open> <summary>output</summary> \n <pre>Changed fields:\n name: MxResNet\n act_fn: Mish\n stem_sizes: [3, 32, 64, 64]\n make_stem: xresnet_stem\n </pre>\n</details>\n\nHere is model: \n\n\n```python\n\nmc()\n```\n<details> <summary>output</summary> \n <pre>MxResNet(\n act_fn: Mish, stem_sizes: [3, 32, 64, 64], make_stem: xresnet_stem\n (stem): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(3, 3, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (conv_2): ConvBnAct(\n (conv): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (conv_3): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (stem_pool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)\n )\n (body): Sequential(\n (l_0): Sequential(\n (bl_0): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): Mish(inplace=True)\n )\n (bl_1): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): Mish(inplace=True)\n )\n )\n (l_1): Sequential(\n (bl_0): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (id_conv): Sequential(\n (id_conv): ConvBnAct(\n (conv): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): Mish(inplace=True)\n )\n (bl_1): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): Mish(inplace=True)\n )\n )\n (l_2): Sequential(\n (bl_0): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (id_conv): Sequential(\n (id_conv): ConvBnAct(\n (conv): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): Mish(inplace=True)\n )\n (bl_1): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): Mish(inplace=True)\n )\n )\n (l_3): Sequential(\n (bl_0): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (id_conv): Sequential(\n (id_conv): ConvBnAct(\n (conv): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): Mish(inplace=True)\n )\n (bl_1): BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): Mish(inplace=True)\n )\n )\n )\n (head): Sequential(\n (pool): AdaptiveAvgPool2d(output_size=1)\n (flat): Flatten(start_dim=1, end_dim=-1)\n (fc): Linear(in_features=512, out_features=1000, bias=True)\n )\n )</pre>\n</details>\n\n\n\n## MXResNet50\n\nNow lets make MxResNet50\n\n\n```python\nmc.expansion = 4\nmc.layers = [3,4,6,3]\nmc.name = \"mxresnet50\"\n```\n\n\n```python\nmc.print_changed_fields()\n```\n<details open> <summary>output</summary> \n <pre>Changed fields:\n name: mxresnet50\n layers: [3, 4, 6, 3]\n act_fn: Mish\n expansion: 4\n stem_sizes: [3, 32, 64, 64]\n make_stem: xresnet_stem\n </pre>\n</details>\n\nNow we have mxresnet50 constructor. \nWe can inspect every parts of it. \nAnd after call it we got model.\n\n\n```python\nmc\n```\n<details open> <summary>output</summary> \n <pre>mxresnet50\n in_chans: 3, num_classes: 1000\n expansion: 4, groups: 1, dw: False, div_groups: None\n act_fn: Mish, sa: False, se: False\n stem sizes: [3, 32, 64, 64], stride on 0\n body sizes [64, 128, 256, 512]\n layers: [3, 4, 6, 3]</pre>\n</details>\n\n\n\n\n```python\n\nmc.stem.conv_1\n```\n<details> <summary>output</summary> \n <pre>ConvBnAct(\n (conv): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )</pre>\n</details>\n\n\n\n\n```python\n\nmc.body.l_0.bl_0\n```\n<details> <summary>output</summary> \n <pre>BasicBlock(\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): Mish(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (act_fn): Mish(inplace=True)\n )</pre>\n</details>\n\n\n\nWe can get model direct way:\n\n\n```python\nmc = ModelConstructor(\n name=\"MxResNet\",\n act_fn=Mish,\n layers=[3,4,6,3],\n expansion=4,\n make_stem=xresnet_stem,\n stem_sizes=[32,64,64]\n)\nmodel = mc()\n```\n\nAnother way:\n\n\n```python\nmodel = ModelConstructor.create_model(\n name=\"MxResNet\",\n act_fn=Mish,\n layers=[3,4,6,3],\n expansion=4,\n make_stem=xresnet_stem,\n stem_sizes=[32,64,64]\n)\n```\n\n## YaResNet\n\nNow lets change Resblock to YaResBlock (Yet another ResNet, former NewResBlock) is in lib from version 0.1.0\n\n\n```python\nfrom model_constructor.yaresnet import YaBasicBlock\n```\n\n\n```python\nmc = ModelConstructor(name=\"YaResNet\")\nmc.block = YaBasicBlock\n```\n\nOr in one line:\n\n\n```python\nmc = ModelConstructor(name=\"YaResNet\", block=YaBasicBlock)\n```\n\nThat all. Now we have YaResNet constructor\n\n\n```python\n\nmc.print_cfg()\n```\n<details> <summary>output</summary> \n <pre>ModelConstructor(\n name='YaResNet'\n in_chans=3\n num_classes=1000\n block='YaBasicBlock'\n conv_layer='ConvBnAct'\n block_sizes=[64, 128, 256, 512]\n layers=[2, 2, 2, 2]\n norm='BatchNorm2d'\n act_fn='ReLU'\n expansion=1\n groups=1\n bn_1st=True\n zero_bn=True\n stem_sizes=[64]\n stem_pool=\"MaxPool2d {'kernel_size': 3, 'stride': 2, 'padding': 1}\"\n init_cnn='init_cnn'\n make_stem='make_stem'\n make_layer='make_layer'\n make_body='make_body'\n make_head='make_head')\n </pre>\n</details>\n\nLet see what we have.\n\n\n```python\n\nmc.body.l_1.bl_0\n```\n<details> <summary>output</summary> \n <pre>YaBasicBlock(\n (reduce): ConvBnAct(\n (conv): Conv2d(64, 64, kernel_size=(1, 1), stride=(2, 2), bias=False)\n (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (convs): Sequential(\n (conv_0): ConvBnAct(\n (conv): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n (act_fn): ReLU(inplace=True)\n )\n (conv_1): ConvBnAct(\n (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n )\n (id_conv): ConvBnAct(\n (conv): Conv2d(64, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n (bn): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n )\n (merge): ReLU(inplace=True)\n )</pre>\n</details>\n\n\n\nLets create `xResnet34` like model constructor:\n\n\n```python\nfrom typing import Callable\n\nfrom model_constructor.helpers import ModSeq\n\n\nclass YaResnet34(ModelConstructor):\n block: type[nn.Module] = YaBasicBlock\n layers: list[int] = [3, 4, 6, 3]\n make_stem: Callable[[ModelCfg], ModSeq] = xresnet_stem\n```\n\n\n```python\nmc = YaResnet34()\nmc.print_cfg()\n```\n<details open> <summary>output</summary> \n <pre>YaResnet34(\n in_chans=3\n num_classes=1000\n block='YaBasicBlock'\n conv_layer='ConvBnAct'\n block_sizes=[64, 128, 256, 512]\n layers=[3, 4, 6, 3]\n norm='BatchNorm2d'\n act_fn='ReLU'\n expansion=1\n groups=1\n bn_1st=True\n zero_bn=True\n stem_sizes=[64]\n stem_pool=\"MaxPool2d {'kernel_size': 3, 'stride': 2, 'padding': 1}\"\n init_cnn='init_cnn'\n make_stem='xresnet_stem'\n make_layer='make_layer'\n make_body='make_body'\n make_head='make_head')\n </pre>\n</details>\n\nAnd `xResnet50` like model can be inherited from `YaResnet34`:\n\n\n```python\nclass YaResnet50(YaResnet34):\n expansion: int = 4\n```\n\n\n```python\nmc = YaResnet50()\nmc\n```\n<details open> <summary>output</summary> \n <pre>YaResnet50\n in_chans: 3, num_classes: 1000\n expansion: 4, groups: 1, dw: False, div_groups: None\n act_fn: ReLU, sa: False, se: False\n stem sizes: [64], stride on 0\n body sizes [64, 128, 256, 512]\n layers: [3, 4, 6, 3]</pre>\n</details>\n\n\n",
"bugtrack_url": null,
"license": "apache2",
"summary": "Pytorch models constructor.",
"version": "0.4.1",
"project_urls": {
"Homepage": "https://github.com/ayasyrev/model_constructor"
},
"split_keywords": [
"pytorch",
"models"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1402344dbc035666ba7c883cfa03f879b66282216aa0fea3f5224f48f0c6b6f9",
"md5": "51e8446ccd44840502c52bb0c66310fe",
"sha256": "a3ed1fe821066d39ce154b91890d4f0c432d7973de4e70f00aaca2bb59506117"
},
"downloads": -1,
"filename": "model_constructor-0.4.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "51e8446ccd44840502c52bb0c66310fe",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 32071,
"upload_time": "2023-07-18T14:30:43",
"upload_time_iso_8601": "2023-07-18T14:30:43.189597Z",
"url": "https://files.pythonhosted.org/packages/14/02/344dbc035666ba7c883cfa03f879b66282216aa0fea3f5224f48f0c6b6f9/model_constructor-0.4.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c48f05d789190040948ad7c2300ebef03c50dc710c03988a605deab3ea8cda99",
"md5": "b7b0c030918250bd51a7bd2768b497d9",
"sha256": "e75aa7213e340fd8dcf78a1f2424dae2c1aca64d89d8d7d5a37a1a10174f2d52"
},
"downloads": -1,
"filename": "model_constructor-0.4.1.tar.gz",
"has_sig": false,
"md5_digest": "b7b0c030918250bd51a7bd2768b497d9",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 37091,
"upload_time": "2023-07-18T14:30:44",
"upload_time_iso_8601": "2023-07-18T14:30:44.910388Z",
"url": "https://files.pythonhosted.org/packages/c4/8f/05d789190040948ad7c2300ebef03c50dc710c03988a605deab3ea8cda99/model_constructor-0.4.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-07-18 14:30:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ayasyrev",
"github_project": "model_constructor",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "model-constructor"
}