1. """dense net in pytorch
    2. """
    3. import torch
    4. import torch.nn as nn
    5. class Bottleneck(nn.Module):
    6. def __init__(self, in_channels, growth_rate):
    7. super().__init__()
    8. inner_channel = 4 * growth_rate
    9. self.bottle_neck = nn.Sequential(
    10. nn.BatchNorm2d(in_channels),
    11. nn.ReLU(inplace=True),
    12. nn.Conv2d(in_channels, inner_channel, kernel_size=1, bias=False),
    13. nn.BatchNorm2d(inner_channel),
    14. nn.ReLU(inplace=True),
    15. nn.Conv2d(inner_channel, growth_rate, kernel_size=3, padding=1, bias=False)
    16. )
    17. def forward(self, x):
    18. return torch.cat([x, self.bottle_neck(x)], 1)
    19. class Transition(nn.Module):
    20. def __init__(self, in_channels, out_channels):
    21. super().__init__()
    22. self.down_sample = nn.Sequential(
    23. nn.BatchNorm2d(in_channels),
    24. nn.Conv2d(in_channels, out_channels, 1, bias=False),
    25. nn.AvgPool2d(2, stride=2)
    26. )
    27. def forward(self, x):
    28. return self.down_sample(x)
    29. class DenseNet(nn.Module):
    30. def __init__(self, block, nblocks, growth_rate=12, reduction=0.5, num_class=100):
    31. super().__init__()
    32. self.growth_rate = growth_rate
    33. #扩张率设为32
    34. inner_channels = 2 * growth_rate
    35. #将通道数扩张为64
    36. self.conv1 = nn.Conv2d(3, inner_channels, kernel_size=3, padding=1, bias=False)
    37. self.features = nn.Sequential()
    38. for index in range(len(nblocks) - 1):
    39. self.features.add_module("dense_block_layer_{}".format(index), self._make_dense_layers(block, inner_channels, nblocks[index]))
    40. inner_channels += growth_rate * nblocks[index]
    41. out_channels = int(reduction * inner_channels) # int() will automatic floor the value
    42. self.features.add_module("transition_layer_{}".format(index), Transition(inner_channels, out_channels))
    43. inner_channels = out_channels
    44. self.features.add_module("dense_block{}".format(len(nblocks) - 1), self._make_dense_layers(block, inner_channels, nblocks[len(nblocks)-1]))
    45. inner_channels += growth_rate * nblocks[len(nblocks) - 1]
    46. self.features.add_module('bn', nn.BatchNorm2d(inner_channels))
    47. self.features.add_module('relu', nn.ReLU(inplace=True))
    48. self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
    49. self.linear = nn.Linear(inner_channels, num_class)
    50. def forward(self, x):
    51. output = self.conv1(x)#64, 32, 32
    52. output = self.features(output)
    53. output = self.avgpool(output)
    54. output = output.view(output.size()[0], -1)
    55. output = self.linear(output)
    56. return output
    57. def _make_dense_layers(self, block, in_channels, nblocks):
    58. dense_block = nn.Sequential()
    59. for index in range(nblocks):
    60. dense_block.add_module('bottle_neck_layer_{}'.format(index), block(in_channels, self.growth_rate))
    61. in_channels += self.growth_rate
    62. return dense_block
    63. def densenet121():
    64. return DenseNet(Bottleneck, [6,12,24,16], growth_rate=32)
    65. def densenet169():
    66. return DenseNet(Bottleneck, [6,12,32,32], growth_rate=32)
    67. def densenet201():
    68. return DenseNet(Bottleneck, [6,12,48,32], growth_rate=32)
    69. def densenet161():
    70. return DenseNet(Bottleneck, [6,12,36,24], growth_rate=48)