# resnet

Python API: `luxonis_train.nodes.blocks.resnet`

The residual and bottleneck blocks of ResNet.

## Classes

### GenericResidualBlock

Residual block that adds a shortcut to the output of any block.

The shortcut is `torch.nn.Identity` when `stride` is `1` and `in_channels` equals `expansion * hidden_channels`. Otherwise it is a
`1x1`
[ConvBlock](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/blocks/blocks.md)
with `stride`, a batch norm, and no activation. This projection maps the input to `expansion * hidden_channels` channels.
[ResNetBlock](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/blocks/resnet.md)
and
[ResNetBottleneck](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/blocks/resnet.md)
build on this class.

#### Methods

##### init

```python
def __init__(in_channels: int, hidden_channels: int, stride: int, expansion: int, final_relu: bool, block: nn.Module):
```

Store the branch and build the shortcut and the activation.

Parameters

 * `in_channels` (`int`): The number of input channels.
 * `hidden_channels` (`int`): The base width. The output has `expansion * hidden_channels` channels.
 * `stride` (`int`): The stride of the shortcut projection. The branch must reduce the size by the same factor.
 * `expansion` (`int`): The factor from `hidden_channels` to the number of output channels.
 * `final_relu` (`bool`): Whether a ReLU follows the sum.
 * `block` (`nn.Module`): The residual branch. Its output must have the shape of the shortcut output.

##### forward

```python
def forward(x: Tensor) -> Tensor:
```

Add the shortcut to the output of the branch.

The addition runs in place on the output of `block`.

Parameters

 * `x` (`Tensor`): The input of shape `[B, in_channels, H, W]`.

Returns

 * `Tensor`: The sum `block(x) + shortcut(x)`, after the ReLU when the constructor got `final_relu=True`. The shape is `[B,
   expansion * hidden_channels, H', W']`, where `stride` sets `H'` and `W'`.

#### Attributes

##### block

The residual branch.

##### final_relu

`torch.nn.ReLU` or `torch.nn.Identity`.

##### shortcut

The identity or the `1x1` projection.

### ResNetBlock

Basic ResNet block with two `3x3` convolutions.

The residual branch is a `3x3` convolution with `stride`, a batch norm, a ReLU, a `3x3` convolution, a batch norm, and
[DropPath](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/blocks/blocks.md).
The convolutions have no bias. The shortcut follows the rules of
[GenericResidualBlock](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/blocks/resnet.md).

> **Example**
> ```pycon
>>> import torch
>>> from torch import nn
>>> from luxonis_train.nodes.blocks import ResNetBlock
>>> isinstance(ResNetBlock(8, 8).shortcut, nn.Identity)
True
>>> block = ResNetBlock(8, 16, stride=2)
>>> block(torch.zeros(1, 8, 8, 8)).shape
torch.Size([1, 16, 4, 4])
```

#### Methods

##### init

```python
def __init__(in_channels: int, hidden_channels: int, stride: int = 1, expansion: int = 1, final_relu: bool = True, droppath_prob:
float = 0.0):
```

Build the residual branch of the block.

Parameters

 * `in_channels` (`int`): The number of input channels.
 * `hidden_channels` (`int`): The number of output channels.
 * `stride` (`int`): The stride of the first convolution and of the shortcut.
 * `expansion` (`int`): The factor of the shortcut channels. The branch always gives `hidden_channels` channels, so only `1` works. With a value above `1`, `forward` raises `RuntimeError`.
 * `final_relu` (`bool`): Whether a ReLU follows the sum.
 * `droppath_prob` (`float`): The drop probability of the [DropPath](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/blocks/blocks.md) at the end of the branch.

### ResNetBottleneck

ResNet bottleneck block of three convolutions.

The residual branch reduces the input to `hidden_channels` with a `1x1` convolution. A `3x3` convolution with `stride` follows. A last `1x1` convolution expands the result to `expansion * hidden_channels` channels. Each convolution has a batch norm and no bias. ReLUs follow the first two batch norms, and [DropPath](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/blocks/blocks.md) ends the branch. The shortcut follows the rules of [GenericResidualBlock](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/blocks/resnet.md).

> **Example**
> ```pycon
>>> import torch
>>> from luxonis_train.nodes.blocks import ResNetBottleneck
>>> block = ResNetBottleneck(16, 8, stride=2)
>>> block(torch.zeros(1, 16, 8, 8)).shape
torch.Size([1, 32, 4, 4])
```

#### Methods

##### init

```python
def __init__(in_channels: int, hidden_channels: int, stride: int = 1, expansion: int = 4, final_relu: bool = True, droppath_prob: float = 0.0):
```

Build the residual branch of the block.

Parameters

 * `in_channels` (`int`): The number of input channels.
 * `hidden_channels` (`int`): The number of channels of the `1x1` reduction and of the `3x3` convolution.
 * `stride` (`int`): The stride of the `3x3` convolution and of the shortcut.
 * `expansion` (`int`): The output has `expansion * hidden_channels` channels.
 * `final_relu` (`bool`): Whether a ReLU follows the sum.
 * `droppath_prob` (`float`): The drop probability of the
   [DropPath](https://docs.luxonis.com/software-v3/ai-inference/model-source/training/luxonis-train/luxonis-train-api-reference/nodes/blocks/blocks.md)
   at the end of the branch.
