训练 Pytorch 模型

问题描述

我在训练 PyTorch 模型时遇到了问题。遵循从 GitHub 找到的 PyTorch 模型,我完美地运行了该源代码,可以假设训练 SEC 模型的原始想法运行良好。然后,我试着稍微修改一下:

SEC model

  1. 实现算法

我为此应用了 DSRG algorithm 弱监督语义分割任务到我的 PyTorch 模型中。它在技术上需要 最终特征映射出来,并执行一些机制来提出新的 “语义地图(G)”(尺寸:21x41x41)。

DSRG model

我认为它运行良好,因为我使用此修改运行代码,并且训练和推理运行良好。

  1. 实现损失函数

同样从 DSRG 中,我计算出像素级的种子损失,它只不过是交叉熵损失。

def dsrg_seed_loss_layer(probs,labels):

    count_bg = torch.sum(labels[:,0:1,:,:],dim=(2,3,1),keepdim=True)
    loss_bg = -torch.mean(torch.sum(labels[:,:] * torch.log(probs[:,:]),keepdim=True) / (count_bg+MIN_PROB))
    
    count_fg = torch.sum(labels[:,1:,keepdim=True)
    loss_fg = -torch.mean(torch.sum(labels[:,keepdim=True) / (count_fg+MIN_PROB))
    loss_balanced = loss_bg+loss_fg
    
    count_bg_avg = torch.mean(count_bg.squeeze())
    count_fg_avg = torch.mean(count_fg.squeeze())
    return loss_balanced,loss_bg,count_bg_avg,loss_fg,count_fg_avg

同上,应该可以了!!

  1. 修改模型网络结构

我尝试将更多层附加到原始模型网络。 (原来的 模型是 vgg16-deeplabv1 而我实现了 vgg16-deeplabv2)

class DeepLabV2LargeFOV(nn.Module):

    def __init__(self,num_classes,original_model,small = False):
        super(DeepLabV2LargeFOV,self).__init__()
        self.num_classes = num_classes
        self.features =  nn.Sequential(*list(original_model.features.children()))
              
        if small:
            rates = [2,4,8,12]
        else:
            rates = [6,12,18,24]
            
        self.aspp1 = self.atrous_layers(rates[0],self.num_classes,"1")
        self.aspp2 = self.atrous_layers(rates[1],"2")
        self.aspp3 = self.atrous_layers(rates[2],"3")
        self.aspp4 = self.atrous_layers(rates[3],"4")
        
    def forward(self,x):
        x = self.features(x)      
        
        # Atrous Layers
        aspp1 = self.aspp1(x)
        aspp2 = self.aspp2(x)
        aspp3 = self.aspp3(x)
        aspp4 = self.aspp4(x)        
        
        x = aspp1 + aspp2 + aspp3 + aspp4
        
        return x
    
    def atrous_layers(self,rate,num):      
        layers = nn.Sequential()
        layers.add_module("fc6_{0:s}".format(num),nn.Conv2d(512,1024,kernel_size=3,padding=rate,dilation=rate))
        layers.add_module("relu6_{0:s}".format(num),nn.ReLU())
        layers.add_module("drop6_{0:s}".format(num),nn.Dropout2d(0.5))
        layers.add_module("fc7_{0:s}".format(num),nn.Conv2d(1024,kernel_size=1,stride=1,padding=0))
        layers.add_module("relu7_{0:s}".format(num),nn.ReLU())
        layers.add_module("drop7_{0:s}".format(num),nn.Dropout2d(0.5))
        layers.add_module("fc8-SEC_{0:s}".format(num),padding=0))
        weight_init(layers)
        return layers
    
def weight_init(m):
    for name,layer in m.named_modules():
        if isinstance(layer,nn.Conv2d):
            nn.init.normal_(layer.weight,mean=0,std=0.01)
            nn.init.constant_(layer.bias,0)
            
def deeplabv2_large_fov(num_classes,original_model):
    return DeepLabV2LargeFOV(num_classes=num_classes,original_model=original_model)

在我实现这部分之后,我尝试通过仅加载给定的原始 PyTorch 权重(对于前一层)来训练模型。但是,似乎模型没有正常训练。

Training Result

  1. 加载预训练权重

我尝试将 pretrained weight 加载到新模型中。 然而,预训练的权重不过是 python numpy 字典。我开发了另一个文件来转换这样的 numpy 文件 (.npy) 进入 PyTorch 模式 (.pth.tar)

我还花时间加载权重和偏差以逐层建模并保存为 .pth.tar。我很确定每一层的大小都是匹配的,同时参数都被保存了。但是结果也和之前一样,所以证明无论是partial-pretrained-weight还是complete-pretrained-weight在我的程序中都行不通。


有没有人知道我的技术培训问题。我其实没什么想法

  • 由于损失通常会下降,我可以假设我的模型是通过完整的计算图和所有连接的梯度流正确构建的(例如 requires_grad=True?如果不是,我该如何检查?

  • 问题是否可能发生在优化器上?我的意思是,源代码似乎对来自不同层(实际上是 2 个,最后一个和其他)的参数设置了动态学习率。有谁知道它是如何工作的

     optimizer = torch.optim.SGD([
     {'params': get_parameters(model,bias=False,final=False),'lr':args.lr,'weight_decay': args.wd},{'params': get_parameters(model,bias=True,'lr':args.lr * 2,'weight_decay': 0},final=True),'lr':args.lr * 10,'lr':args.lr * 20,'weight_decay': 0}],momentum=args.momentum)
    
  • 它结合了常规的学习率衰减技术。如何检查它是否正常工作?

         if global_iter % args.lr_decay == 0:
         args.lr = args.lr * 0.1
         optimizer = adjust_learning_rate(optimizer,args.lr)
    
  • 超参数调整,这是我正在尝试做的,因为涉及很多超参数。如果有人能给我带来关于这个问题的经验,我会很高兴。 (整个训练需要8个多小时才能完成)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)