77import torch
88import torch .nn as nn
99from typing import Union , Any
10- from .base import BaseBlock , WeightInitializer
10+ from .base import BaseConvBlock , WeightInitializer
1111
1212
13- class ResidualBlock (BaseBlock ):
13+ class ResidualBlock (BaseConvBlock ):
1414 """Residual convolutional block with batch normalization and ReLU.
1515
1616 This block implements a standard residual connection with two convolutional
@@ -27,9 +27,6 @@ class ResidualBlock(BaseBlock):
2727 Size of the convolving kernel.
2828 stride : int or tuple of int, default=1
2929 Stride of the convolution.
30- padding : int, tuple of int, or str, default='auto'
31- Padding added to all four sides of the input. If 'auto', padding is
32- calculated to maintain spatial dimensions when stride=1.
3330 bias : bool, default=True
3431 If True, adds a learnable bias to the output.
3532 use_batch_norm : bool, default=True
@@ -78,7 +75,6 @@ def __init__(
7875 out_channels : int ,
7976 kernel_size : Union [int , tuple [int , int ]] = 3 ,
8077 stride : Union [int , tuple [int , int ]] = 1 ,
81- padding : Union [int , tuple [int , int ], str ] = 'auto' ,
8278 bias : bool = True ,
8379 use_batch_norm : bool = True ,
8480 activation : str = 'relu' ,
@@ -96,8 +92,6 @@ def __init__(
9692 Size of the convolving kernel.
9793 stride : int or tuple of int, default=1
9894 Stride of the convolution.
99- padding : int, tuple of int, or str, default='auto'
100- Padding specification.
10195 bias : bool, default=True
10296 Whether to use bias in convolutions.
10397 use_batch_norm : bool, default=True
@@ -110,9 +104,20 @@ def __init__(
110104 # Initialize base class
111105 super ().__init__ (in_channels , out_channels , kernel_size , bias )
112106
107+ if isinstance (stride , int ) and stride < 1 :
108+ raise ValueError (f"Stride must be a positive integer or tuple, "
109+ f"got { stride } " )
110+ if isinstance (stride , tuple ) and any (s < 1 for s in stride ):
111+ raise ValueError (f"Stride must be a positive integer or tuple, "
112+ f"got { stride } " )
113+ if (isinstance (stride , float ) or isinstance (stride , tuple )
114+ and any (isinstance (s , float ) for s in stride )):
115+ raise TypeError (f"Stride must be an integer or tuple, "
116+ f"got float { stride } " )
117+
113118 # Normalize stride and padding
114119 self .stride = self ._normalize_stride (stride )
115- self .padding = self ._calculate_padding (self .kernel_size , padding )
120+ self .padding = self ._calculate_padding (self .kernel_size , "auto" )
116121 self .use_batch_norm = use_batch_norm
117122 self .activation_name = activation
118123 self .init_method = init_method
@@ -239,8 +244,9 @@ def forward(self, x: torch.Tensor) -> torch.Tensor:
239244 Returns
240245 -------
241246 torch.Tensor
242- Output tensor with shape (batch_size, out_channels, height', width')
243- where height' and width' depend on stride.
247+ Output tensor with shape
248+ (batch_size, out_channels, height', width') where height'
249+ and 'width' depend on stride.
244250 """
245251 # Store input for residual connection
246252 residual = x
@@ -350,4 +356,4 @@ def get_output_shape(
350356
351357 # Update channels
352358 batch_size , _ , height , width = temp_shape
353- return ( batch_size , self .out_channels , height , width )
359+ return batch_size , self .out_channels , height , width
0 commit comments