三、深度学习分类模型的代码讲解 持续更新 2023年MathorCup大数据竞赛A题基于计算机视觉的坑洼道路检测和识别 思路论文代码

本文用于手把手教学如何使用深度学习处理分类问题。

在前面的文章中我们明确了最关键的是将该问题看做(转换)成一个深度学习处理图片分类的问题。
那么只有了解如何使用深度学习处理一个基本的分类问题,再根据本文将其适配到本文的问题上即可。

当然后续还需要更多的调优以及针对该问题对模型和处理步骤做出一些调整才能达到更高的准确率以及完成论文。

结果展示

先展示训练结果,后续再讲解。主要按照数据的流动处理过程来讲解。
运行结果:可以看到示例代码在没有经过任何调优的情况下已经可以达到91%的准确率了:

(yolov5) PS C:\Users\Admin\Desktop\tmp\2023mathcup赛题解析\DLNetwork> python .\train.py --model googlenet
Downloading: "https://download.pytorch.org/models/googlenet-1378be20.pth" to C:\Users\Admin/.cache\torch\hub\checkpoints\googlenet-1378be20.pth
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 49.7M/49.7M [00:07<00:00, 6.54MB/s]
GoogLeNet(
  (conv1): BasicConv2d(
    (conv): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
    (bn): BatchNorm2d(64, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
  )
  (maxpool1): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=True)
  (conv2): BasicConv2d(
    (conv): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
    (bn): BatchNorm2d(64, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
  )
  (conv3): BasicConv2d(
    (conv): Conv2d(64, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
    (bn): BatchNorm2d(192, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
  )
  (maxpool2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=True)
  (inception3a): Inception(
    (branch1): BasicConv2d(
      (conv): Conv2d(192, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
      (bn): BatchNorm2d(64, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
    )
    (branch2): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(192, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(96, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(96, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch3): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(192, 16, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(16, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(16, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(32, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch4): Sequential(
      (0): MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=True)
      (1): BasicConv2d(
        (conv): Conv2d(192, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(32, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
  (inception3b): Inception(
    (branch1): BasicConv2d(
      (conv): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
      (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
    )
    (branch2): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(128, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(192, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch3): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(256, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(32, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(32, 96, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(96, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch4): Sequential(
      (0): MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=True)
      (1): BasicConv2d(
        (conv): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(64, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
  (maxpool3): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=True)
  (inception4a): Inception(
    (branch1): BasicConv2d(
      (conv): Conv2d(480, 192, kernel_size=(1, 1), stride=(1, 1), bias=False)
      (bn): BatchNorm2d(192, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
    )
    (branch2): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(480, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(96, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(96, 208, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(208, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch3): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(480, 16, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(16, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(16, 48, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(48, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch4): Sequential(
      (0): MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=True)
      (1): BasicConv2d(
        (conv): Conv2d(480, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(64, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
  (inception4b): Inception(
    (branch1): BasicConv2d(
      (conv): Conv2d(512, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)
      (bn): BatchNorm2d(160, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
    )
    (branch2): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(512, 112, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(112, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(112, 224, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(224, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch3): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(512, 24, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(24, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(24, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(64, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch4): Sequential(
      (0): MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=True)
      (1): BasicConv2d(
        (conv): Conv2d(512, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(64, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
  (inception4c): Inception(
    (branch1): BasicConv2d(
      (conv): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
      (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
    )
    (branch2): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(256, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch3): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(512, 24, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(24, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(24, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(64, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch4): Sequential(
      (0): MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=True)
      (1): BasicConv2d(
        (conv): Conv2d(512, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(64, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
  (inception4d): Inception(
    (branch1): BasicConv2d(
      (conv): Conv2d(512, 112, kernel_size=(1, 1), stride=(1, 1), bias=False)
      (bn): BatchNorm2d(112, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
    )
    (branch2): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(512, 144, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(144, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(144, 288, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(288, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch3): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(512, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(32, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(64, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch4): Sequential(
      (0): MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=True)
      (1): BasicConv2d(
        (conv): Conv2d(512, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(64, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
  (inception4e): Inception(
    (branch1): BasicConv2d(
      (conv): Conv2d(528, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
      (bn): BatchNorm2d(256, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
    )
    (branch2): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(528, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(160, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(160, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(320, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch3): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(528, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(32, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(32, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch4): Sequential(
      (0): MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=True)
      (1): BasicConv2d(
        (conv): Conv2d(528, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
  (maxpool4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=True)
  (inception5a): Inception(
    (branch1): BasicConv2d(
      (conv): Conv2d(832, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
      (bn): BatchNorm2d(256, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
    )
    (branch2): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(832, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(160, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(160, 320, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(320, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch3): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(832, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(32, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(32, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch4): Sequential(
      (0): MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=True)
      (1): BasicConv2d(
        (conv): Conv2d(832, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
  (inception5b): Inception(
    (branch1): BasicConv2d(
      (conv): Conv2d(832, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)
      (bn): BatchNorm2d(384, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
    )
    (branch2): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(832, 192, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(192, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(384, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch3): Sequential(
      (0): BasicConv2d(
        (conv): Conv2d(832, 48, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(48, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicConv2d(
        (conv): Conv2d(48, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (branch4): Sequential(
      (0): MaxPool2d(kernel_size=3, stride=1, padding=1, dilation=1, ceil_mode=True)
      (1): BasicConv2d(
        (conv): Conv2d(832, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(128, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
  (aux1): None
  (aux2): None
  (avgpool): AdaptiveAvgPool2d(output_size=(1, 1))
  (dropout): Dropout(p=0.2, inplace=False)
  (fc): Linear(in_features=1024, out_features=10, bias=True)
)
{'model': <function googlenet at 0x000001BB25E26DC8>, 'pretrained': True, 'epoch': 5, 'num_class': 10, 'save_path': 'params/googlenet.pth', 'input_size': (112, 112), 
'batch_size': (8, 1000), 'lr': 0.0001}
[1,     1] train_loss: 0.094  test_accuracy: 0.079
[1,   101] train_loss: 4.629  test_accuracy: 0.476
[1,   201] train_loss: 2.699  test_accuracy: 0.559
[1,   301] train_loss: 2.126  test_accuracy: 0.636
[1,   401] train_loss: 1.917  test_accuracy: 0.701
[1,   501] train_loss: 1.661  test_accuracy: 0.723
[1,   601] train_loss: 1.515  test_accuracy: 0.721
[1,   701] train_loss: 1.531  test_accuracy: 0.750
[1,   801] train_loss: 1.309  test_accuracy: 0.767
[1,   901] train_loss: 1.238  test_accuracy: 0.762
[1,  1001] train_loss: 1.244  test_accuracy: 0.780
[1,  1101] train_loss: 0.886  test_accuracy: 0.800
[1,  1201] train_loss: 0.974  test_accuracy: 0.786
[1,  1301] train_loss: 0.987  test_accuracy: 0.810
[1,  1401] train_loss: 0.993  test_accuracy: 0.812
[1,  1501] train_loss: 0.898  test_accuracy: 0.815
[1,  1601] train_loss: 0.882  test_accuracy: 0.825
[1,  1701] train_loss: 0.803  test_accuracy: 0.832
[1,  1801] train_loss: 0.804  test_accuracy: 0.818
[1,  1901] train_loss: 0.813  test_accuracy: 0.847
[1,  2001] train_loss: 0.843  test_accuracy: 0.849
[1,  2101] train_loss: 0.845  test_accuracy: 0.852
[1,  2201] train_loss: 0.815  test_accuracy: 0.836
[1,  2301] train_loss: 0.828  test_accuracy: 0.852
[1,  2401] train_loss: 0.792  test_accuracy: 0.842
[1,  2501] train_loss: 0.763  test_accuracy: 0.853
[1,  2601] train_loss: 0.764  test_accuracy: 0.857
[1,  2701] train_loss: 0.619  test_accuracy: 0.860
[1,  2801] train_loss: 0.754  test_accuracy: 0.850
[1,  2901] train_loss: 0.818  test_accuracy: 0.862
[1,  3001] train_loss: 0.613  test_accuracy: 0.857
[1,  3101] train_loss: 0.700  test_accuracy: 0.848
[1,  3201] train_loss: 0.708  test_accuracy: 0.871
[1,  3301] train_loss: 0.621  test_accuracy: 0.852
[1,  3401] train_loss: 0.727  test_accuracy: 0.854
[1,  3501] train_loss: 0.644  test_accuracy: 0.866
[1,  3601] train_loss: 0.596  test_accuracy: 0.866
[1,  3701] train_loss: 0.583  test_accuracy: 0.875
[1,  3801] train_loss: 0.621  test_accuracy: 0.850
[1,  3901] train_loss: 0.684  test_accuracy: 0.862
[1,  4001] train_loss: 0.598  test_accuracy: 0.868
[1,  4101] train_loss: 0.667  test_accuracy: 0.870
[1,  4201] train_loss: 0.768  test_accuracy: 0.866
[1,  4301] train_loss: 0.616  test_accuracy: 0.874
[1,  4401] train_loss: 0.743  test_accuracy: 0.858
[1,  4501] train_loss: 0.583  test_accuracy: 0.854
[1,  4601] train_loss: 0.539  test_accuracy: 0.865
[1,  4701] train_loss: 0.631  test_accuracy: 0.879
[1,  4801] train_loss: 0.542  test_accuracy: 0.874
[1,  4901] train_loss: 0.484  test_accuracy: 0.886
[1,  5001] train_loss: 0.515  test_accuracy: 0.864
[1,  5101] train_loss: 0.553  test_accuracy: 0.877
[1,  5201] train_loss: 0.628  test_accuracy: 0.876
[1,  5301] train_loss: 0.534  test_accuracy: 0.886
[1,  5401] train_loss: 0.616  test_accuracy: 0.865
[1,  5501] train_loss: 0.673  test_accuracy: 0.883
[1,  5601] train_loss: 0.517  test_accuracy: 0.890
[1,  5701] train_loss: 0.541  test_accuracy: 0.873
[1,  5801] train_loss: 0.565  test_accuracy: 0.862
[1,  5901] train_loss: 0.557  test_accuracy: 0.897
[1,  6001] train_loss: 0.518  test_accuracy: 0.884
[1,  6101] train_loss: 0.469  test_accuracy: 0.881
[1,  6201] train_loss: 0.515  test_accuracy: 0.877
[2,     1] train_loss: 0.000  test_accuracy: 0.875
[2,   101] train_loss: 0.515  test_accuracy: 0.897
[2,   201] train_loss: 0.553  test_accuracy: 0.886
[2,   301] train_loss: 0.447  test_accuracy: 0.904
[2,   401] train_loss: 0.449  test_accuracy: 0.892
[2,   501] train_loss: 0.495  test_accuracy: 0.896
[2,   601] train_loss: 0.427  test_accuracy: 0.887
[2,   701] train_loss: 0.538  test_accuracy: 0.876
[2,   801] train_loss: 0.470  test_accuracy: 0.898
[2,   901] train_loss: 0.429  test_accuracy: 0.887
[2,  1001] train_loss: 0.498  test_accuracy: 0.894
[2,  1101] train_loss: 0.428  test_accuracy: 0.893
[2,  1201] train_loss: 0.465  test_accuracy: 0.899
[2,  1301] train_loss: 0.419  test_accuracy: 0.904
[2,  1401] train_loss: 0.399  test_accuracy: 0.891
[2,  1501] train_loss: 0.369  test_accuracy: 0.896
[2,  1601] train_loss: 0.412  test_accuracy: 0.896
[2,  1701] train_loss: 0.400  test_accuracy: 0.914
[2,  1801] train_loss: 0.410  test_accuracy: 0.895
[2,  1901] train_loss: 0.405  test_accuracy: 0.888
[2,  2001] train_loss: 0.417  test_accuracy: 0.900
[2,  2101] train_loss: 0.405  test_accuracy: 0.898
[2,  2201] train_loss: 0.362  test_accuracy: 0.899
[2,  2301] train_loss: 0.362  test_accuracy: 0.893
[2,  2401] train_loss: 0.446  test_accuracy: 0.876
[2,  2501] train_loss: 0.389  test_accuracy: 0.903
[2,  2601] train_loss: 0.365  test_accuracy: 0.906
[2,  2701] train_loss: 0.361  test_accuracy: 0.895
[2,  2801] train_loss: 0.423  test_accuracy: 0.910

代码片段1:

实现了在 PyTorch 中构建 GoogLeNet(Inception v1)模型的函数。下面对这个函数的实现进行讲解:

  • 函数定义:定义了一个名为googlenet的函数,它接受三个参数:saveFeature、cfg和progress,其中cfg是一个字典,包含了网络的配置信息,progress表示是否显示下载进度条。
  • 预训练参数:从参数中获取pretrained(是否加载预训练模型)和num_class(分类数),并根据pretrained的值和kwargs(关键字参数)设置网络的一些属性。
  • 加载预训练模型:当pretrained为True时,创建一个 GoogLeNet 模型,并从 PyTorch 官方网站上下载预训练权重。如果num_class不等于 1000,则需要重新初始化最后的全连接层和两个辅助网络的全连接层。
  • 返回模型:返回 GoogLeNet 模型。

总体来说,这段代码实现了一个可以加载预训练权重的 GoogLeNet(Inception v1)模型,并且可以根据配置信息进行修改。

def googlenet(saveFeature = False, cfg = None,progress: bool = True, **kwargs: Any) -> "GoogLeNet":
    r"""GoogLeNet (Inception v1) model architecture from
    `"Going Deeper with Convolutions" <http://arxiv.org/abs/1409.4842>`_.
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
        progress (bool): If True, displays a progress bar of the download to stderr
        aux_logits (bool): If True, adds two auxiliary branches that can improve training.
            Default: *False* when pretrained is True otherwise *True*
        transform_input (bool): If True, preprocesses the input according to the method with which it
            was trained on ImageNet. Default: *False*
    """
    pretrained = cfg["pretrained"]
    num_class = cfg["num_class"]
    if pretrained:
        if 'transform_input' not in kwargs:
            kwargs['transform_input'] = True
        if 'aux_logits' not in kwargs:
            kwargs['aux_logits'] = False
        if kwargs['aux_logits']:
            warnings.warn('auxiliary heads in the pretrained googlenet model are NOT pretrained, '
                          'so make sure to train them')
        original_aux_logits = kwargs['aux_logits']
        kwargs['aux_logits'] = True
        kwargs['init_weights'] = False
        kwargs["num_classes"] = num_class
        model = GoogLeNet(**kwargs)
        state_dict = load_state_dict_from_url(model_urls['googlenet'],
                                              progress=progress)
        if num_class != 1000:
            weight = torch.Tensor(random.rand(num_class, 1024))
            bias = torch.Tensor(random.rand(num_class))
            state_dict["fc.weight"] = weight
            state_dict["fc.bias"] = bias
            state_dict["aux1.fc2.weight"] = weight
            state_dict["aux1.fc2.bias"] = bias
            state_dict["aux2.fc2.weight"] = weight
            state_dict["aux2.fc2.bias"] = bias


        model.load_state_dict(state_dict)
        if not original_aux_logits:
            model.aux_logits = False
            model.aux1 = None  # type: ignore[assignment]
            model.aux2 = None  # type: ignore[assignment]
        return model

    return GoogLeNet(**kwargs)

GoogleNet主模型:这是一个基于PyTorch的GoogLeNet模型的实现代码。GoogLeNet是Google在2014年提出的一种卷积神经网络模型,主要应用于ImageNet图像分类竞赛。
这个类实现了GoogLeNet模型的前向传播过程,包含多个卷积层、池化层和Inception模块。其中Inception模块是GoogLeNet模型的核心组成部分,它使用多个不同大小的卷积核并行处理输入特征图,然后将它们的输出在通道维度上进行拼接,从而扩展和深化了特征表示能力。
具体来说,在这个类中:

  • __init__方法定义了模型结构,包括多个卷积层、池化层和Inception模块,以及是否需要进行辅助分类(即auxiliary classification)和输入变换(transform input)等设置。
  • _initialize_weights方法用于模型参数的初始化,采用截断正态分布和常数初始化。
  • _transform_input方法用于对输入数据进行预处理,即归一化和标准化处理。
  • _forward方法是模型的前向传播过程,其中包括多个卷积层、池化层和Inception模块的串联,以及辅助分类器的添加和dropout操作等。
  • forward方法是对外的接口,用于调用模型的前向传播过程,并根据是否需要辅助分类返回相应的输出。

这个类还包括一些辅助方法,如__constants__、eager_outputs等,主要用于定义常量和辅助返回值的处理。

代码片段2

class GoogLeNet(nn.Module):
    __constants__ = ['aux_logits', 'transform_input']

    def __init__(
        self,
        num_classes: int = 1000,
        aux_logits: bool = True,
        transform_input: bool = False,
        init_weights: Optional[bool] = None,
        blocks: Optional[List[Callable[..., nn.Module]]] = None
    ) -> None:
        super(GoogLeNet, self).__init__()
        if blocks is None:
            blocks = [BasicConv2d, Inception, InceptionAux]
        if init_weights is None:
            warnings.warn('The default weight initialization of GoogleNet will be changed in future releases of '
                          'torchvision. If you wish to keep the old behavior (which leads to long initialization times'
                          ' due to scipy/scipy#11299), please set init_weights=True.', FutureWarning)
            init_weights = True
        assert len(blocks) == 3
        conv_block = blocks[0]
        inception_block = blocks[1]
        inception_aux_block = blocks[2]

        self.aux_logits = aux_logits
        self.transform_input = transform_input

        self.conv1 = conv_block(3, 64, kernel_size=7, stride=2, padding=3)
        self.maxpool1 = nn.MaxPool2d(3, stride=2, ceil_mode=True)
        self.conv2 = conv_block(64, 64, kernel_size=1)
        self.conv3 = conv_block(64, 192, kernel_size=3, padding=1)
        self.maxpool2 = nn.MaxPool2d(3, stride=2, ceil_mode=True)

        self.inception3a = inception_block(192, 64, 96, 128, 16, 32, 32)
        self.inception3b = inception_block(256, 128, 128, 192, 32, 96, 64)
        self.maxpool3 = nn.MaxPool2d(3, stride=2, ceil_mode=True)

        self.inception4a = inception_block(480, 192, 96, 208, 16, 48, 64)
        self.inception4b = inception_block(512, 160, 112, 224, 24, 64, 64)
        self.inception4c = inception_block(512, 128, 128, 256, 24, 64, 64)
        self.inception4d = inception_block(512, 112, 144, 288, 32, 64, 64)
        self.inception4e = inception_block(528, 256, 160, 320, 32, 128, 128)
        self.maxpool4 = nn.MaxPool2d(2, stride=2, ceil_mode=True)

        self.inception5a = inception_block(832, 256, 160, 320, 32, 128, 128)
        self.inception5b = inception_block(832, 384, 192, 384, 48, 128, 128)

        if aux_logits:
            self.aux1 = inception_aux_block(512, num_classes)
            self.aux2 = inception_aux_block(528, num_classes)
        else:
            self.aux1 = None  # type: ignore[assignment]
            self.aux2 = None  # type: ignore[assignment]

        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.dropout = nn.Dropout(0.2)
        self.fc = nn.Linear(1024, num_classes)

        if init_weights:
            self._initialize_weights()

    def _initialize_weights(self) -> None:
        for m in self.modules():
            if isinstance(m, nn.Conv2d) or isinstance(m, nn.Linear):
                import scipy.stats as stats
                X = stats.truncnorm(-2, 2, scale=0.01)
                values = torch.as_tensor(X.rvs(m.weight.numel()), dtype=m.weight.dtype)
                values = values.view(m.weight.size())
                with torch.no_grad():
                    m.weight.copy_(values)
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

    def _transform_input(self, x: Tensor) -> Tensor:
        if self.transform_input:
            x_ch0 = torch.unsqueeze(x[:, 0], 1) * (0.229 / 0.5) + (0.485 - 0.5) / 0.5
            x_ch1 = torch.unsqueeze(x[:, 1], 1) * (0.224 / 0.5) + (0.456 - 0.5) / 0.5
            x_ch2 = torch.unsqueeze(x[:, 2], 1) * (0.225 / 0.5) + (0.406 - 0.5) / 0.5
            x = torch.cat((x_ch0, x_ch1, x_ch2), 1)
        return x

    def _forward(self, x: Tensor) -> Tuple[Tensor, Optional[Tensor], Optional[Tensor]]:
        # N x 3 x 224 x 224
        x = self.conv1(x)
        # N x 64 x 112 x 112
        x = self.maxpool1(x)
        # N x 64 x 56 x 56
        x = self.conv2(x)
        # N x 64 x 56 x 56
        x = self.conv3(x)
        # N x 192 x 56 x 56
        x = self.maxpool2(x)

        # N x 192 x 28 x 28
        x = self.inception3a(x)
        # N x 256 x 28 x 28
        x = self.inception3b(x)
        # N x 480 x 28 x 28
        x = self.maxpool3(x)
        # N x 480 x 14 x 14
        x = self.inception4a(x)
        # N x 512 x 14 x 14
        aux1: Optional[Tensor] = None
        if self.aux1 is not None:
            if self.training:
                aux1 = self.aux1(x)

        x = self.inception4b(x)
        # N x 512 x 14 x 14
        x = self.inception4c(x)
        # N x 512 x 14 x 14
        x = self.inception4d(x)
        # N x 528 x 14 x 14
        aux2: Optional[Tensor] = None
        if self.aux2 is not None:
            if self.training:
                aux2 = self.aux2(x)

        x = self.inception4e(x)
        # N x 832 x 14 x 14
        x = self.maxpool4(x)
        # N x 832 x 7 x 7
        x = self.inception5a(x)
        # N x 832 x 7 x 7
        x = self.inception5b(x)
        # N x 1024 x 7 x 7

        x = self.avgpool(x)
        # N x 1024 x 1 x 1
        x = torch.flatten(x, 1)
        # N x 1024
        x = self.dropout(x)
        x = self.fc(x)
        # N x 1000 (num_classes)
        return x, aux2, aux1

    @torch.jit.unused
    def eager_outputs(self, x: Tensor, aux2: Tensor, aux1: Optional[Tensor]) -> GoogLeNetOutputs:
        if self.training and self.aux_logits:
            return _GoogLeNetOutputs(x, aux2, aux1)
        else:
            return x   # type: ignore[return-value]

    def forward(self, x: Tensor) -> GoogLeNetOutputs:
        x = self._transform_input(x)
        x, aux1, aux2 = self._forward(x)
        aux_defined = self.training and self.aux_logits
        if torch.jit.is_scripting():
            if not aux_defined:
                warnings.warn("Scripted GoogleNet always returns GoogleNetOutputs Tuple")
            return GoogLeNetOutputs(x, aux2, aux1)
        else:
            return self.eager_outputs(x, aux2, aux1)

代码片段3:

class Inception(nn.Module):

    def __init__(
        self,
        in_channels: int,
        ch1x1: int,
        ch3x3red: int,
        ch3x3: int,
        ch5x5red: int,
        ch5x5: int,
        pool_proj: int,
        conv_block: Optional[Callable[..., nn.Module]] = None
    ) -> None:
        super(Inception, self).__init__()
        if conv_block is None:
            conv_block = BasicConv2d
        self.branch1 = conv_block(in_channels, ch1x1, kernel_size=1)

        self.branch2 = nn.Sequential(
            conv_block(in_channels, ch3x3red, kernel_size=1),
            conv_block(ch3x3red, ch3x3, kernel_size=3, padding=1)
        )

        self.branch3 = nn.Sequential(
            conv_block(in_channels, ch5x5red, kernel_size=1),
            # Here, kernel_size=3 instead of kernel_size=5 is a known bug.
            # Please see https://github.com/pytorch/vision/issues/906 for details.
            conv_block(ch5x5red, ch5x5, kernel_size=3, padding=1)
        )

        self.branch4 = nn.Sequential(
            nn.MaxPool2d(kernel_size=3, stride=1, padding=1, ceil_mode=True),
            conv_block(in_channels, pool_proj, kernel_size=1)
        )

    def _forward(self, x: Tensor) -> List[Tensor]:
        branch1 = self.branch1(x)
        branch2 = self.branch2(x)
        branch3 = self.branch3(x)
        branch4 = self.branch4(x)

        outputs = [branch1, branch2, branch3, branch4]
        return outputs

    def forward(self, x: Tensor) -> Tensor:
        outputs = self._forward(x)
        return torch.cat(outputs, 1)


class InceptionAux(nn.Module):

    def __init__(
        self,
        in_channels: int,
        num_classes: int,
        conv_block: Optional[Callable[..., nn.Module]] = None
    ) -> None:
        super(InceptionAux, self).__init__()
        if conv_block is None:
            conv_block = BasicConv2d
        self.conv = conv_block(in_channels, 128, kernel_size=1)

        self.fc1 = nn.Linear(2048, 1024)
        self.fc2 = nn.Linear(1024, num_classes)

    def forward(self, x: Tensor) -> Tensor:
        # aux1: N x 512 x 14 x 14, aux2: N x 528 x 14 x 14
        x = F.adaptive_avg_pool2d(x, (4, 4))
        # aux1: N x 512 x 4 x 4, aux2: N x 528 x 4 x 4
        x = self.conv(x)
        # N x 128 x 4 x 4
        x = torch.flatten(x, 1)
        # N x 2048
        x = F.relu(self.fc1(x), inplace=True)
        # N x 1024
        x = F.dropout(x, 0.7, training=self.training)
        # N x 1024
        x = self.fc2(x)
        # N x 1000 (num_classes)

        return x


class BasicConv2d(nn.Module):

    def __init__(
        self,
        in_channels: int,
        out_channels: int,
        **kwargs: Any
    ) -> None:
        super(BasicConv2d, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, bias=False, **kwargs)
        self.bn = nn.BatchNorm2d(out_channels, eps=0.001)

    def forward(self, x: Tensor) -> Tensor:
        x = self.conv(x)
        x = self.bn(x)
        return F.relu(x, inplace=True)

全部模型代码:

import ssl
ssl._create_default_https_context = ssl._create_unverified_context
import warnings
from collections import namedtuple
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch import Tensor
try:
    from torch.hub import load_state_dict_from_url
except ImportError:
    from torch.utils.model_zoo import load_url as load_state_dict_from_url
from numpy import random
from utils.util import save_feature
from typing import Optional, Tuple, List, Callable, Any

__all__ = ['GoogLeNet', 'googlenet', "GoogLeNetOutputs", "_GoogLeNetOutputs"]

model_urls = {
    # GoogLeNet ported from TensorFlow
    'googlenet': 'https://download.pytorch.org/models/googlenet-1378be20.pth',
}

GoogLeNetOutputs = namedtuple('GoogLeNetOutputs', ['logits', 'aux_logits2', 'aux_logits1'])
GoogLeNetOutputs.__annotations__ = {'logits': Tensor, 'aux_logits2': Optional[Tensor],
                                    'aux_logits1': Optional[Tensor]}

# Script annotations failed with _GoogleNetOutputs = namedtuple ...
# _GoogLeNetOutputs set here for backwards compat
_GoogLeNetOutputs = GoogLeNetOutputs


def googlenet(saveFeature = False, cfg = None,progress: bool = True, **kwargs: Any) -> "GoogLeNet":
    r"""GoogLeNet (Inception v1) model architecture from
    `"Going Deeper with Convolutions" <http://arxiv.org/abs/1409.4842>`_.
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
        progress (bool): If True, displays a progress bar of the download to stderr
        aux_logits (bool): If True, adds two auxiliary branches that can improve training.
            Default: *False* when pretrained is True otherwise *True*
        transform_input (bool): If True, preprocesses the input according to the method with which it
            was trained on ImageNet. Default: *False*
    """
    pretrained = cfg["pretrained"]
    num_class = cfg["num_class"]
    if pretrained:
        if 'transform_input' not in kwargs:
            kwargs['transform_input'] = True
        if 'aux_logits' not in kwargs:
            kwargs['aux_logits'] = False
        if kwargs['aux_logits']:
            warnings.warn('auxiliary heads in the pretrained googlenet model are NOT pretrained, '
                          'so make sure to train them')
        original_aux_logits = kwargs['aux_logits']
        kwargs['aux_logits'] = True
        kwargs['init_weights'] = False
        kwargs["num_classes"] = num_class
        model = GoogLeNet(**kwargs)
        state_dict = load_state_dict_from_url(model_urls['googlenet'],
                                              progress=progress)
        if num_class != 1000:
            weight = torch.Tensor(random.rand(num_class, 1024))
            bias = torch.Tensor(random.rand(num_class))
            state_dict["fc.weight"] = weight
            state_dict["fc.bias"] = bias
            state_dict["aux1.fc2.weight"] = weight
            state_dict["aux1.fc2.bias"] = bias
            state_dict["aux2.fc2.weight"] = weight
            state_dict["aux2.fc2.bias"] = bias


            model.load_state_dict(state_dict)
            if not original_aux_logits:
            model.aux_logits = False
            model.aux1 = None  # type: ignore[assignment]
            model.aux2 = None  # type: ignore[assignment]
            return model

            return GoogLeNet(**kwargs)


            class GoogLeNet(nn.Module):
            __constants__ = ['aux_logits', 'transform_input']

            def __init__(
            self,
            num_classes: int = 1000,
            aux_logits: bool = True,
            transform_input: bool = False,
            init_weights: Optional[bool] = None,
            blocks: Optional[List[Callable[..., nn.Module]]] = None
            ) -> None:
            super(GoogLeNet, self).__init__()
            if blocks is None:
            blocks = [BasicConv2d, Inception, InceptionAux]
            if init_weights is None:
            warnings.warn('The default weight initialization of GoogleNet will be changed in future releases of '
            'torchvision. If you wish to keep the old behavior (which leads to long initialization times'
            ' due to scipy/scipy#11299), please set init_weights=True.', FutureWarning)
            init_weights = True
            assert len(blocks) == 3
            conv_block = blocks[0]
            inception_block = blocks[1]
            inception_aux_block = blocks[2]

            self.aux_logits = aux_logits
            self.transform_input = transform_input

            self.conv1 = conv_block(3, 64, kernel_size=7, stride=2, padding=3)
            self.maxpool1 = nn.MaxPool2d(3, stride=2, ceil_mode=True)
            self.conv2 = conv_block(64, 64, kernel_size=1)
            self.conv3 = conv_block(64, 192, kernel_size=3, padding=1)
            self.maxpool2 = nn.MaxPool2d(3, stride=2, ceil_mode=True)

            self.inception3a = inception_block(192, 64, 96, 128, 16, 32, 32)
            self.inception3b = inception_block(256, 128, 128, 192, 32, 96, 64)
            self.maxpool3 = nn.MaxPool2d(3, stride=2, ceil_mode=True)

            self.inception4a = inception_block(480, 192, 96, 208, 16, 48, 64)
            self.inception4b = inception_block(512, 160, 112, 224, 24, 64, 64)
            self.inception4c = inception_block(512, 128, 128, 256, 24, 64, 64)
            self.inception4d = inception_block(512, 112, 144, 288, 32, 64, 64)
            self.inception4e = inception_block(528, 256, 160, 320, 32, 128, 128)
            self.maxpool4 = nn.MaxPool2d(2, stride=2, ceil_mode=True)

            self.inception5a = inception_block(832, 256, 160, 320, 32, 128, 128)
            self.inception5b = inception_block(832, 384, 192, 384, 48, 128, 128)

            if aux_logits:
            self.aux1 = inception_aux_block(512, num_classes)
            self.aux2 = inception_aux_block(528, num_classes)
            else:
            self.aux1 = None  # type: ignore[assignment]
            self.aux2 = None  # type: ignore[assignment]

            self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
            self.dropout = nn.Dropout(0.2)
            self.fc = nn.Linear(1024, num_classes)

            if init_weights:
            self._initialize_weights()

            def _initialize_weights(self) -> None:
            for m in self.modules():
            if isinstance(m, nn.Conv2d) or isinstance(m, nn.Linear):
            import scipy.stats as stats
            X = stats.truncnorm(-2, 2, scale=0.01)
            values = torch.as_tensor(X.rvs(m.weight.numel()), dtype=m.weight.dtype)
            values = values.view(m.weight.size())
            with torch.no_grad():
            m.weight.copy_(values)
        elif isinstance(m, nn.BatchNorm2d):
            nn.init.constant_(m.weight, 1)
            nn.init.constant_(m.bias, 0)

            def _transform_input(self, x: Tensor) -> Tensor:
            if self.transform_input:
            x_ch0 = torch.unsqueeze(x[:, 0], 1) * (0.229 / 0.5) + (0.485 - 0.5) / 0.5
            x_ch1 = torch.unsqueeze(x[:, 1], 1) * (0.224 / 0.5) + (0.456 - 0.5) / 0.5
            x_ch2 = torch.unsqueeze(x[:, 2], 1) * (0.225 / 0.5) + (0.406 - 0.5) / 0.5
            x = torch.cat((x_ch0, x_ch1, x_ch2), 1)
            return x

            def _forward(self, x: Tensor) -> Tuple[Tensor, Optional[Tensor], Optional[Tensor]]:
        # N x 3 x 224 x 224
            x = self.conv1(x)
        # N x 64 x 112 x 112
            x = self.maxpool1(x)
        # N x 64 x 56 x 56
            x = self.conv2(x)
        # N x 64 x 56 x 56
            x = self.conv3(x)
        # N x 192 x 56 x 56
            x = self.maxpool2(x)

        # N x 192 x 28 x 28
            x = self.inception3a(x)
        # N x 256 x 28 x 28
            x = self.inception3b(x)
        # N x 480 x 28 x 28
            x = self.maxpool3(x)
        # N x 480 x 14 x 14
            x = self.inception4a(x)
        # N x 512 x 14 x 14
            aux1: Optional[Tensor] = None
            if self.aux1 is not None:
            if self.training:
            aux1 = self.aux1(x)

            x = self.inception4b(x)
        # N x 512 x 14 x 14
            x = self.inception4c(x)
        # N x 512 x 14 x 14
            x = self.inception4d(x)
        # N x 528 x 14 x 14
            aux2: Optional[Tensor] = None
            if self.aux2 is not None:
            if self.training:
            aux2 = self.aux2(x)

            x = self.inception4e(x)
        # N x 832 x 14 x 14
            x = self.maxpool4(x)
        # N x 832 x 7 x 7
            x = self.inception5a(x)
        # N x 832 x 7 x 7
            x = self.inception5b(x)
        # N x 1024 x 7 x 7

            x = self.avgpool(x)
        # N x 1024 x 1 x 1
            x = torch.flatten(x, 1)
        # N x 1024
            x = self.dropout(x)
            x = self.fc(x)
        # N x 1000 (num_classes)
            return x, aux2, aux1

            @torch.jit.unused
            def eager_outputs(self, x: Tensor, aux2: Tensor, aux1: Optional[Tensor]) -> GoogLeNetOutputs:
            if self.training and self.aux_logits:
            return _GoogLeNetOutputs(x, aux2, aux1)
            else:
            return x   # type: ignore[return-value]

            def forward(self, x: Tensor) -> GoogLeNetOutputs:
            x = self._transform_input(x)
            x, aux1, aux2 = self._forward(x)
            aux_defined = self.training and self.aux_logits
            if torch.jit.is_scripting():
            if not aux_defined:
            warnings.warn("Scripted GoogleNet always returns GoogleNetOutputs Tuple")
            return GoogLeNetOutputs(x, aux2, aux1)
            else:
            return self.eager_outputs(x, aux2, aux1)


            class Inception(nn.Module):

            def __init__(
            self,
            in_channels: int,
            ch1x1: int,
            ch3x3red: int,
            ch3x3: int,
            ch5x5red: int,
            ch5x5: int,
            pool_proj: int,
            conv_block: Optional[Callable[..., nn.Module]] = None
            ) -> None:
            super(Inception, self).__init__()
            if conv_block is None:
            conv_block = BasicConv2d
            self.branch1 = conv_block(in_channels, ch1x1, kernel_size=1)

            self.branch2 = nn.Sequential(
            conv_block(in_channels, ch3x3red, kernel_size=1),
            conv_block(ch3x3red, ch3x3, kernel_size=3, padding=1)
            )

            self.branch3 = nn.Sequential(
            conv_block(in_channels, ch5x5red, kernel_size=1),
            # Here, kernel_size=3 instead of kernel_size=5 is a known bug.
            # Please see https://github.com/pytorch/vision/issues/906 for details.
            conv_block(ch5x5red, ch5x5, kernel_size=3, padding=1)
            )

            self.branch4 = nn.Sequential(
            nn.MaxPool2d(kernel_size=3, stride=1, padding=1, ceil_mode=True),
            conv_block(in_channels, pool_proj, kernel_size=1)
            )

            def _forward(self, x: Tensor) -> List[Tensor]:
            branch1 = self.branch1(x)
            branch2 = self.branch2(x)
            branch3 = self.branch3(x)
            branch4 = self.branch4(x)

            outputs = [branch1, branch2, branch3, branch4]
            return outputs

            def forward(self, x: Tensor) -> Tensor:
            outputs = self._forward(x)
            return torch.cat(outputs, 1)


            class InceptionAux(nn.Module):

            def __init__(
            self,
            in_channels: int,
            num_classes: int,
            conv_block: Optional[Callable[..., nn.Module]] = None
            ) -> None:
            super(InceptionAux, self).__init__()
            if conv_block is None:
            conv_block = BasicConv2d
            self.conv = conv_block(in_channels, 128, kernel_size=1)

            self.fc1 = nn.Linear(2048, 1024)
            self.fc2 = nn.Linear(1024, num_classes)

            def forward(self, x: Tensor) -> Tensor:
        # aux1: N x 512 x 14 x 14, aux2: N x 528 x 14 x 14
            x = F.adaptive_avg_pool2d(x, (4, 4))
        # aux1: N x 512 x 4 x 4, aux2: N x 528 x 4 x 4
            x = self.conv(x)
        # N x 128 x 4 x 4
            x = torch.flatten(x, 1)
        # N x 2048
            x = F.relu(self.fc1(x), inplace=True)
        # N x 1024
            x = F.dropout(x, 0.7, training=self.training)
        # N x 1024
            x = self.fc2(x)
        # N x 1000 (num_classes)

            return x


            class BasicConv2d(nn.Module):

            def __init__(
            self,
            in_channels: int,
            out_channels: int,
            **kwargs: Any
            ) -> None:
            super(BasicConv2d, self).__init__()
            self.conv = nn.Conv2d(in_channels, out_channels, bias=False, **kwargs)
            self.bn = nn.BatchNorm2d(out_channels, eps=0.001)

            def forward(self, x: Tensor) -> Tensor:
            x = self.conv(x)
            x = self.bn(x)
            return F.relu(x, inplace=True)


            if __name__ == '__main__':
            cfg = {
            "name": "googlenet",
            "pretrained":True,
            "num_class":10
            }
            net = googlenet(cfg=cfg)
            print(net)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值