Darknet53 detailed principle (including torch version source code)

Principle of Darknet53

        Darknet53 is a convolutional neural network model proposed by Joseph Redmon in the paper "YOLOv3: An Incremental Improvement" in 2018 for target detection and classification tasks. It is the core network model of YOLOv3, and its design idea is to improve the effect of feature extraction by stacking multiple convolution and residual connection layers.

        Darknet53 consists of 53 convolutional layers and 5 max-pooling layers. The structure of Darknet53 can be divided into three groups: the front section is mainly composed of convolutional layers and max-pooling layers, the middle section is mainly composed of residual blocks, and the back section is mainly composed of global average pooling layers and fully connected layers.

        Specifically, each of the 7 convolutional layers in the previous section is a convolution with a convolution kernel size of 3x3 and a step size of 1x1, followed by 5 max-pooling layers. The purpose of this part is to continuously reduce the spatial information of the image and increase the depth.

        Next is the residual block in the middle. Since the author of YOLOv3 found that under the above design, the learning of YOLOv3 is very slow, so he proposed a structure called "Residual Block (Residual Block)". The residual block is similar to a short circuit, which allows the neural network to learn the "residual", which is the difference between the current input and the desired output. It uses a residual structure to speed up convergence, reduce the problem of vanishing gradients, and improve accuracy. This structure enables the network to better learn the features in the input image and enhances the expressive ability of the model. The network frame diagram is as follows:

 

        The input of Darknet53 is an RGB image with a size of 416x416 pixels. After a series of convolution operations, the output is a tensor of 13x13x1024. This tensor can be passed to the detection head in YOLOv3 to detect objects in the image.

Features of the Darknet53 network framework include:

  1. Shallow model: Compared with other deep neural network frameworks, Darknet53 has only 53 layers, so the training speed is fast and the performance is high.

  2. Scalable network depth: Using the residual structure, it is easy to add more convolutional layers to improve the performance of the network.

  3. Small amount of parameters: Darknet53 has much fewer parameters than other networks, especially compared with models such as ResNet, which makes the model faster and easier to train and optimize.

  4. Efficient reasoning: Darknet53 uses low-precision computing and parallel computing technology, which makes the model's reasoning speed very fast and can be executed on low-power devices.

  5. Applicable to object classification of a large number of categories: The advantage of Darknet53 is to learn image features and can efficiently solve the problem of object classification of a large number of categories.

        In general, Darknet53 is a very effective convolutional neural network with high accuracy and efficiency, which has become one of the backbone networks widely used in modern computer vision tasks, and it has been widely used in the field of computer vision Various tasks, including image classification, object detection, face recognition, etc.

Darknet53 source code (torch version)

The data set is automatically downloaded when the code is run. If the network is slow, you can click the link I shared to download the cifar data set.

Link: Baidu Netdisk 
Extraction code: kd9a 

This code is run using the GPU. If there is no GPU and the operation fails, delete the device and .to(device) in the code and use the default CPU to run.

If the GPU memory is small and the operation error is reported, just reduce the batch_size in the main function main().


import torch
import torch.nn as nn
from torch.nn import modules
from torch.utils.data import DataLoader
from torchvision.datasets import CIFAR10
from torchvision.transforms import transforms
from torch.autograd import Variable


class ConvBnLeaky(modules.Module):
    def __init__(self,in_it,out_it,kernels,padding = 0,strides = 1):
        super(ConvBnLeaky, self).__init__()
        self.convs = nn.Sequential(
            nn.Conv2d(in_it,out_it,kernels,padding=padding,stride=strides),
            nn.BatchNorm2d(out_it),
            nn.LeakyReLU(0.1,True)
        )
    def forward(self,x):
        x = self.convs(x)
        return x
    pass
