官方文档:nn.Module

    继承 nn.Module 类,重写 __init__()forward() 两个函数

    1. import torch.nn as nn
    2. import torch.nn.functional as F
    3. class Model(nn.Module):
    4. def __init__(self):
    5. super().__init__()
    6. self.conv1 = nn.Conv2d(1, 20, 5)
    7. self.conv2 = nn.Conv2d(20, 20, 5)
    8. def forward(self, x):
    9. x = F.relu(self.conv1(x))
    10. return F.relu(self.conv2(x))

    搭建网络时可以用 [nn.Sequential](https://pytorch.org/docs/stable/generated/torch.nn.Sequential.html?highlight=sequential#torch.nn.Sequential) 来组合不同的层,使得代码更简洁(后续 forward 函数里可以少些很多行)

    1. model = nn.Sequential(
    2. nn.Conv2d(1,20,5),
    3. nn.ReLU(),
    4. nn.Conv2d(20,64,5),
    5. nn.ReLU()
    6. )
    7. model = nn.Sequential(OrderedDict([
    8. ('conv1', nn.Conv2d(1,20,5)),
    9. ('relu1', nn.ReLU()),
    10. ('conv2', nn.Conv2d(20,64,5)),
    11. ('relu2', nn.ReLU())
    12. ]))

    可以通过 print 打印出网络结构的详细信息

    1. vgg16 = torchvision.models.vgg16(pretrained=True)
    2. print(vgg16)

    输出:

    1. VGG(
    2. (features): Sequential(
    3. (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    4. (1): ReLU(inplace=True)
    5. (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    6. (3): ReLU(inplace=True)
    7. (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    8. (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    9. (6): ReLU(inplace=True)
    10. (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    11. (8): ReLU(inplace=True)
    12. (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    13. (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    14. (11): ReLU(inplace=True)
    15. (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    16. (13): ReLU(inplace=True)
    17. (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    18. (15): ReLU(inplace=True)
    19. (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    20. (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    21. (18): ReLU(inplace=True)
    22. (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    23. (20): ReLU(inplace=True)
    24. (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    25. (22): ReLU(inplace=True)
    26. (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    27. (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    28. (25): ReLU(inplace=True)
    29. (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    30. (27): ReLU(inplace=True)
    31. (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    32. (29): ReLU(inplace=True)
    33. (30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    34. )
    35. (avgpool): AdaptiveAvgPool2d(output_size=(7, 7))
    36. (classifier): Sequential(
    37. (0): Linear(in_features=25088, out_features=4096, bias=True)
    38. (1): ReLU(inplace=True)
    39. (2): Dropout(p=0.5, inplace=False)
    40. (3): Linear(in_features=4096, out_features=4096, bias=True)
    41. (4): ReLU(inplace=True)
    42. (5): Dropout(p=0.5, inplace=False)
    43. (6): Linear(in_features=4096, out_features=1000, bias=True)
    44. )
    45. )

    在 vgg 网络的 classifier 部分的最后增加一层全连接层:

    1. vgg16.classifier.add_module('add_linear', nn.Linear(1000, 10))
    2. print(vgg16)

    输出:

    1. VGG(
    2. (features): Sequential(
    3. (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    4. (1): ReLU(inplace=True)
    5. (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    6. (3): ReLU(inplace=True)
    7. (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    8. (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    9. (6): ReLU(inplace=True)
    10. (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    11. (8): ReLU(inplace=True)
    12. (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    13. (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    14. (11): ReLU(inplace=True)
    15. (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    16. (13): ReLU(inplace=True)
    17. (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    18. (15): ReLU(inplace=True)
    19. (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    20. (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    21. (18): ReLU(inplace=True)
    22. (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    23. (20): ReLU(inplace=True)
    24. (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    25. (22): ReLU(inplace=True)
    26. (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    27. (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    28. (25): ReLU(inplace=True)
    29. (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    30. (27): ReLU(inplace=True)
    31. (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    32. (29): ReLU(inplace=True)
    33. (30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    34. )
    35. (avgpool): AdaptiveAvgPool2d(output_size=(7, 7))
    36. (classifier): Sequential(
    37. (0): Linear(in_features=25088, out_features=4096, bias=True)
    38. (1): ReLU(inplace=True)
    39. (2): Dropout(p=0.5, inplace=False)
    40. (3): Linear(in_features=4096, out_features=4096, bias=True)
    41. (4): ReLU(inplace=True)
    42. (5): Dropout(p=0.5, inplace=False)
    43. (6): Linear(in_features=4096, out_features=1000, bias=True)
    44. (add_linear): Linear(in_features=1000, out_features=10, bias=True)
    45. )
    46. )

    更改 vgg 网络某一层的结构:

    1. vgg16 = torchvision.models.vgg16(pretrained=True)
    2. vgg16.classifier[6] = nn.Linear(4096, 10)
    3. print(vgg16)

    输出:

    1. VGG(
    2. (features): Sequential(
    3. (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    4. (1): ReLU(inplace=True)
    5. (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    6. (3): ReLU(inplace=True)
    7. (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    8. (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    9. (6): ReLU(inplace=True)
    10. (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    11. (8): ReLU(inplace=True)
    12. (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    13. (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    14. (11): ReLU(inplace=True)
    15. (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    16. (13): ReLU(inplace=True)
    17. (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    18. (15): ReLU(inplace=True)
    19. (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    20. (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    21. (18): ReLU(inplace=True)
    22. (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    23. (20): ReLU(inplace=True)
    24. (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    25. (22): ReLU(inplace=True)
    26. (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    27. (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    28. (25): ReLU(inplace=True)
    29. (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    30. (27): ReLU(inplace=True)
    31. (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    32. (29): ReLU(inplace=True)
    33. (30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    34. )
    35. (avgpool): AdaptiveAvgPool2d(output_size=(7, 7))
    36. (classifier): Sequential(
    37. (0): Linear(in_features=25088, out_features=4096, bias=True)
    38. (1): ReLU(inplace=True)
    39. (2): Dropout(p=0.5, inplace=False)
    40. (3): Linear(in_features=4096, out_features=4096, bias=True)
    41. (4): ReLU(inplace=True)
    42. (5): Dropout(p=0.5, inplace=False)
    43. (6): Linear(in_features=4096, out_features=10, bias=True)
    44. )
    45. )
    46. 1