pytorch手动加入正则

1.Pytorch自带的加正则化方法

Pytorch的优化器都自带正则化,比如

 optimizer = optim.Adam(model.parameters(),lr=learning_rate,weight_decay=0.01)
 optimizer = optim.SGD(model.parameters(), lr=learing_rate, momentum=0.9,weight_decay=0.01)

其中的weight_decay就是正则化系数,设定为0或者不设定就是无正则化。但这个优化器自带正则化有两个特点,一是只能是L2正则,二是它将所有的参数都进行了正则化,包括权重、偏执及其他的一些。

2.自己加正则化的方式

可以模仿tensorflow自己加正则化,这包括几个步骤:获得需要加正则的参数,将这些参数的正则化和表示出来,将这个和加入损失函数。下面采用一个类来具体介绍,先给出代码。

class Regularization(nn.Module):
    def __init__(self,model,weight_decay,p=2):
        super(Regularization, self).__init__()
        self.model = model
        self.weight_decay = weight_decay
        self.p = p
        self.weight_list = self.get_weight(model)
        self.weight_info(self.weight_list)
    #在训练过程中每次调用需要
    def forward(self,model):
        self.weight_list = self.get_weight(model)
        reg_loss = self.regularization_loss(self.weight_list,self.weight_decay,p=self.p)
        return reg_loss
    #确定设备
    def to(self, device):
        self.device = device
        super().to(device)
        return self
    #得到正则化参数
    def get_weight(self, model):
        weight_list = []
        for name, param in model.named_parameters():
            if 'weight' in name:
                weight = (name, param)
                weight_list.append(weight)
        return weight_list
    #求取正则化的和
    def regularization_loss(self, weight_list, weight_decay, p=2):
        reg_loss = 0
        for name, w in weight_list:
            l2_reg = torch.norm(w, p=p)
            reg_loss = reg_loss + l2_reg
        reg_loss = weight_decay * reg_loss
        return reg_loss
    #打印有哪些参数
    def weight_info(self, weight_list):
        print("---------------regularization weight---------------")
        for name, w in weight_list:
            print(name)
        print("---------------------------------------------------")

这个类需要传入模型model,正则化系数weight_decay。p是决定L1正则还是L2正则的一个系数,p=1代表L1,p=2代表L2.
其中get_weight(self, model)函数用于获取参数列表,里面只获取权重列表,如果要获取其他可以自行修改,但一般来说,都是获取权重。weight_info(self, weight_list)函数用于打印获取的权重,可以知晓都获得了哪些层的权重,得到的结果如下面的例子所示:
pytorch手动加入正则_第1张图片
regularization_loss(self, weight_list, weight_decay, p=2)函数用于具体的计算正则化。它的原理很简单,就是取出每个参数值,然后求一范数或者二范数,再求和。to(self, device)函数和forward(self,model)函数是继承nn.Module()所常用的两个函数。

3.代码里面如何用

首先,把这个函数完整的放入代码中
然后,在你的模型建立的时候也调用一下这个,像这样

reg_loss = Regularization(model, weight_decay, p=2).to(device)

将这一行放在迭代训练开始前就可以,和优化器什么的放一起
最后,在你的损失里面加入正则损失,像下面这样,其中第一行是真实损失,第二行是加入正则后的损失

loss = criterion(y_pred, labels.long())
loss = loss + reg_loss(model) 

4.如何知道是否加入正则

在训练过程中将loss.item()输出一下,可以看到具体损失值是多少,大倍数的改变正则化系数weight_decay,如果loss.item的输出变化很大,那么就是加入了

以上内容都是在看了一个github后总结的,原代码地址如下
https://github.com/PanJinquan/pytorch-learning-tutorials/blob/master/image_classification/train_resNet.py

你可能感兴趣的:(深度学习技巧)