| import torch |
| import torch.nn as nn |
|
|
|
|
| |
| |
|
|
| class ResidualBlock(nn.Module): |
| def __init__(self, in_ch, out_ch, stride=1): |
| super().__init__() |
| self.conv1 = nn.Conv2d(in_ch, out_ch, 3, stride, 1, bias=False) |
| self.bn1 = nn.BatchNorm2d(out_ch) |
| self.relu = nn.ReLU(True) |
| self.conv2 = nn.Conv2d(out_ch, out_ch, 3, 1, 1, bias=False) |
| self.bn2 = nn.BatchNorm2d(out_ch) |
| self.shortcut = nn.Identity() |
| if stride != 1 or in_ch != out_ch: |
| self.shortcut = nn.Sequential( |
| nn.Conv2d(in_ch, out_ch, 1, stride, bias=False), |
| nn.BatchNorm2d(out_ch) |
| ) |
| def forward(self, x): |
| out = self.relu(self.bn1(self.conv1(x))) |
| out = self.bn2(self.conv2(out)) |
| out += self.shortcut(x) |
| return self.relu(out) |
| |
| class MyModel(nn.Module): |
| def __init__(self, num_classes: int = 1000, dropout: float = 0.7) -> None: |
| super().__init__() |
| self.Backbone = nn.Sequential( |
| ResidualBlock(3, 64, 1), |
| ResidualBlock(64, 128, 2), |
| ResidualBlock(128, 256, 2), |
| ResidualBlock(256, 512, 2), |
| nn.AdaptiveAvgPool2d((1,1)) |
| ) |
| self.Classifier = nn.Sequential( |
| nn.Flatten(), |
| nn.Linear(512, 512), |
| nn.BatchNorm1d(512), |
| nn.ReLU(True), |
| nn.Dropout(dropout), |
| |
| nn.Linear(512,192), |
| nn.BatchNorm1d(192), |
| nn.ReLU(True), |
| nn.Dropout(dropout), |
| |
| nn.Linear(192, num_classes) |
| ) |
| |
| def forward(self, x): |
| return self.Classifier(self.Backbone(x)) |
| |
|
|
|
|
| |
| |
| |
| import pytest |
|
|
|
|
| @pytest.fixture(scope="session") |
| def data_loaders(): |
| from .data import get_data_loaders |
|
|
| return get_data_loaders(batch_size=2) |
|
|
|
|
| def test_model_construction(data_loaders): |
|
|
| model = MyModel(num_classes=23, dropout=0.3) |
|
|
| dataiter = iter(data_loaders["train"]) |
| images, labels = next(dataiter) |
|
|
| out = model(images) |
|
|
| assert isinstance( |
| out, torch.Tensor |
| ), "The output of the .forward method should be a Tensor of size ([batch_size], [n_classes])" |
|
|
| assert out.shape == torch.Size( |
| [2, 23] |
| ), f"Expected an output tensor of size (2, 23), got {out.shape}" |
|
|