{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# One-demensional DenseNet\nThis is a pytorch implementation of one-demensional DenseNet(https://arxiv.org/abs/1608.06993).  \nThis implementation follows timm model interface i.e. `.forward_features(x)`, `.get_classifier()`, `.reset_classifier()` are supported.","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-10-01T08:33:12.174034Z","iopub.execute_input":"2021-10-01T08:33:12.174588Z","iopub.status.idle":"2021-10-01T08:33:12.180701Z","shell.execute_reply.started":"2021-10-01T08:33:12.174550Z","shell.execute_reply":"2021-10-01T08:33:12.179707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DenseLayer(nn.Module):\n    '''\n    '''\n    def __init__(self, in_channels, growth_rate, bottleneck_size, kernel_size):\n        super().__init__()\n        self.use_bottleneck = bottleneck_size > 0\n        self.num_bottleneck_output_filters = growth_rate * bottleneck_size\n        if self.use_bottleneck:\n            self.bn2 = nn.BatchNorm1d(in_channels)\n            self.act2 = nn.ReLU(inplace=True)\n            self.conv2 = nn.Conv1d(\n                in_channels, \n                self.num_bottleneck_output_filters,\n                kernel_size=1,\n                stride=1)\n        self.bn1 = nn.BatchNorm1d(self.num_bottleneck_output_filters)\n        self.act1 = nn.ReLU(inplace=True)\n        self.conv1 = nn.Conv1d(\n            self.num_bottleneck_output_filters,\n            growth_rate,\n            kernel_size=kernel_size,\n            stride=1, \n            dilation=1, \n            padding=kernel_size // 2)\n\n    def forward(self, x):\n        if self.use_bottleneck:\n            x = self.bn2(x)\n            x = self.act2(x)\n            x = self.conv2(x)\n        x = self.bn1(x)\n        x = self.act1(x)\n        x = self.conv1(x)\n        return x\n\n\nclass DenseBlock(nn.ModuleDict):\n    '''\n    '''\n    def __init__(self, num_layers, in_channels, growth_rate, kernel_size, bottleneck_size):\n        super().__init__()\n        self.num_layers = num_layers\n        for i in range(self.num_layers):\n            self.add_module(f'denselayer{i}', \n                DenseLayer(in_channels + i * growth_rate, \n                           growth_rate, \n                           bottleneck_size, \n                           kernel_size))\n\n    def forward(self, x):\n        layer_outputs = [x]\n        for _, layer in self.items():\n            x = layer(x)\n            layer_outputs.append(x)\n            x = torch.cat(layer_outputs, dim=1)\n        return x\n\n\nclass TransitionBlock(nn.Module):\n    '''\n    '''\n    def __init__(self, in_channels, out_channels):\n        super().__init__()\n        self.bn = nn.BatchNorm1d(in_channels)\n        self.act = nn.ReLU(inplace=True)\n        self.conv = nn.Conv1d(in_channels, out_channels, kernel_size=1, stride=1, dilation=1)\n        self.pool = nn.AvgPool1d(kernel_size=2, stride=2)\n    \n    def forward(self, x):\n        x = self.bn(x)\n        x = self.act(x)\n        x = self.conv(x)\n        x = self.pool(x)\n        return x\n        \n\nclass DenseNet1d(nn.Module):\n\n    def __init__(\n        self, \n        growth_rate: int = 32,\n        block_config: tuple = (6, 12, 24, 16),\n        num_init_features: int = 64,\n        bottleneck_size: int = 4,\n        kernel_size: int = 3, \n        in_channels: int = 3,\n        num_classes: int = 1,\n        reinit: bool = True,\n    ):\n        super().__init__()\n\n        self.features = nn.Sequential(\n            nn.Conv1d(\n                in_channels, num_init_features, \n                kernel_size=7, stride=2, padding=3, dilation=1),\n            nn.BatchNorm1d(num_init_features),\n            nn.ReLU(inplace=True),\n            nn.MaxPool1d(kernel_size=3, stride=2, padding=1),\n        )\n\n        num_features = num_init_features\n        for i, num_layers in enumerate(block_config):\n            block = DenseBlock(\n                num_layers=num_layers,\n                in_channels=num_features,\n                growth_rate=growth_rate,\n                kernel_size=kernel_size,\n                bottleneck_size=bottleneck_size,\n            )\n            self.features.add_module(f'denseblock{i}', block)\n            num_features = num_features + num_layers * growth_rate\n            if i != len(block_config) - 1:\n                trans = TransitionBlock(\n                    in_channels=num_features,\n                    out_channels=num_features // 2)\n                self.features.add_module(f'transition{i}', trans)\n                num_features = num_features // 2\n        \n        self.final_bn = nn.BatchNorm1d(num_features)\n        self.final_act = nn.ReLU(inplace=True)\n        self.final_pool = nn.AdaptiveAvgPool1d(1)\n        self.classifier = nn.Linear(num_features, num_classes)\n        \n        # init\n        if reinit:\n            for m in self.modules():\n                if isinstance(m, nn.Conv1d):\n                    nn.init.kaiming_normal_(m.weight)\n                elif isinstance(m, nn.BatchNorm1d):\n                    nn.init.constant_(m.weight, 1)\n                    nn.init.constant_(m.bias, 0)\n                elif isinstance(m, nn.Linear):\n                    nn.init.constant_(m.bias, 0)\n\n    def forward_features(self, x):\n        out = self.features(x)\n        out = self.final_bn(out)\n        out = self.final_act(out)\n        out = self.final_pool(out)\n        return out\n\n    def forward(self, x):\n        features = self.forward_features(x)\n        features = features.squeeze(-1)\n        out = self.classifier(features)\n        return out\n\n    def reset_classifier(self):\n        self.classifier = nn.Identity()\n    \n    def get_classifier(self):\n        return self.classifier","metadata":{"execution":{"iopub.status.busy":"2021-10-01T08:33:12.182558Z","iopub.execute_input":"2021-10-01T08:33:12.182777Z","iopub.status.idle":"2021-10-01T08:33:12.215851Z","shell.execute_reply.started":"2021-10-01T08:33:12.182751Z","shell.execute_reply":"2021-10-01T08:33:12.215006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def densenet121_1d(in_chans=3, num_classes=1, **kwargs):\n    return DenseNet1d(32, (6, 12, 24, 16), 64, in_channels=in_chans, num_classes=num_classes, **kwargs)\n\n\ndef densenet201_1d(in_chans=3, num_classes=1, **kwargs):\n    return DenseNet1d(32, (6, 12, 48, 32), 64, in_channels=in_chans, num_classes=num_classes, **kwargs)","metadata":{"execution":{"iopub.status.busy":"2021-10-01T08:33:12.217084Z","iopub.execute_input":"2021-10-01T08:33:12.217399Z","iopub.status.idle":"2021-10-01T08:33:12.231430Z","shell.execute_reply.started":"2021-10-01T08:33:12.217292Z","shell.execute_reply":"2021-10-01T08:33:12.230521Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Summary","metadata":{}},{"cell_type":"code","source":"!pip install torchsummary","metadata":{"execution":{"iopub.status.busy":"2021-10-01T08:33:12.232681Z","iopub.execute_input":"2021-10-01T08:33:12.233115Z","iopub.status.idle":"2021-10-01T08:33:12.242501Z","shell.execute_reply.started":"2021-10-01T08:33:12.233085Z","shell.execute_reply":"2021-10-01T08:33:12.241765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torchsummary import summary\n\nsummary(densenet121_1d(), (3, 4096))","metadata":{"execution":{"iopub.status.busy":"2021-10-01T08:33:12.244256Z","iopub.execute_input":"2021-10-01T08:33:12.244647Z","iopub.status.idle":"2021-10-01T08:33:13.045111Z","shell.execute_reply.started":"2021-10-01T08:33:12.244614Z","shell.execute_reply":"2021-10-01T08:33:13.044401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}