class Resnet_Block(modules.Module):
    def __init__(self,ch,num_block = 1):
        super(Resnet_Block, self).__init__()
        self.module_list = modules.ModuleList()
        for _ in range(num_block):
            resblock = nn.Sequential(
                ConvBnLeaky(ch,ch // 2,1),
                ConvBnLeaky(ch // 2,ch,kernels=3,padding=1)
            )
            self.module_list.append(resblock)
    def forward(self,x):
        for i in self.module_list:
            x = i(x) + x
        return x

class Darknet_53(modules.Module):
    def __init__(self,num_classes = 10):
        super(Darknet_53, self).__init__()
        self.later_1 = nn.Sequential(
            ConvBnLeaky(3,32,3,padding=1),
            ConvBnLeaky(32,64,3,padding=1,strides=2),
            Resnet_Block(64,1)
        )
        self.later_2 = nn.Sequential(
            ConvBnLeaky(64, 128, 3, padding=1,strides=2),
            Resnet_Block(128, 2)
        )
        self.later_3 = nn.Sequential(
            ConvBnLeaky(128, 256, 3, padding=1, strides=2),
            Resnet_Block(256, 8)
        )
        self.later_4 = nn.Sequential(
            ConvBnLeaky(256, 512, 3, padding=1, strides=2),
            Resnet_Block(512, 8)
        )
        self.later_5 = nn.Sequential(
            ConvBnLeaky(512, 1024, 3, padding=1, strides=2),
            Resnet_Block(1024, 4)
        )
        self.pool = nn.AdaptiveAvgPool2d((1,1))
        self.fc = nn.Linear(1024,num_classes)
    def forward(self,x):
        x = self.later_1(x)
        x = self.later_2(x)
        x = self.later_3(x)
        x = self.later_4(x)
        x = self.later_5(x)
        x = self.pool(x)
        x = torch.squeeze(x)
        x = self.fc(x)
        return x


def main():
    Root_file = 'cifar'
    train_data = CIFAR10(Root_file,train=True,transform = transforms.ToTensor())
    data = DataLoader(train_data,batch_size=64,shuffle=True)

    device = torch.device('cuda')
    net = Darknet_53().to(device)
    print(net)
    Cross = nn.CrossEntropyLoss().to(device)
    optimizer = torch.optim.Adam(net.parameters(),0.001)
    for epoch in range(10):
        for img,label in data:
            img = Variable(img).to(device)
            label = Variable(label).to(device)
            output = net.forward(img)
            loss = Cross(output,label)
            loss.backward()
            optimizer.zero_grad()
            optimizer.step()
            pre = torch.argmax(output,1)
            num = (pre == label).sum().item()
            acc = num / img.shape[0]
            loss_val = loss.item()
        print("epoch:",epoch)
        print("acc:",acc)
        print("loss:",loss_val)
    pass


if __name__ == '__main__':
    main()

 The effect of training for 10 epochs

renderings

 

Frames

Darknet_53(
  (later_1): Sequential(
    (0): ConvBnLeaky(
      (convs): Sequential(
        (0): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (2): LeakyReLU(negative_slope=0.1, inplace=True)
      )
    )
    (1): ConvBnLeaky(
      (convs): Sequential(
        (0): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
        (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (2): LeakyReLU(negative_slope=0.1, inplace=True)
      )
    )
    (2): Resnet_Block(
      (module_list): ModuleList(
        (0): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(64, 32, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
      )
    )
  )
  (later_2): Sequential(
    (0): ConvBnLeaky(
      (convs): Sequential(
        (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
        (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (2): LeakyReLU(negative_slope=0.1, inplace=True)
      )
    )
    (1): Resnet_Block(
      (module_list): ModuleList(
        (0): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(128, 64, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (1): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(128, 64, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
      )
    )
  )
  (later_3): Sequential(
    (0): ConvBnLeaky(
      (convs): Sequential(
        (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (2): LeakyReLU(negative_slope=0.1, inplace=True)
      )
    )
    (1): Resnet_Block(
      (module_list): ModuleList(
        (0): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (1): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (2): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (3): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (4): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (5): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (6): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (7): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
      )
    )
  )
  (later_4): Sequential(
    (0): ConvBnLeaky(
      (convs): Sequential(
        (0): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
        (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (2): LeakyReLU(negative_slope=0.1, inplace=True)
      )
    )
    (1): Resnet_Block(
      (module_list): ModuleList(
        (0): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (1): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (2): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (3): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (4): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (5): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (6): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (7): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
      )
    )
  )
  (later_5): Sequential(
    (0): ConvBnLeaky(
      (convs): Sequential(
        (0): Conv2d(512, 1024, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
        (1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (2): LeakyReLU(negative_slope=0.1, inplace=True)
      )
    )
    (1): Resnet_Block(
      (module_list): ModuleList(
        (0): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(512, 1024, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (1): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(512, 1024, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (2): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(512, 1024, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
        (3): Sequential(
          (0): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1))
              (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
          (1): ConvBnLeaky(
            (convs): Sequential(
              (0): Conv2d(512, 1024, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
              (1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
              (2): LeakyReLU(negative_slope=0.1, inplace=True)
            )
          )
        )
      )
    )
  )
  (pool): AdaptiveAvgPool2d(output_size=(1, 1))
  (fc): Linear(in_features=1024, out_features=10, bias=True)
)

Guess you like

Origin blog.csdn.net/Code_and516/article/details/129976322