-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement base Model and Head classes #17
Conversation
… docstring to make_centered_bboxes, fixed find_global_peaks_rough; added crop_bboxes
…leupsamplingblock, encoder, decoder; added unet
Rate Limit ExceededYou have exceeded the limit for the number of files or commits that can be reviewed per hour. Please wait 29 minutes and 59 seconds before requesting another review. To re-trigger a review, convert this PR to a draft and then mark it as ready for review again. Alternatively, you can push a new commit to this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 2
Files selected for processing (1)
- sleap_nn/architectures/heads.py (1 hunks)
Additional comments (Suppressed): 1
sleap_nn/architectures/heads.py (1)
- 498-512: The
make_head
method in theClassVectorsHead
class uses a softmax activation function at the end. This is fine if you are dealing with exclusive classes, but if your problem allows for multi-label classification (an instance can belong to more than one class), then you should use a sigmoid activation function instead. Please verify whether the classes are mutually exclusive or not.Also, there seems to be no dropout layers added in between the fully connected layers. Dropout layers can help prevent overfitting by randomly setting a fraction rate of input units to 0 at each update during training time. Consider adding dropout layers if overfitting is a concern.
for i in range(self.num_fc_layers): if i == 0: module_list.append(nn.Linear(x_in, self.num_fc_units)) else: module_list.append(nn.Linear(self.num_fc_units, self.num_fc_units)) module_list.append(get_act_fn("relu")) + module_list.append(nn.Dropout(0.5)) # Add dropout layer with dropout rate of 0.5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 2
Files selected for processing (6)
- .gitignore (1 hunks)
- sleap_nn/architectures/encoder_decoder.py (4 hunks)
- sleap_nn/architectures/model.py (1 hunks)
- sleap_nn/architectures/unet.py (3 hunks)
- tests/architectures/test_model.py (1 hunks)
- tests/architectures/test_unet.py (3 hunks)
Files skipped from review due to trivial changes (2)
- .gitignore
- sleap_nn/architectures/model.py
Additional comments (Suppressed): 11
sleap_nn/architectures/unet.py (3)
3-11: The import of
math
andtyping
modules has been removed. Ensure that this does not affect any other parts of the code that might be using these imports.43-52: The initialization of several attributes (
in_channels
,kernel_size
,filters
,filters_rate
,down_blocks
,up_blocks
,convs_per_block
) has been added to theUNet
class. This is a good practice as it makes the code more readable and maintainable by clearly defining what attributes are expected in an instance of the class.82-93: A new attribute
current_strides
and a new propertyoutput_channels
have been added to theUNet
class. Thecurrent_strides
attribute seems to be derived from theDecoder
instance, while theoutput_channels
property is calculated based on thefilters
,filters_rate
,down_blocks
, andup_blocks
attributes. Make sure that these new additions are used appropriately throughout the rest of the codebase.sleap_nn/architectures/encoder_decoder.py (4)
28-38: The import statement for
get_act_fn
has been moved fromsleap_nn.architectures.common
tosleap_nn.architectures.utils
. Ensure that this function exists in the new module and all references to it have been updated accordingly.430-437: The attribute
self.current_strides
has been added. This seems to be a list that will store the stride values at each level of the decoder. Make sure that this attribute is used correctly throughout the codebase.458-463: The current stride value is now being stored in
self.current_strides
after each iteration. This change appears to be part of the addition of thecurrent_strides
attribute. Ensure that this list is updated correctly and used as intended.469-479: The return type of the
forward
method has changed from a single tensor to a list of tensors. This could potentially break any code that expects the output of this method to be a single tensor. Verify that all calls to this method have been updated to handle the new return type.tests/architectures/test_unet.py (4)
- 6-6: The import path for
get_children_layers
has been changed. Ensure that the function is still correctly imported from the new location.- from sleap_nn.architectures.common import get_children_layers + from sleap_nn.architectures.utils import get_children_layers
59-60: The variable name for the UNet instance has been changed from
model
tounet
. Make sure this change is consistent throughout the codebase and does not affect any other parts of the code that reference this variable.65-66: The output of the UNet model is now a list, and the final output shape is checked on the last element of this list. This is a significant change from the previous version where the output was directly a tensor. Ensure that all parts of the code that use the output of the UNet model are updated to handle this change.
- assert y.shape == (1, 13, 192, 192) + assert type(y) is list + assert y[-1].shape == (1, 64, 192, 192)
- 68-75: A new Conv2d layer is added after the UNet model, and its output shape is checked. This seems to be a new addition to the test case. If this Conv2d layer is part of the actual model architecture, ensure that it is properly integrated into the model and not just in the test case.
@talmo I set up a hacky way (above) to select the correct head based on output stride. I was thinking of creating some IntermediateFeature-like class, but that might not be necessary...? Maybe I could just return a dictionary with the output features and the current stride in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 2
Files selected for processing (4)
- sleap_nn/architectures/encoder_decoder.py (3 hunks)
- sleap_nn/architectures/model.py (1 hunks)
- sleap_nn/architectures/unet.py (3 hunks)
- tests/architectures/test_unet.py (3 hunks)
Additional comments (Suppressed): 12
sleap_nn/architectures/model.py (2)
1-6: The introduction of a higher-level wrapper around
nn.Module
is a good design choice. It allows for easy querying of the model configuration without instantiating the model itself, which can be beneficial for debugging and understanding the model structure.55-97: Similar to
get_backbone
, theget_head
function provides a clean way to instantiate different head models based on a string identifier. This function supports a variety of head types, which is good for flexibility and extensibility.sleap_nn/architectures/encoder_decoder.py (3)
28-38: The import statement for
get_act_fn
has been moved fromsleap_nn.architectures.common
tosleap_nn.architectures.utils
. Ensure that the function is correctly implemented in the new module and all references to it have been updated.430-437: The addition of
self.current_strides = []
suggests that you're now tracking the strides at each block level. This could be useful for debugging or understanding the model's structure, but ensure it doesn't introduce unnecessary overhead if not used elsewhere.458-482: The
forward
method signature and return type have changed. It now returns a tuple containing a list of output tensors and the current strides. Make sure all calls to this method are updated to handle the new return type. Also, verify that the change in the return type does not break any functionality where the output of this method is used.- def forward(self, x: torch.Tensor, features: List[torch.Tensor]) -> torch.Tensor: + def forward( + self, x: torch.Tensor, features: List[torch.Tensor] + ) -> Tuple[List[torch.Tensor], List]:tests/architectures/test_unet.py (3)
1-6: The import statement for
get_children_layers
has been updated to reflect its new location in thesleap_nn.architectures.utils
module. Ensure that this function has been correctly moved and that all other references to it have been updated accordingly.56-78: The test for the final output shape of the UNet model has been modified. Previously, the test was checking if the output shape of the model was
(1, 13, 192, 192)
. Now, it checks if the output is a list, and if the shape of the last element of the list is(1, 64, 192, 192)
. It also checks ifcurrent_strides
is a list and its length is 4. Then, it applies a convolutional layer with kernel size 1 to the last output of the UNet model and checks if the output shape is(1, 13, 192, 192)
. Make sure these changes are consistent with the modifications made to the UNet model.88-94: The assignment of the evaluation mode to the encoder instance has been changed from
_ = enc.eval()
toenc.eval()
. This change is fine as the return value ofeval()
(which is the module itself) is not used anywhere else in the code.sleap_nn/architectures/unet.py (4)
3-12: The import of
math
andtorch.nn.functional as F
has been removed, and theTuple
type hint has been added. Ensure that these changes do not affect other parts of the code that may rely on these imports.44-54: The initialization of several attributes (
in_channels
,kernel_size
,filters
,filters_rate
,down_blocks
,up_blocks
,convs_per_block
) has been added to theUNet
class. Make sure these are used appropriately in the rest of the class methods.83-92: A new property
output_channels
has been added to calculate and return the output channels of the UNet. This seems to be a useful addition for understanding the structure of the network.94-106: The
forward
method now returns a tuple containing the output tensor and a list of current strides from the decoder, instead of just the output tensor. Ensure all calls to this method have been updated to handle the new return type.- def forward(self, x: torch.Tensor) -> torch.Tensor: + def forward(self, x: torch.Tensor) -> Tuple[List[torch.Tensor], List]:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 0
Files selected for processing (1)
- sleap_nn/architectures/model.py (1 hunks)
Additional comments (Suppressed): 4
sleap_nn/architectures/model.py (4)
1-6: The introduction of a higher-level wrapper around
nn.Module
is a good design choice. It provides an abstraction layer that simplifies the process of defining and configuring models.27-52: The
get_backbone
function is well implemented. It checks if the provided backbone name is supported, raises an error if not, and returns an instance of the requested backbone model. However, consider adding more backbones in the future to provide more flexibility.55-97: The
get_head
function follows the same pattern asget_backbone
, which maintains consistency. It's also extensible for additional head types in the future.100-145: The
Model
class is well structured. The__init__
method initializes the backbone and heads based on the provided configurations. Thefrom_config
class method allows creating a model from a configuration dictionary, which can be useful when loading models from saved configurations. Theforward
method correctly performs a forward pass through the model, applying each head to the appropriate feature map from the backbone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 0
Files selected for processing (4)
- sleap_nn/architectures/encoder_decoder.py (3 hunks)
- sleap_nn/architectures/model.py (1 hunks)
- sleap_nn/architectures/unet.py (3 hunks)
- tests/architectures/test_unet.py (3 hunks)
Additional comments (Suppressed): 11
tests/architectures/test_unet.py (3)
1-9: The import statement for
get_children_layers
has been updated to reflect its new location insleap_nn.architectures.utils
. Ensure that the function has been correctly moved to this new module and that all other references to this function in the codebase have been updated accordingly.56-80: The output of the UNet model is now a dictionary containing the final output tensor and a list of current strides from the decoder. This is a significant change from the previous version, where the model directly returned the output tensor. Ensure that all parts of the codebase that use the UNet model have been updated to handle this new output format. Also, verify that the strides are being correctly calculated and returned by the model.
90-96: The
eval
method of theEncoder
instance is now being called without assigning its return value to a variable. This is a minor change from the previous version, where the return value was assigned to_
. This change is acceptable as theeval
method does not return any value and is used for setting the model to evaluation mode.sleap_nn/architectures/model.py (1)
- 1-154: The new hunks in
sleap_nn/architectures/model.py
introduce aModel
class that serves as a higher-level wrapper aroundtorch.nn.Module
. This class holds the configuration parameters required to construct the actual model and allows for easy querying of the model configuration. It initializes the backbone and head based on the providedmodel_config
and performs a forward pass through the model.The
get_backbone
andget_head
functions are used to instantiate the appropriate backbone and head modules based on the provided names and configurations. These functions raise aKeyError
if the provided name is not one of the supported values.The
Model
class has afrom_config
class method that creates a model instance from a configuration dictionary. Theforward
method performs a forward pass through the model, applying the backbone and each head layer to the input tensor and returning a dictionary of outputs.The code appears to be logically sound and well-structured, with clear separation of concerns and good use of Python's object-oriented features. The use of a dictionary to map names to classes in the
get_backbone
andget_head
functions is a good approach for handling multiple types of backbones and heads.However, there are some commented-out lines of code (lines 130-136) that should be removed if they are not needed. Leaving commented-out code in the codebase can lead to confusion and clutter.
- # self.heads = nn.ModuleList() - # self.heads_metadata = [] - # for head_config in head_configs: - # head = get_head(head_config.head_type, head_config.head_config) - # self.heads_metadata.append((head.output_stride, head.name)) - # head = head.make_head(x_in=in_channels) - # self.heads.append(head)sleap_nn/architectures/unet.py (4)
2-12: The import of
math
andF
(functional) fromtorch.nn
has been removed. Ensure that these are not used elsewhere in the code or in the functions that are not shown in the hunks. If they are used, they should be imported back.44-54: The initialization of the
UNet
class has been updated to include more attributes. This is a good practice as it makes the class more flexible and customizable. However, ensure that these new attributes are used correctly throughout the class and that their default values (if any) are set appropriately.83-92: The
output_channels
property has been added to theUNet
class. This property calculates the number of output channels based on thefilters
,filters_rate
,down_blocks
, andup_blocks
attributes. This is a good addition as it provides a way to easily get the number of output channels without having to calculate it manually each time.94-105: The
forward
method has been updated to return a tuple containing the output tensor and a list of current strides from the decoder. This is a significant change and could potentially break existing code that calls this method and expects a single output tensor. Ensure that all calls to this method throughout the codebase have been updated to handle the new return type.sleap_nn/architectures/encoder_decoder.py (3)
28-38: The import statement for
get_act_fn
has been moved fromsleap_nn.architectures.common
tosleap_nn.architectures.utils
. Ensure that the function is correctly defined in the new module and that all references to it have been updated.430-437: The
current_strides
attribute has been added to theDecoder
class. This attribute is used to keep track of the current stride at each level of the decoder. This is a good practice as it allows for dynamic tracking of the stride, which can be useful for understanding the scale of the features at each level.458-485: The
forward
method of theDecoder
class has been updated to return a dictionary containing the output tensors and the current strides. This change provides more information about the state of the decoder and can be useful for debugging and understanding the model's behavior. However, ensure that all calls to this method throughout the codebase have been updated to handle the new return type.- def forward(self, x: torch.Tensor, features: List[torch.Tensor]) -> torch.Tensor: + def forward( + self, x: torch.Tensor, features: List[torch.Tensor] + ) -> Tuple[List[torch.Tensor], List]:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 1
Files selected for processing (1)
- sleap_nn/architectures/utils.py (1 hunks)
Additional comments (Suppressed): 1
sleap_nn/architectures/utils.py (1)
- 6-42: The
get_act_fn
function is well implemented. It provides a clear and concise way to get an instance of a PyTorch activation function module based on a string input. The error handling for unsupported activation functions is also appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 3
Files selected for processing (1)
- sleap_nn/architectures/model.py (1 hunks)
Additional comments (Suppressed): 1
sleap_nn/architectures/model.py (1)
- 108-130: The
Model
class is initialized with a list of head configurations but it's not clear if all heads are compatible with the backbone. Consider adding a compatibility check between the backbone and the heads to avoid potential runtime errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 1
Files ignored due to filter (1)
- pyproject.toml
Files selected for processing (2)
- sleap_nn/data/pipelines.py (3 hunks)
- tests/data/test_pipelines.py (3 hunks)
Additional comments (Suppressed): 6
tests/data/test_pipelines.py (2)
42-77: The augmentation configuration has been restructured into two categories:
intensity
andgeometric
. Ensure that the code that uses this configuration has been updated to handle the new structure. Also, a new keyanchor_ind
has been added to thepreprocessing
section. Verify its usage and impact on the system.96-131: Similar to the previous comment, the augmentation configuration has been restructured and a new key
anchor_ind
has been added. Ensure that the code that uses this configuration has been updated to handle the new structure and the new key.sleap_nn/data/pipelines.py (4)
- 6-6: The import statement for
DictConfig
has been changed. Ensure that the new import path is correct and does not break the code.- from omegaconf.dictconfig import DictConfig + from omegaconf.omegaconf import DictConfig
49-51: The
InstanceCentroidFinder
instantiation now includes an additional parameteranchor_ind
. Ensure that this parameter is correctly defined inself.data_config.preprocessing
and that it is correctly used within theInstanceCentroidFinder
class.44-47: The
KorniaAugmenter
instantiation now includes a specific subset of augmentations (intensity
). Ensure that this subset is correctly defined inself.data_config.augmentation_config.augmentations
and that it is correctly used within theKorniaAugmenter
class.62-65: The
KorniaAugmenter
instantiation now includes a specific subset of augmentations (geometric
). Ensure that this subset is correctly defined inself.data_config.augmentation_config.augmentations
and that it is correctly used within theKorniaAugmenter
class.
Summary by CodeRabbit
Model
module that serves as a higher-level wrapper aroundnn.Module
, simplifying the process of defining and using a trainable model.UNet
class with additional attributes and a newoutput_channels
property for better control over the output channels.InstanceCentroidFinder
andKorniaAugmenter
instantiations for more precise data augmentation.Model
class and updated existing tests for theUNet
class, ensuring the reliability of these modules.augmentation_config
dictionary in the test function for better organization of intensity and geometric augmentations.