Why lasso can't produce sparse solution in pytorch
lasso = linear model +
在pytorch试图实现lasso regression
分析:pytorch 是用SGD 优化,SGD不可以直接求解lasso, 在0点处绝对值函数不可导。
**结论:**它是直接求的,$\beta^{k+1} = \beta^{k} +\eta\cdot X^T(y-X\beta^k) + \lambda sgn(\beta^k)$ .
这种求法被叫做 SGD-L1 naive,导致了$\beta^{k+1}$ 几乎不会严格等于0,可能在0附近震荡。
一个自然的想法:SGD-L1 clipping, 每一次梯度更新后对参数做 soft-threshold.
python sklearn SGD regressor就是这么干的:the update is truncted to 0 to allow for learning sparse models
给一篇参考文献:Stochastic Gradient Descent Training for L1-regularized Log-linear Models with Cumulative Penalty。
-
产生真实的beta, sample size n = 100, dim p =10, 前两个系数为10,10,第三个第四个是-10,其它为0.
np.random.seed(5) n = 100 p = 10 beta = np.zeros([p]).astype(np.float32) beta[0] = 10 beta[1] =10 beta[2] = -10 beta[3] =-10 X = np.random.rand(n,p).astype(np.float32) Y = np.dot(X,beta) a = torch.from_numpy(X) b = torch.from_numpy(Y.reshape(-1,1))
-
SGD-L1 naive
可以看到,前四个变量估计的不错,分别在+10和-10附近,和sklearn的lasso结果也很接近。后6个变量的系数非常小,对prediction应该影响不大,但是没有exactly 等于0,所以不是稀疏解
-
SGD-L1 clipping
三个结果,第一个SGD-L1 clipping, 可以看到,后6个变量系数exactly 被压缩到0了,第三个结果是 sklearn SGDRregressor方法,它用的是参考文献中的clipping方式,效果会好一点,但改进不大了,而且也没有什么理论支持。
- L1 regularization在PyTorch中,SGD无法直接产生稀疏解,需要每一次参数更新后做soft-threshold.
- code放到了我的github,有需要的朋友可自取(并点个star)