Spaces:
Build error
Build error
| """ | |
| MLP (Multi-Layer Perceptron) baseline model. | |
| Flattens input image and passes through dense layers. | |
| Purpose: weak baseline to compare against CNNs and transformers. | |
| """ | |
| import torch | |
| import torch.nn as nn | |
| class CattleMLP(nn.Module): | |
| """ | |
| Simple MLP classifier for image classification. | |
| Flattens the image into a vector and passes through FC layers. | |
| """ | |
| def __init__( | |
| self, | |
| num_classes: int = 26, | |
| img_size: int = 224, | |
| channels: int = 3, | |
| hidden_layers: list[int] = None, | |
| dropout: float = 0.3, | |
| batch_norm: bool = True, | |
| ): | |
| super().__init__() | |
| if hidden_layers is None: | |
| hidden_layers = [1024, 512, 256] | |
| self.flatten = nn.Flatten() | |
| input_dim = channels * img_size * img_size | |
| layers = [] | |
| prev_dim = input_dim | |
| for hidden_dim in hidden_layers: | |
| layers.append(nn.Linear(prev_dim, hidden_dim)) | |
| if batch_norm: | |
| layers.append(nn.BatchNorm1d(hidden_dim)) | |
| layers.append(nn.ReLU(inplace=True)) | |
| layers.append(nn.Dropout(p=dropout)) | |
| prev_dim = hidden_dim | |
| # Final classifier | |
| layers.append(nn.Linear(prev_dim, num_classes)) | |
| self.classifier = nn.Sequential(*layers) | |
| # Initialize weights | |
| self._init_weights() | |
| def _init_weights(self): | |
| for m in self.modules(): | |
| if isinstance(m, nn.Linear): | |
| nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') | |
| if m.bias is not None: | |
| nn.init.constant_(m.bias, 0) | |
| elif isinstance(m, nn.BatchNorm1d): | |
| nn.init.constant_(m.weight, 1) | |
| nn.init.constant_(m.bias, 0) | |
| def forward(self, x: torch.Tensor) -> torch.Tensor: | |
| x = self.flatten(x) | |
| x = self.classifier(x) | |
| return x | |
| def from_config(config: dict) -> 'CattleMLP': | |
| """Create model from config dict.""" | |
| arch = config.get('model', {}).get('architecture', {}) | |
| return CattleMLP( | |
| num_classes=config.get('num_classes', 26), | |
| img_size=config.get('image', {}).get('size', 224), | |
| channels=config.get('image', {}).get('channels', 3), | |
| hidden_layers=arch.get('hidden_layers', [1024, 512, 256]), | |
| dropout=arch.get('dropout', 0.3), | |
| batch_norm=arch.get('batch_norm', True), | |
| ) | |