如何把“自己的”网络中的conv2d替换为dcnv2

1、dcnv2的实现测试了两种,一种是官方版dcnv2,git链接:https://github.com/CharlesShang/DCNv2.git,编译直接cd到DCNv2,然后./make.sh即可,第二种是mmcv.ops.modulated_deform_conv.ModulatedDeformConv2dPack

2、实验以resnet50、mnist训练为例

from torch_op.common import init_seed
from torchvision.datasets import MNIST
from torchvision import transforms
from torch.utils.data import DataLoader
from torchvision.models.resnet import resnet50
from torch import nn,optim
import torch

with_dcn = True
if with_dcn:
    #两种dcn导入方法
    # from dcn_v2 import DCN
    from mmcv.ops.modulated_deform_conv import ModulatedDeformConv2dPack as DCN

init_seed(0)

batch_size =64
num_workers = 16
epochs = 20
lr = 0.1

train_dataset = MNIST('torch_op/mnist/data',train=True,download=True,
                      transform=transforms.Compose([
                          transforms.ToTensor(),
                          # transforms.Normalize((0.1307,),(0.3081))
                      ])
                      )

test_dataset = MNIST('torch_op/mnist/data',train=False,download=True,
                      transform=transforms.Compose([
                          transforms.ToTensor(),
                          # transforms.Normalize((0.1307,),(0.3081))
                      ])
                      )

train_loader = DataLoader(train_dataset,batch_size=batch_size,shuffle=True,num_workers=num_workers)
test_loader = DataLoader(test_dataset,batch_size=batch_size,shuffle=False,num_workers=num_workers)

#替换原网络中每个bottleneck中第二个conv为dcn
def replace(layers):
    for name,module in layers.named_children():
        if isinstance(module,torch.nn.Conv2d):
            if 'conv2' in name:
                new_module = DCN(module.in_channels, module.out_channels, module.kernel_size, module.stride, module.padding,
                                 module.dilation, 1)
                layers.add_module(name,new_module)
        else:
            replace(module)


model = resnet50(False,num_classes=10)

#需要将conv替换成dcn的module列表
if with_dcn:
    replace_list = ['layer2','layer3','layer4']
    for name,module in model.named_children():
        if name not in replace_list:
            continue
        # print(module)
        replace(module)
        # print('*'*20)
        # print(module)
        # print('-'*20)

print(model)
model = model.cuda()

optimizer = optim.SGD(model.parameters(),lr=lr)
criterion = nn.CrossEntropyLoss()

def train():
    model.train()
    for batch_idx,(data,target) in enumerate(train_loader):
        if data.size(1)==1:
            data = torch.cat([data,data,data],dim=1)
        # print('start_train')
        data = data.cuda()
        target = target.cuda()

        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output,target)
        loss.backward()
        optimizer.step()
        if batch_idx % 100 == 0:
            print('loss:{}'.format(loss.item()))

def test(e):
    model.eval()
    total_right = 0
    total_wrong = 0
    with torch.no_grad():
        for batch_idx,(data,target) in enumerate(test_loader):
            if data.size(1) == 1:
                data = torch.cat([data, data, data], dim=1)
            data = data.cuda()
            target = target.cuda()
            output = model(data)
            output = output.max(dim=1)[1]
            right = torch.sum(output==target).item()
            wrong = len(data) - right
            total_right += right
            total_wrong += wrong
    print('epoch-{} acc:{}/{}={}'.format(e,total_right,total_right+total_wrong,total_right/(total_wrong+total_right)))


for e in range(epochs):
    train()
    test(e)

3、总结

当把layer2、3、4的conv全部替换为dcn时,训练特别慢,而且acc一直很低,大概只有10%左右

 

 

  • 3
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值