关于WGAN中Parameter Clip的问题


#1

在实现WGAN的时候遇到了这个问题
尝试过两种写法:

    # clip1
    for p in netD.params.values():
        p.set_data(nd.clip(p.data(ctx=ctx),-0.01,0.01))
    # clip2
    for p in netD.collect_params():
         data = netD.collect_params().get(p).data()
         netD.collect_params().get(p).set_data(nd.clip(data, -0.01, 0.01))  

第一种写法没有报错,但是貌似并没有成功,并没有做clip。
第二种写法runtime error:Parameter ‘sequential1_sequential1_conv0_weight’ has not been initialized. Note that you should initialize parameters and create Trainer with Block.collect_params() instead of Block.params because the later does not include Parameters of nested child Blocks

netD和netG是网上课程中DCGAN的写法。

请问MXnet/Gluon中如何做Param clip是正确的?WGAN的Gluon实现


#2

你要先net.initialize()然后forward一遍


#3

谢谢!
我刚刚在MXnet的文档中,也发现了


#4

你好,你最后clip成功了吗?我怎么先forward了一篇,还是跟你一样的错误呢?


#5

你好,我觉得我clip成功了,因为没有报错了,也跑出来图了。
在训练之前的clip:
out = netD(nd.random.normal(shape=(64,3,64,64), ctx = ctx))
# clip D
for p in netD.collect_params().values():
p.data()[:] = nd.clip(p.data(ctx=ctx),-0.01,0.01)

如果是在训练之中的话,就不用故意forward了,算loss的时候自然forward了。
但是这里有另外一个问题,好像是关于异步的惰性计算的,有个小坑,(我也不是很熟悉MXNet,猜的):
# clip D
for p in netD.collect_params().values():
p.data().wait_to_read()
p.data()[:] = nd.clip(p.data(ctx=ctx),-0.01,0.01)
加上wait_to_read就解决了。
祝成功!


#6

果然,不加wait_to_read就会报之前你说的那个错


#7

第二种方法导致Parameter ‘sequential1_sequential1_conv0_weight’ has not been initialized的原因,主要是因为你再调用 ParameterDict方法的时候会给param的name添加一个字典的prefix,官方API解释


所以你可以发现输出错误信息中的Parameter参数的name中包含了两个sequential1,所以你只要在调用ge方法之前将p的prefix去掉即可,代码如下

    for p in netD.collect_params():
         p  = p.replace(netD.prefix,"")
         data = netD.collect_params().get(p).data()
         netD.collect_params().get(p).set_data(nd.clip(data, -0.01, 0.01))