= torch_randn(16, 1, 32, 64)
x
= DnCNN(2,1)
tst test_eq(tst(x).shape, x.shape)
Networks
UNet
create_custom_unet
create_custom_unet (resnet_version, n_in=1, n_out=1, img_size=(128, 128), pretrained=True, cut=4)
Create a U-Net model with a ResNet backbone.
Returns: - U-Net model with the specified ResNet backbone.
Type | Default | Details | |
---|---|---|---|
resnet_version | Choose a ResNet model between: ‘resnet18’, ‘resnet34’, ‘resnet50’, ‘resnet101’, and ‘resnet152’. | ||
n_in | int | 1 | Number of input channels, default is 1 (e.g., grayscale). |
n_out | int | 1 | Number of output channels. |
img_size | tuple | (128, 128) | Tuple for the input image size, default is (128, 128). |
pretrained | bool | True | If True, use a pretrained ResNet backbone. |
cut | int | 4 | The cut point for the ResNet model, default is 4. |
Denoising CNN
DnCNN
DnCNN (spatial_dims=2, in_channels=1, out_channels=1, num_of_layers=9, features=64, kernel_size=3)
A Deep Neural Network for Image Denoising (DnCNN) model.
Type | Default | Details | |
---|---|---|---|
spatial_dims | int | 2 | Number of spatial dimensions |
in_channels | int | 1 | Number of input channels |
out_channels | int | 1 | Number of output channels |
num_of_layers | int | 9 | Number of convolutional layers |
features | int | 64 | Number of feature maps |
kernel_size | int | 3 | Size of the convolution kernel |
DeepLab v3+
DeepLabv3
is a semantic segmentation architecture that handles the problem of segmenting objects at multiple scales. It uses the Atroys Spatial Pyramid Pooling module, and introduces various updates with respect to other versions.
Config
The DeeplabConfig
class has been created to centralize all settings and hyperparameters in one place. It uses two main functions: Get_padding and interpolate. Get_padding is a function that calculates the amount of padding needed for a convolution operation to get the desired output size. Interpolate is a function that allows the resizing of a tensor using interpolation.
interpolate
interpolate (x:torch.Tensor, size:Union[List[int],Tuple[int,...]], dims:int)
Type | Details | |
---|---|---|
x | Tensor | Input tensor |
size | Union | Size of the output tensor |
dims | int | Number of spatial dimensions |
Returns | Tensor | Output tensor |
get_padding
get_padding (kernel_size:int, dilation:int)
Type | Details | |
---|---|---|
kernel_size | int | Size of the convolution kernel |
dilation | int | Dilation rate |
Returns | int | Padding size |
DeeplabConfig
DeeplabConfig (dimensions:int, in_channels:int, out_channels:int, backbone:str='xception', pretrained:bool=False, middle_flow_blocks:int=16, aspp_dilations:List[int]=<factory>, entry_block3_stride:int=2, middle_block_dilation:int=1, exit_block_dilations:Tuple[int,int]=(1, 2))
Blocks
SeparableConv
is a class that carries out a type of convolution operation that splits the traditional convolution into two parts: depthwise convolution (a convolution filter for each channel independently), and pointwise convolution (combines the outputs of the depthwise convolution).
SeparableConv
SeparableConv (config:__main__.DeeplabConfig, inplanes:int, planes:int, kernel_size:int=3, stride:int=1, dilation:int=1, bias:bool=False, norm:Optional[str]=None)
Base class for all neural network modules.
Your models should also subclass this class.
Modules can also contain other Modules, allowing to nest them in a tree structure. You can assign the submodules as regular attributes::
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))
Submodules assigned in this way will be registered, and will have their parameters converted too when you call :meth:to
, etc.
.. note:: As per the example above, an __init__()
call to the parent class must be made before assignment on the child.
Type | Default | Details | |
---|---|---|---|
config | DeeplabConfig | Configuration for the Deeplab model | |
inplanes | int | Number of input channels | |
planes | int | Number of output channels | |
kernel_size | int | 3 | Size of the convolution kernel |
stride | int | 1 | Stride for the convolution |
dilation | int | 1 | Dilation rate for the convolution |
bias | bool | False | If True, add a bias term |
norm | Optional | None | Type of normalization layer |
Block
is a class that combines multiple separable convolutional layers and residual connections.
class Block(nn.Module):
def __init__(self, config: DeeplabConfig, # Configuration for the Deeplab model
int, # Number of input channels
inplanes: int, # Number of output channels
planes: int, # Number of convolutional layers
reps: int = 1, # Stride for the convolution
stride: int = 1, # Dilation rate for the convolution
dilation: bool = True, # If True, start with a ReLU activation
start_with_relu: bool = True, # If True, increase the number of channels in the first convolution
grow_first: bool = False, # If True, add a convolution layer at the end
is_last:
):super().__init__()
if planes != inplanes or stride != 1:
self.skip = Convolution(config.dimensions, inplanes, planes, kernel_size=1, bias=False,
=stride, norm=Norm.BATCH)
strideselse:
self.skip = None
self.relu = nn.ReLU(inplace=True)
= []
rep
= inplanes
filters if grow_first:
self.relu)
rep.append(3, stride=1, dilation=dilation, norm=Norm.BATCH))
rep.append(SeparableConv(config, inplanes, planes, = planes
filters
for _ in range(reps - 1):
self.relu)
rep.append(3, stride=1, dilation=dilation, norm=Norm.BATCH))
rep.append(SeparableConv(config, filters, filters,
if not grow_first:
self.relu)
rep.append(3, stride=1, dilation=dilation, norm=Norm.BATCH))
rep.append(SeparableConv(config, inplanes, planes,
if not start_with_relu:
= rep[1:]
rep
if stride != 1:
3, stride=2))
rep.append(SeparableConv(config, planes, planes,
if stride == 1 and is_last:
3, stride=1))
rep.append(SeparableConv(config, planes, planes,
self.rep = nn.Sequential(*rep)
def forward(self, inp: torch_Tensor) -> torch_Tensor:
= self.rep(inp)
x if self.skip is not None:
= self.skip(inp)
skip else:
= inp
skip += skip
x return x
Aligned Xception
The Xception
class defines the Xception Neural Network used in DeepLab.
Xception
Xception (config:__main__.DeeplabConfig)
Base class for all neural network modules.
Your models should also subclass this class.
Modules can also contain other Modules, allowing to nest them in a tree structure. You can assign the submodules as regular attributes::
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))
Submodules assigned in this way will be registered, and will have their parameters converted too when you call :meth:to
, etc.
.. note:: As per the example above, an __init__()
call to the parent class must be made before assignment on the child.
Type | Details | |
---|---|---|
config | DeeplabConfig | Configuration for the Deeplab model |
ASPP
The class ASPP_module
to compute the Atroys Spatial Pyramid Pooling method and create the convolution that uses it.
ASPP_module
ASPP_module (config:__main__.DeeplabConfig, inplanes:int, planes:int, dilation:int)
Base class for all neural network modules.
Your models should also subclass this class.
Modules can also contain other Modules, allowing to nest them in a tree structure. You can assign the submodules as regular attributes::
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))
Submodules assigned in this way will be registered, and will have their parameters converted too when you call :meth:to
, etc.
.. note:: As per the example above, an __init__()
call to the parent class must be made before assignment on the child.
Type | Details | |
---|---|---|
config | DeeplabConfig | Configuration for the Deeplab model |
inplanes | int | Number of input channels |
planes | int | Number of output channels |
dilation | int | Dilation rate for the convolution |
DeepLab V3
The Deeplab
class combines the different modules to make the DeepLab V3 architecture.
Deeplab
Deeplab (config:__main__.DeeplabConfig)
Base class for all neural network modules.
Your models should also subclass this class.
Modules can also contain other Modules, allowing to nest them in a tree structure. You can assign the submodules as regular attributes::
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))
Submodules assigned in this way will be registered, and will have their parameters converted too when you call :meth:to
, etc.
.. note:: As per the example above, an __init__()
call to the parent class must be made before assignment on the child.
:ivar training: Boolean represents whether this module is in training or evaluation mode. :vartype training: bool
Example
# Load a pre-trained ResNet backbone
= ResNetFeatures('resnet10', pretrained=False, in_channels=1, spatial_dims=3)
resnet_backbone
# Forward pass through the backbone to get the output before the final classifier
= torch_randn(1, 1, 64, 224, 224) # Example input size; adjust based on your needs
dummy_input = resnet_backbone(dummy_input)
output
# The shape of 'output' will give you the number of channels at this stage in the backbone
print("Output channels:", output[-1].shape[1])
Output channels: 512
# For 2D images
= DeeplabConfig(
config_2d =2,
dimensions=3, # For RGB images
in_channels=4,
out_channels="xception", # or whatever backbone you're using
backbone=[1, 6, 12, 18]
aspp_dilations
)= Deeplab(config_2d)
model_2d
# For 3D images
= DeeplabConfig(
config_3d =3,
dimensions=1, # For single-channel 3D medical images
in_channels=4,
out_channels=16,
middle_flow_blocks=[1, 6, 12, 18]
aspp_dilations
)= Deeplab(config_3d) model_3d
from torch import no_grad as torch_no_grad
def test_deeplab(config, input_shape, expected_output_shape):
0) # For reproducibility
set_determinism(
= Deeplab(config)
model eval() # Set the model to evaluation mode
model.
# Generate random input tensor
= torch_randn(*input_shape)
x
# Forward pass
with torch_no_grad():
= model(x)
output
# Check output shape
assert output.shape == expected_output_shape, f"Expected shape {expected_output_shape}, but got {output.shape}"
print(f"Test passed for {config.dimensions}D model with backbone {config.backbone}")
print(f"Input shape: {input_shape}")
print(f"Output shape: {output.shape}")
print("---")
# Test 2D model
= DeeplabConfig(
config_2d =2,
dimensions=3,
in_channels=4,
out_channels="xception",
backbone=[1, 6, 12, 18]
aspp_dilations
)1, 3, 64, 64), (1, 4, 64, 64))
test_deeplab(config_2d, (
# Test 2D model with ResNet50 backbone
= DeeplabConfig(
config_2d_resnet =2,
dimensions=3,
in_channels=4,
out_channels="resnet50",
backbone=[1, 6, 12, 18]
aspp_dilations
)1, 3, 64, 64), (1, 4, 64, 64))
test_deeplab(config_2d_resnet, (
# Test 3D model
= DeeplabConfig(
config_3d =3,
dimensions=1,
in_channels=4,
out_channels="xception",
backbone=[1, 6, 12, 18]
aspp_dilations
)1, 1, 64, 64, 64), (1, 4, 64, 64, 64))
test_deeplab(config_3d, (
# Test 3D model with ResNet10 backbone
= DeeplabConfig(
config_3d_resnet =3,
dimensions=1,
in_channels=4,
out_channels="resnet10",
backbone=[1, 6, 12, 18]
aspp_dilations
)1, 1, 64, 64, 64), (1, 4, 64, 64, 64))
test_deeplab(config_3d_resnet, (
print("All tests passed successfully!")
Test passed for 2D model with backbone xception
Input shape: (1, 3, 64, 64)
Output shape: torch.Size([1, 4, 64, 64])
---
Test passed for 2D model with backbone resnet50
Input shape: (1, 3, 64, 64)
Output shape: torch.Size([1, 4, 64, 64])
---
Test passed for 3D model with backbone xception
Input shape: (1, 1, 64, 64, 64)
Output shape: torch.Size([1, 4, 64, 64, 64])
---
Test passed for 3D model with backbone resnet10
Input shape: (1, 1, 64, 64, 64)
Output shape: torch.Size([1, 4, 64, 64, 64])
---
All tests passed successfully!
UMamba
MambaLayer
MambaLayer (dim, d_state=16, d_conv=4, expand=2)
A custom neural network layer that incorporates the Mamba block from the Mamba model, along with layer normalization and optional mixed precision handling.
Type | Default | Details | |
---|---|---|---|
dim | Dimension of the input tensor | ||
d_state | int | 16 | Expansion factor for the state in the Mamba block |
d_conv | int | 4 | Width of the local convolution in the Mamba block |
expand | int | 2 | Factor by which to expand the dimensions in the Mamba block |
UMamba
UMamba (spatial_dims:int, in_channels:int, out_channels:int, kernel_size:Sequence[Union[Sequence[int],int]], strides:Sequence[Union[Sequence[int],int]], upsample_kernel_size:Sequence[Union[Sequence[int],int]], filters:Optional[Sequence[int]]=None, dropout:Union[Tuple,str,float,NoneType]=None, norm_name:Union[Tuple,str]=('INSTANCE', {'affine': True}), act_name:Union[Tuple,str]=('leakyrelu', {'inplace': True, 'negative_slope': 0.01}), deep_supervision:bool=False, deep_supr_num:int=1, res_block:bool=False, trans_bias:bool=False)
A custom subclass of DynUNet that integrates the Mamba layer into the model’s bottleneck.
This class inherits from DynUNet
and adds a specific bottleneck structure containing a convolution block followed by a MambaLayer.
Example
= torch_randn(16, 1, 32, 64)
x
= DynUNet(2,1,1,[3,3,3],[1,1,1],[1,1])
tst print(tst(x).shape)
test_eq(tst(x).shape, x.shape)
torch.Size([16, 1, 32, 64])
= torch_randn(16, 1, 32, 64).cuda()
x
= UMamba(2,1,1,[3,3,3],[1,1,1],[1,1]).cuda()
tst print(tst(x).shape)
test_eq(tst(x).shape, x.shape)
torch.Size([16, 1, 32, 64])