逻辑回归迭代过程权重变化绘图
1 | import numpy as np |
梯度下降算法
1 | def gradAscent(dataMatIn, classLabels,maxCycles=500): |
逻辑回归随机梯度上升算法权重绘制
绘图算法原理:
- 在梯度下降算法的开始定义一个列表
weightlist = []
用于存放每次迭代过程中的==权重==变化,每次迭代使用weightlist.append(weights)
将该次迭代的权重值weights
存入列表,这样便得到了权重历史迭代数据 - 绘图;
- 因为有三个权重,所以使用
plt.subplots(nrows=3, ncols=1, figsize=(20, 15))
将图分为3x1 - X轴为迭代次数,从weightlist长度可以得到
X = range(len(weightlist))
- Y轴即为迭代的权重数据,
W[:, n]
得到第n列数据,W.shape = (100,3)
梯度上升算法原理:
梯度上升法的思想:要找到某函数的最大值 ,最好的方法是沿着该函数的梯度方向探寻。
梯度上升算法的迭代公式:$w := w+\alpha*dw (f(w)) $(dw是关于系数w的梯度,$\alpha$是学习率)
1 | 每个回归系数初始化为1 |
运行结果:
可见两种随机梯度上升算法的权重值W[0],W[1]最后都趋于稳定值。
不同的是没有随机选取样本数据而是顺序遍历每个数据点的stocGradAscent0
方法迭代200(每次遍历全部100给数据点)次后任然没有达到足够的稳定,而使用随机算法选取每次迭代数据点的stocGradAscent1方法在约25次的迭代后就开始收敛了。可见改进后的随机梯度下降算法效果较好。
stocGradAscent1效果较好的原因:
第一点增加了alpha动态减少的机制,这样做的原因是为了保证在多次迭代之后新数据仍然具有一定的影响。
第二点是通过随机选取样本来更新回归系数,这种方法减少周期性的波动。每次随机从列表中选出一个值,然后从列表中删掉该值,重新迭代。
1 | #W权重参数列表W.shape = (m,3),title标题 |
测试
1 | dataset,labelset = loadDataSet() |
1 | weightlist = stocGradAscent1(dataset,labelset,200) |
简单神经网络迭代过程
绘图算法原理:
- 与之前逻辑回归一样,在迭代开始定义一个列表
losslist = []
用于存放每次迭代过程中的==loss==变化,每次迭代使用losslist.append(loss)
将该次迭代的Loss值loss
存入列表,这样便得到了Loss值历史迭代数据 - 绘图与之前一样,不多赘述
梯度下降算法原理:
与梯度上升类似,只不过是计算使得Loss值最小的权重参数,例如$\frac{\partial Loss}{\partial W_1} = 1$说明W1对Loss的贡献是$+1$,那么为了使得Loss值减小:
$W_1 := W_1 - \frac{\partial Loss}{\partial W_1}$,当然这样学习率就默认为1了,可能会离理想的最小Loss值点较远,所以需要设置学习率$\alpha$,做最终就是$W_1 := W_1 - \alpha * \frac{\partial Loss}{\partial W_1}$。实际过程中可能会加入例如ReLU,Sigmoid等激活函数,包含读个隐含层等,这样使用链式求导法则更新各级权重(反向传播)即可。
运行结果:
可见随着迭代次数的增加,Loss值不断减小,符合预期。
1 | import numpy as np |
关于《机器学习实践-Peter Harrington》
我认为书上随机梯度上升算法的迭代图的第一幅图是错误的!!
理由如下:
书上给出的回归曲线y = (-weights[0]-weights[1]*x)/weights[2]
,显然对于回归曲线$\hat{y} = \hat{a} x+b$,$\hat{a}$应该是相近的,至少正负号应该是一样的。按照书上给出的代码 $\hat{a}$ = -weights[1]//weights[2],观察发现$\hat{a} < 0$。这就非常奇怪的,所以我认为是书的错误。