模型参数的访问、初始化和共享 讨论区


#1

http://zh.diveintodeeplearning.org/chapter_deep-learning-computation/parameters.html


#2

参数复用的部分,需要保证两个layer的参数shape相同是吗?


#3


使用的时候,这里arr的值是怎么来的???:sweat_smile:


于置顶 #4

#6

如何实现对不同层使用不同的初始化函数呢?


#7

nd.random.uniform(low=5, high=10, out=arr) 这句赋值的 :laughing:


#8

试了一种比较蠢的办法 :laughing:
params[“sequential1_dense0_weight”].initialize(init=MyInit(), force_reinit=True)
params[“sequential1_dense1_weight”].initialize(init=MyInit2(), force_reinit=True)


#9

手动试了一把,应该必须一致,不然报这个
AssertionError: Cannot retrieve Parameter sequential30_dense0_weight because desired attribute does not match with stored for attribute shape: desired (4, 2) vs stored (4, 4).


#10

两个层共用一个参数求梯度也试了一个,发现两层的梯度值是一样的


#11

这句话不是把arr值赋给out变量吗 :joy:


#12

第一节讲的 nd.elemwise_add(x, y, out=z)
out是方法的形参,表示输出放在z里


#13

喔 好的 自己没仔细 原来前面有讲过 :sweat_smile:


#14
class MyInit(init.Initializer):
    def __init__(self):
        super(MyInit, self).__init__()
        self._verbose = True
    def _init_weight(self, _, arr):
        # 初始化权重,使用out=arr后我们不需指定形状
        print('init weight', arr.shape)
        nd.random.uniform(low=5, high=10, out=arr)
    def _init_bias(self, _, arr):
        print('init bias', arr.shape)
        # 初始化偏移
        arr[:] = 2

# FIXME: init_bias doesn't work
params.initialize(init=MyInit(), force_reinit=True)
print(net[0].weight.data(), net[0].bias.data())

这段代码有点没看懂,主要是以下几点:

  1. self._verbose = True是实现什么功能?
  2. “ 初始化权重,使用out=arr后我们不需指定形状”这个没整明白,这段代码是实现初始化权重参数的原理是啥呢?
  3. 为啥bias没有被初始化呢?(注释中的“FIXME”难道表示这个是一个没修的bug吗?)

#15

关于留的第二个作业,如果直接给每层用不同的初始化函数,会报警,需要把定义net里的参数一致删了吧。。。51


#16

关于沐神留的第三个问题不太懂哎,求了梯度,发现都为0,然后对两个层用了不同的初始化方法,得到的梯度还是0,是不是我哪里没操作对哎???而且梯度为0的话,就是没有变化,这样能说明两个参数一致的神经层有什么特征啊???


#17
@init.register
class MyInit1(init.Initializer):
    def __init__(self):
        super(MyInit1, self).__init__()
        self._verbose = True
    def _init_weight(self, desc, arr):
        # 初始化权重,使用out=arr后我们不需指定形状
        if desc.endswith('weight'):
            print('init weight', arr.shape)
            nd.random.uniform(low=1, high=2, out=arr)
        elif desc.endswith('bias'):
            print('init bias', arr.shape)
            # 初始化偏移
            arr[:] = 1
@init.register
class MyInit2(init.Initializer):
    def __init__(self):
        super(MyInit2, self).__init__()
        self._verbose = True
    def _init_weight(self, desc, arr):
        # 初始化权重,使用out=arr后我们不需指定形状
        if desc.endswith('weight'):
            print('init weight', arr.shape)
            nd.random.uniform(low=2, high=3, out=arr)
        elif desc.endswith('bias'):
            print('init bias', arr.shape)
            # 初始化偏移
            arr[:] = 2
def get_net():
    net = nn.Sequential()
    with net.name_scope():
        net.add(nn.Dense(4, weight_initializer = 'MyInit1', bias_initializer = 'MyInit1'))
        net.add(nn.Dense(2, weight_initializer = 'MyInit2', bias_initializer = 'MyInit2'))
    return net        
# FIXME: init_bias doesn't work
net = get_net()
net.initialize()
net(x)
print(net[0].weight.data(), net[0].bias.data())
print(net[1].weight.data(), net[1].bias.data())

貌似这样可以定制特殊层使用特殊的参数初始化 方法挺笨的


#18

没有反向传播吧


#19

我试了一下,用这种方式可以对不同层实现不同的初始化方式
def get_new_net():
net = nn.Sequential(‘test_’)
with net.name_scope():
net.add(nn.Dense(4, activation=“relu”, weight_initializer = init.One()))
net.add(nn.Dense(2, weight_initializer = init.Xavier()))
return net


#20

我感觉第三个问题应该是说,由于共享了参数,共享的grad产生了两次,共享的weight被更新了两次吧
这个问题该如何验证呢?
@mli


#21

你是如何分别查看共享参数这两层的梯度的?