权重衰减 讨论区


#1

http://zh.diveintodeeplearning.org/chapter_deep-learning-basics/weight-decay.html

更新正则化的贝叶斯解释:


#2

我有一些疑问。

  1. from scratch和gluon版本非常相似,为什么loss差了几个数量级,没想明白原因
  2. 文档比较不清楚,比如 net[0].weight.data() 这个用法在API文档里貌似查不到,类似的缺失之处还不少。
  3. parameter的形状不对,按照约定,weight.shape=(num_input, num_output),也就是说net[0].weight.data().shape=(200, 1),但实测是(1, 200),很confusing,应该需要consistent才好。

于置顶 #3

#4

你看到的这个版本是不是weight初始化不太一样?mxnet/gluon的默认初始化是weight = uniform(-0.07, 0.07), bias = 0。

咱们现在的教程还在更新中~


#5

第一个问题应该是这个原因了,谢谢…没想起去查一下net默认的初始化方式,这个default值文档里也没有,只能看源码。教程里应该提一下的。不过我还是没法直接reproduce出来gluon的结果…

另外看了下SGD的文档,也有误,

state = momentum * state + lr * rescale_grad * clip(grad, clip_gradient) + wd * weight

应为

state = momentum * state + lr * rescale_grad * clip(grad, clip_gradient) + lr * wd * weight

额,直播的时候也没写lr,我感觉wd应该是要乘lr的吧,要不wd取1不就减没了?


#6

多谢建议
@piiswrong 你看看这个?


#7

关于第三个问题 我一直都很好奇 因为看别的资料的时候 有W.T * X 也有W*X 但其实都是根据X的shape来调整的 :smile:


#8

图片
这里面的*params什么意思,怎么调用的里面的参数


#9

*params意思是把tuple解包,这样你就可以在函数里用W1,b1,W2,b2…多个参数来接受这个tuple的内容。自己搜Python文档吧,这种问题还是自己查比较好。


#10

当然都是可以的,本质上只是做个转置而已。W.dot.X或者X.dot.W,实际上后面的X, W都相当于前面那个的转置。MXNET别的地方都是用的(num_example, num_inputvar)这样的格式,在这个地方貌似是反过来了,我觉得不好。


#11

确实需要乘一个学习率,是不是老师忘记说了?


#12

好的,谢谢,开始简单搜了一下,没搜到,以为是mxnet的特殊用法,


#13

def get_params():
#为什么乘以0.1?
w = nd.random.normal(shape=(num_inputs, 1))*0.1

为什么上面的赋值运算中,后面要乘以0.1?
前面在定义true_w的时候,是乘以0.01, 这里问什么不乘以0.01而是乘以0.1? 谢谢!


#14

当然可以,其实把系数去掉也可以。如果初始化w的系数在百分位范围,其实收敛的loss更小,即收敛越快。

如下图所示,分为为初始化w乘上1,0.1,和0.01:
6666

11111

2


#15

这个是预先设定好的参数,arbitrary value


#16

确实doc写错了
源码:


#17

不清楚代码结构,挺不好找的。这个问题应该还是需要说明下。还有adam这样lr魔改后的情况怎么处理wd的,我觉得有点意思。


#18

因为L2正则化对应于参数是服从高斯分布的先验假设啊。
平常我们推导线性回归算法时倾向于用最小化平方损失(即最小二乘)的方法来进行参数W的估计,但是如果我们利用最大似然估计的方法(即概率的方法)来推的话,就可以很容易得到正则化的解释了。


没有办法写LaTeX,就在本地写了一下,好麻烦,希望换个支持LaTeX的前端的编辑器啊。


#19

我想是不是这样的:
当我们把L2加入loss,然后求导之后,grad就会包括lambda*w。然后lr * grad = lr * lambda * w。
但是我们可以令weight_decay = lr * lambda,这样weight_decay就等于是一个新的超参。

第二课70分钟的时候沐神有提到过这个,不知道他是不是指的这个意思。

不过看你们发的代码,感觉文档和代码确实有不一致的地方。


#21

文档里的

def net(X,lambd,w,b):
    return nd.dot(X,w) + b

中的lambda定义是不是有点多余的感觉?
毕竟lambda所实际上是在后面的square_loss部分使用到了。
(不过也有可能是为了方便使用者观察net的情况下设置L2范数和在loss里面设置的情况下的不同?