【论文复现】https://github.com/veralauee/DPatch代码详解(非常详细,附相关pytorch语法和知识点补充)

本文详细解析了DPatch项目的Darknet19网络结构,包括darknet.py文件中的_layers函数、Darknet19类,以及reorg layer和全局平均池化等算法知识点。此外,还介绍了PyTorch中的permute、view和torch.cat函数的用法,并探讨了图像处理中的掩膜概念。
摘要由CSDN通过智能技术生成

写在前面

最近需要在DPatch源码的基础上,做一些修改,改成自己的网络,生成自己的对抗样本。为了方便修改,需要花点时间将DPatch的源码啃明白。所以就有了这篇博客,记录源码学习的过程,方便后面查看修改。为了方便查看,我将自己对于源码的理解直接作为注释添加在源代码中。由于我主要是要修改darknet.py文件为其他网络结构,同时使用train.py文件进行训练,所以我主要关注这两个文件,同时关注一些输入和输出。

Darknet19的整个的网络结构

在这里插入图片描述

darknet.py文件

(1)def _make_layers(in_channels, net_cfg)
#这个文件用来定义网络中的每一层,其中的in_channels是每一层的输入通道数,out_channels是输出通道数
def _make_layers(in_channels, net_cfg):
    layers = []
    #如果net_cfg这个列表中不止一个元素,则对列表中每一个元素都进行一次_make_layers操作
    if len(net_cfg) > 0 and isinstance(net_cfg[0], list):
        for sub_cfg in net_cfg:
            layer, in_channels = _make_layers(in_channels, sub_cfg)
            #将每一层都保存到layers中
            layers.append(layer)
    else:
        for item in net_cfg:
            #net_cfg中的第一个元素如果为M,则表明要执行max pooling最大池化操作,这一层也要放到layers中
            if item == 'M':
                layers.append(nn.MaxPool2d(kernel_size=2, stride=2))
            else:
                out_channels, ksize = item
                #此时应该是构建卷积层,通过调用net_utils中的Conv2d_BatchNorm函数,从而执行卷积,batch normalization这些操作
                layers.append(net_utils.Conv2d_BatchNorm(in_channels,
                                                         out_channels,
                                                         ksize,
                                                         same_padding=True))
                # layers.append(net_utils.Conv2d(in_channels, out_channels,
                #     ksize, same_padding=True))
                in_channels = out_channels
   #nn.sequential是一个容器,就是根据自己的需求,把不同的函数组合成一个模块使用,这里的in_channels就是最后一层的输出通道数目
    return nn.Sequential(*layers), in_channels
(2)class Darknet19(nn.Module)
1)def __init__函数
def __init__(self, training=True):
        super(Darknet19, self).__init__()
        #这里就是Darknet19的网络结构,全部保存在net_cfgs这个列表中。其中M表示做最大池化,(64, 3)表示做一次卷积,输出通道数目64,3表示卷积核的size是3×3.
        net_cfgs = [
            # conv1s
            [(32, 3)],
            ['M', (64, 3)],
            ['M', (128, 3), (64, 1), (128, 3)],
            ['M', (256, 3), (128, 1), (256, 3)],
            ['M', (512, 3), (256, 1), (512, 3), (256, 1), (512, 3)],
            # conv2
            ['M', (1024, 3), (512, 1), (1024, 3), (512, 1), (1024, 3)],
            # ------------
            # conv3
            [(1024, 3), (1024, 3)],
            # conv4
            [(1024, 3)]
        ]

        # darknet
        #每次调用_make_layers,其中3表示输入通道数目为3,c1是上一层的输出通道数目,同时也是下一层的输入通道数目
        self.conv1s, c1 = _make_layers(3, net_cfgs[0:5])
        self.conv2, c2 = _make_layers(c1, net_cfgs[5])
        # ---
        self.conv3, c3 = _make_layers(c2, net_cfgs[6])

        stride = 2
        # stride*stride times the channels of conv1s
        #这里调用了作者自己写的函数ReorgLayer,下面对这个函数进行解析
        self.reorg = ReorgLayer(stride=2)
        # cat [conv1s, conv3]
        #经过上面的reorg layer,此时的输入通道数目变成了c1*(stride*stride) + c3
        self.conv4, c4 = _make_layers((c1*(stride*stride) + c3), net_cfgs[7])

        # linear
        out_channels = cfg.num_anchors * (cfg.num_classes + 5)
        self.conv5 = net_utils.Conv2d(c4, out_channels, 1, 1, relu=False)
        #这里的nn.AvgPool2d((1, 1))表示是做平均全局池化global average pool。具体解释见下面
        self.global_average_pool = nn.AvgPool2d((1, 1))

        # train
        self.bbox_loss = None
        self.iou_loss = None
        self.cls_loss = None
        self.pool = Pool(processes=10)
       
        ''' define a patch here '''
        # training
        if training:
            #这里的意思是将一个固定不可训练的tensor转换成可以训练的类型parameter。
            #所以经过类型转换这个self.v变成了模型的一部分,成为了模型中根据训练可以改动的参数了。
            #使用这个函数的目的也是想让某些变量在学习的过程中不断的修改其值以达到最优化。
            #(1,3)定义了输出张量的形状,cfg.img_w, cfg.img_h表示的是结果张量
           self.patch = nn.Parameter(torch.rand(1,3, cfg.img_w, cfg.img_h),requires_grad=True)
        # testing
        else:
           self.patch = cfg.patch.cuda()

2)forward函数:
def forward(self, im_data, gt_boxes=None, gt_classes=None, dontcare=None,
                size_index=0, attack=None):
        
        # add patch here
        if attack is not None:
           for k in range(im_data.size(
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值