A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

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

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

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

类神经网络层

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

import math

import torch
from torch.nn.parameter import Parameter
from .. import functional as F
from .module import Module

class 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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
可以看到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)
1
2
3
4
5
可以看出,函数神经网络层的参数需要由用户定义并初始化,然后作为参数传给函数神经网络层。

多层神经网络

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)
---------------------
【转载】
作者:CodeTutor
原文:https://blog.csdn.net/VictoriaW/article/details/72869680


2 个回复

倒序浏览
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马