欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

pytorch中state_dict()和named_parameters()的差别,以及model.buffer/model.parameter

程序员文章站 2022-07-03 20:35:39
在使用pytorch过程中,我发现了torch中存在3个功能极其类似的方法,它们分别是model.parameters()、model.named_parameters()和model.state_dict(),下面就具体来说说这三个函数的差异首先,说说比较接近的model.parameters()和model.named_parameters()。这两者唯一的差别在于,named_parameters()返回的list中,每个元祖打包了2个内容,分别是layer-name和layer-param,而pa...

在使用pytorch过程中,我发现了torch中存在3个功能极其类似的方法,它们分别是model.parameters()model.named_parameters()model.state_dict(),下面就具体来说说这三个函数的差异
首先,说说比较接近的model.parameters()model.named_parameters()。这两者唯一的差别在于,named_parameters()返回的list中,每个元祖打包了2个内容,分别是layer-name和layer-param,而parameters()只有后者。后面只谈model.named_parameters()model.state_dict()间的差别。


它们的差异主要体现在3方面:

  • 返回值类型不同
  • 存储的模型参数的种类不同
  • 返回的值的require_grad属性不同

首先说第一个,这很简单,model.state_dict()是将layer_name : layer_param的键值信息存储为dict形式,而model.named_parameters()则是打包成一个元祖然后再存到list当中;
第二,model.state_dict()存储的是该model中包含的所有layer中的所有参数;而model.named_parameters()则只保存可学习、可被更新的参数,model.buffer()中的参数不包含在model.named_parameters()
最后,model.state_dict()所存储的模型参数tensor的require_grad属性都是False,而model.named_parameters()require_grad属性都是True


最后,再说说nn.Parameters()

实际上,我们以上提到的model.parameters()model.named_parameters()都和这个module有关,毕竟模型参数在初始化中就是用这个模块被实例化的。以神经网络中最常见的nn.Linear()为例,这是pytorch1.4的nn.Linear()源码:

class Linear(Module):
	 __constants__ = ['bias']
    def __init__(self, in_features, out_features, bias=True):
        super(Linear, self).__init__()
        self.in_features = in_features
        self.out_features = out_features
        self.weight = Parameter(torch.Tensor(out_features, in_features))
        if bias:
            self.bias = Parameter(torch.Tensor(out_features))
        else:
            self.register_parameter('bias', None)
        self.reset_parameters()

如上代码第7、第9行,大家可以发现,我们新建的线性层的参数weight和bias的初始化,都是使用nn.Parameters()做的,那么我们再看看这个module的玄机(同样是torch源码):

class Parameter(torch.Tensor):
    def __new__(cls, data=None, requires_grad=True):
        if data is None:
            data = torch.Tensor()
        return torch.Tensor._make_subclass(cls, data, requires_grad)

注意第2行,这里正是说明为何model.parameters()迭代出来的所有参数的require_grad属性都是True了,因为它们在被创建时,默认的require_grad就是True。这也符合逻辑,即,使用nn.Parameter()创建的变量是模型参数,本就是要参与学习和更新的;而不参与模型学习和更新的呢?我们再看一个例子:

class _BatchNorm(Module):
    def __init__(self, num_features, eps=1e-5, momentum=0.1, affine=True,  track_running_stats=True):
        super(_BatchNorm, self).__init__()
        self.num_features = num_features
        self.eps = eps
        self.momentum = momentum
        self.affine = affine
        self.track_running_stats = track_running_stats
        if self.affine:
            self.weight = Parameter(torch.Tensor(num_features))
            self.bias = Parameter(torch.Tensor(num_features))
        else:
            self.register_parameter('weight', None)
            self.register_parameter('bias', None)
        if self.track_running_stats:
            self.register_buffer('running_mean', torch.zeros(num_features))
            self.register_buffer('running_var', torch.ones(num_features))
            self.register_buffer('num_batches_tracked', torch.tensor(0, dtype=torch.long))
        else:
            self.register_parameter('running_mean', None)
            self.register_parameter('running_var', None)
            self.register_parameter('num_batches_tracked', None)
        self.reset_parameters()

如以上代码16-18行,这一行定义的三个参数是不参与模型学习的,所以定义在buffer中,buffer的定义方法为self.register_buffer(),所以模型不参与学习和更新的参数是这样定义的、

本文地址:https://blog.csdn.net/weixin_41712499/article/details/110198423