PyTorch学习系列(九)——参数_定义

来源:互联网 发布:苏州关键词优化 编辑:程序博客网 时间:2024/05/17 22:01

不知道国家在偷偷搞什么,2017.7.1又封了很多翻墙软件。亲们要珍惜能用Google的日子,想到以后只能用百度来搜索问题,真的会死人的。


我们已经知道如何在PyTorch下构建神经网络,参考PyTorch学习系列(三)——构建神经网络。但是读者会不会有这样的疑问:神经网络的参数是什么时候定义的?采用了何种初始化方式?怎么查看指定参数?本文就来聊聊PyTorch中神经网络的参数。

在介绍构建神经网络时,我们提到两种神经网络层:类神经网络层和函数神经网络层。下面我们会分开介绍两种网络层的参数定义及初始化。

类神经网络层

读者稍微思考一下之后,应该可以猜出来参数是在类神经网络层中定义的。我们以线性层类torch.nn.Linear为例:

import mathimport torchfrom torch.nn.parameter import Parameterfrom .. import functional as Ffrom .module import Moduleclass Linear(Module):#继承自Module    r"""Applies a linear transformation to the incoming data: :math:`y = Ax + b`    Args:        in_features: size of each input sample        out_features: size of each output sample        bias: If set to False, the layer will not learn an additive bias. Default: True    Shape:        - Input: :math:`(N, in\_features)`        - Output: :math:`(N, out\_features)`    Attributes:        weight: the learnable weights of the module of shape (out_features x in_features)        bias:   the learnable bias of the module of shape (out_features)    Examples::        >>> m = nn.Linear(20, 30)        >>> input = autograd.Variable(torch.randn(128, 20))        >>> output = m(input)        >>> print(output.size())    """    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()    def reset_parameters(self):        stdv = 1. / math.sqrt(self.weight.size(1))        self.weight.data.uniform_(-stdv, stdv)        if self.bias is not None:            self.bias.data.uniform_(-stdv, stdv)

可以看到Linear神经网络层的参数是作为属性存在的,并且参数是Parameter对象。Parameter类是Variable的子类,但和Variable类不同的是,Parameter在作为Module的属性时,会自动加入到Module的参数列表。

函数神经网络层

至于函数神经网络层中的参数,我们仍以线性层为例:

def linear(input, weight, bias=None):    if bias is None:        return _functions.linear.Linear.apply(input, weight)    else:        return _functions.linear.Linear.apply(input, weight, bias)

可以看出,函数神经网络层的参数需要由用户定义并初始化,然后作为参数传给函数神经网络层。

多层神经网络

Mudule对象显式定义的Parameter类型的属性会放到self._parameters字典中,显式定义的Module类型的属性(子Module)会放在self._modules。取Module所有参数的函数Module::parameters()会递归地获得子Module的self._parameters。

    def __setattr__(self, name, value):        def remove_from(*dicts):            for d in dicts:                if name in d:                    del d[name]        params = self.__dict__.get('_parameters')        if isinstance(value, Parameter):#Parameter类型的属性            if params is None:                raise AttributeError(                    "cannot assign parameters before Module.__init__() call")            remove_from(self.__dict__, self._buffers, self._modules)            self.register_parameter(name, value)        elif params is not None and name in params:            if value is not None:                raise TypeError("cannot assign '{}' as parameter '{}' "                                "(torch.nn.Parameter or None expected)"                                .format(torch.typename(value), name))            self.register_parameter(name, value)        else:            modules = self.__dict__.get('_modules')            if isinstance(value, Module):#Module类型的属性                if modules is None:                    raise AttributeError(                        "cannot assign module before Module.__init__() call")                remove_from(self.__dict__, self._parameters, self._buffers)                modules[name] = value            elif modules is not None and name in modules:                if value is not None:                    raise TypeError("cannot assign '{}' as child module '{}' "                                    "(torch.nn.Module or None expected)"                                    .format(torch.typename(value), name))                modules[name] = value            else:                buffers = self.__dict__.get('_buffers')                if buffers is not None and name in buffers:                    if value is not None and not torch.is_tensor(value):                        raise TypeError("cannot assign '{}' as buffer '{}' "                                        "(torch.Tensor or None expected)"                                        .format(torch.typename(value), name))                    buffers[name] = value                else:                    object.__setattr__(self, name, value)

参数的初始化方法请看下一篇博客:PyTorch学习系列(九)——参数_初始化

原创粉丝点击