首页 优德88中文正文

优德88老虎机下载_优德88官方苹果手机版下载安装_w88top优德官网

admin 优德88中文 2019-05-04 312 0

第十一节梯度下降之手动完成梯度下降和随机梯度下降的代码(6)

咱们回想一下,之前咱们讲什么了?梯度下降,那么梯度下降是一种什么算法呢?函数最优化算法。那么它做的是给我一个函数,拿到这个函数之后,我能够求这个函数的导函数,或许叫能够求这个函数的梯度。导函数是一个数儿,梯度是一组数,求出来梯度之后怎样用?把你瞎蒙出来的这组θ值,减去α乘以梯度向量,是不是就得到了新的θ,那么往复这么迭代下去的,是不是越来越小,越来越小,终究到达咱们的最优解的数值解? 你拿到数值解之后,咱们实践上就得到了咱们的一组最好的θ。

回到咱们持续学习的场景来说,咱们想要找到一组能够使丢失函数最小的θ,那么我本来是经过解析解办法能够直接把这θ求出来,可是求的进程太慢了,有或许当你参数太多的时分,所以咱们经过梯度下降法能够得到咱们丢失函数最小那一刻对应的W值,也便是完成了一个咱们这种参数型模型的练习。其实这个东西尽管咱们只讲了一个线性回归,可是逻辑回归svm,岭回归,学了之后,你实质就会发现它是不同的丢失函数,仍是相同运用函数最优化的办法到达最低值,由于都是参数型模型,只需它有丢失函数,终究你就能经过梯度下降的办法找到令丢失函数最小的一组解,这组解便是你练习完了,想要拿到手,用来猜测未来,比方放到拍人更美芯片里边的模型。哪怕深度神经网络也是这样。

在讲梯度下降背面的数学原理之前,咱们上午仅仅从直觉上来讲,梯度为负的时分应该加一点数,梯度为正的时分应该减一点数,并且梯度越大证明我应该越多加一点数,仅仅这么来解说一下梯度下降,那么它背面实践上是有它的理论地点,为什么要直接把梯度拿过来直接乘上一个数,就能到达一个比较快的收敛的这么一个成果,它有它的理论地点的。

在讲这个之前咱们仍是先来到代码,咱们手艺的完成一个batch_gradient_descent。批量梯度下降,还记得批量梯度下降和Stochastic_ gradient_descent什么关系吗?一个是随机梯度下降,一个是批量梯度下降,那么随机跟批量差在哪了?便是核算负梯度的时分,按理说应该用到一切数据,经过一切的数据各自算出一个成果,然后求均匀值.现在咱们改成了直接抽选一条数据,算出成果就直接作为负梯度来用了,,这样会更快一点,这是一个退让。理论向实践的退让,那么咱们先看看完成批量梯度下降来处理。

import numpy as np
#固定随机种子
np.random.seed(1)
#创立模拟练习集
X = 2 * np.random.rand(10000, 1)
y = 4 + 3 * X + np.random.randn(10000, 1)
X_b = np.c_[np.ones((10000, 1)), X]
# print(X_b)
learning_rate = 0.1
n_iterations = 500
#有100条样本
m = 10000
#初始化θ
theta = np.random.randn(2, 1)
count = 0
for iteration in range(n_iterations):
count += 1
gradients = 1/m * X_b.T.dot(X_b.dot(theta)-y)
theta = theta - learning_rate * gradients
print(count)
print(theta)
X = 2 * np.random.rand(10000, 1)
y = 4 + 3 * X + np.random.randn(10000, 1)

上这两行代码仍然是生成一百个X,模拟出对应了一百个Y,这个代码里边咱们不掉现成的包,不像在这用了一个sklearn了,咱们不必sklearn的话,还有什么包帮你好意的生成出一个截距来,是不是没有了?所以咱们是不是仍是要手艺的,在X这里边拼出一个全为1的向量作为X0,现在X_b是一个什么形状呢?100行2列,榜首列是什么?是不是满是1,第二列是什么?随机生成的数。咱们解说下上面代码:

 learning_rate = 0.1
n_iterations = 500

咱们做梯度下降的时分,是不是有一个α?咱们命名它为学习率,拿一个变量给它接住,learning_rate=0.1。那么iterations什么意思? 迭代是吧,n_iterations便是说我最大迭代次数是1万次,一般这个超参数也是有的,由于在你假设假设你的学习率设的欠好,这个程序是不是就变成死循环了?它一向在走,假设你不设一个停止条件的话,你这个东西一练习你有或许就再也停不下来了。所以一般都会有一个最大迭代次数的。当走了1万次之后没收敛,也给我停在这,终究给我报个正告说并没有收敛,阐明你这个东西有点问题。你应该添加点最大次数,或许你调一调你的学习率是不是太小了或许太大了,导致它还没走到或许说走过了震动震动出去了,你需求再去调整。M是这个数据的数量,这一会再说它是干嘛的。

 theta = np.random.randn(2, 1)
count = 0

接下来θ,咱们上来梯度下降,是不是要先蒙出两个θ来,所以我生成两个随机数,np.random.randn(2, 1)这个的意思是生成一个两行一列的-1到+1之间的正态分布的随机数。接下来我就进入for循环:

 for iteration in range(n_iterations):
count += 1
gradients = 1/m * X_b.T.dot(X_b.dot(theta)-y)
theta = theta - learning_rate * gradients

在python2中,假设你输入range(10000),会得到一个列表,从0一向到9999,就实实在在的是一个列表,你把这列表搁进去,进行for循环,会得到什么?榜首次循环的时分,这次此刻的iteration等于0,第2次等于1,由于列表中的每一个元素要赋值到这个变量里边去。那么在python3里边range就不再直接给你实实在在的生成一个列表了,而生成一个python里边绝无仅有的类型叫Generator,生成器。生成器是一个什么?你仅仅想借用这个东西去循环意思,循环一次,你有必要先放一个列表,在那占你的内存空间,没有必要?实践上它是一个懒加载的这么一个东西,你每次迭代榜首次回来0第2次回来1,每次迭代就给你回来一个数,生成器实质它就变成一个函数了,你榜首次调用它回来零,第2次掉他回来一,第三次调用它回来二,它里边记录了自己当时到哪了,并且生成规矩,这样就没有必要去占用你的内存空间了,这个是range一般是用来做for循环用的,就为了有一个序号。 还有另一种高档的用法是enumerate,假设你用一个enumerate(list),它会给你回来两个数,榜首个是索引号,第二个是list中的自身的元素。在这用逗号能够把这两个变量别离仿制给你指定的两个变量名。

for i,a in enumerate(list):
print(i,a)
那么i在此刻实践上便是li1里边的榜首个元素的索引号是零,第二个元素便是自身是什么什么,这个是一个很便利的技巧,能够帮你在for循环体内部既需求索引号来核算它的方位,又需求这个数据自身的时分能够直接用enumerate一次性的把它取出来,很简略的一个技巧。
gradients = 1/m * X_b.T.dot(X_b.dot(theta)-y)
theta = theta - learning_rate * gradients

那么在这咱们只需求n_iterations给他做个计数器就好了,所以我在这儿只用它。那么咱们看这count默许是零,他是一个计数器,每次循环会自己加1,+=咱们都应该能看懂,自己自加1,那么此刻的gradients实践上便是X_b的转置。乘以它,再乘以1/m。gradients = 1/m * X_b.T.dot(X_b.dot(theta)-y)。这一步里边有没有加和?是批量梯度下降带加和的版别,仍是随机梯度下降,不带加和的版别?由于X_B是个矩阵,

实践上你看X_b是不是一个矩阵,Y是一个向量,咱们需求看Y是个行向量仍是列向量, X是一百行一列的,Y是一百行一列的,它是一个列向量。然后用最开端的X转置去乘以列向量,实践上矩阵乘以一个向量的时分,自身就拿榜首行乘以榜首列加第二行乘以榜首列,自身就把加和融在矩阵乘法里边去了。所以实践上1/m * X_b.T.dot(X_b.dot(theta)-y)这个东西自身就现已是带加和的了,并且如前面所说是不是一定要加一个M分之一?接下来完成梯度下降是不是十分简略,拿上一代的θ减去learnrate,乘以你核算出来的梯度就完事了! 也便是

 theta = theta - learning_rate * gradients

咱们看梯度下降,尽管讲了半响感觉很杂乱,其实四行代码完毕了,那么在履行完了这1万次迭代之后,咱们把θ给打印出来,看看成果,我没有完成那个tolerance,没有断定。假设这样我每一步都让它打印θ。

 for iteration in range(n_iterations):
count += 1
gradients = 1/m * X_b.T.dot(X_b.dot(theta)-y)
theta = theta - learning_rate * gradients
if count%20==0:
print(theta)

咱们看看θ跟着更新,它很早你发现是不是都现已收敛了其实?你看她经过多少次收敛的,上来是3.27,3.52,下次渐渐在改变改变,每一步都走的还比较稳健,到4.00,4.04,


是不是越走越慢了,你发现。你看榜首部时分从3.27到3.51,到后来4.04,4.07是不是越走越慢了?4.10,4.12,为什么会越走越慢,学过梯度下降,你们现在是不是应该知道了?由于越挨近谷底,它的梯度值怎样样?越大仍是越小? 越小,它天然就越走越慢,越小走的越慢。那么终究到4.18,收敛了再也不动,可是咱们循环是不是还在往下一向持续,只不过每次加的梯度都是怎样样?零。

再有一个问题,方才我的数据集里边并没有做归一化,那么实践上它需求做最大最小值归一化吗?实质上不太需求,由于它只要一个W,只要一个W的时分天然做归一化是无所谓的,假设你有多个W的情况下,你对每一个X在预先处理之前做都需求做归一化,其实也是两行代码的事。咱们参加最大最小值归一化的办法:

 X_b[:,1]=X_b[:,1]-X_b[:,1].mean()

X_b[:,1]这个冒号什么意思?这个冒号便是一个索引办法,我要取一切的行,我就打一个冒号:,你取一切的行的榜首列,就写个1,X_b[:,1]其实是一个一维数组,便是那一堆一百个随机数,那么X_b[:,1].mean()加一个.mean,你能够看到它的均匀是多少?0.95。 假设你用X_b[:,1]=X_b[:,1]-X_b[:,1].mean(),会主动的帮咱们对位相减,每一个数都减减去它。然后咱们此刻在看咱们剪完了之后的成果,是不是就变成有正有负的了?


此刻在做梯度下降,按理说速度应该更快一些,咱们看方才咱们迭代次数是多少,取决于你初始化的点,假设你初始化的点好的话是没有差异的,假设初始化的点欠好的话就有差异。咱们运转一下,你看一下,我等待它会有改变。需求多少次?331.方才有多少次?500屡次,现在只需求300屡次,就证明方才随机那个点,实践上关于能不能正负一同优化,是不是有实践的敏感度的,你现在做了一个均值归一化,实践上发生了什么问题? 迭代次数变得更好了,更少了,就更快地到达了收敛的值。可是你发现它W1和W0也变了,


肯定会变,由于你的整个数值全都变了,但变了不要紧。怎样样才干持续用起来?你这变过之后的W,对你新猜测的数据拿回来之后先做相同的归一化,你再去猜测成果也是正确的。

有了批量梯度下降的代码,咱们再看随机梯度下降的话,就简略多了。先上代码:

import numpy as np
from sklearn.linear_model import SGDRegressor
#固定随机种子
np.random.seed(1)
#生成练习集
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
X_b = np.c_[np.ones((100, 1)), X]
print(X_b)
n_epochs = 1000#迭代次数
t0, t1 = 5, 50
m = 100
#设置可变学习率
def learning_schedule(t):
return t0 / (t + t1)
#初始化θ
theta = np.random.randn(2, 1)
#随机梯度下降
learning_rate = 0.1
for epoch in range(n_epochs):
for i in range(m):
random_index = np.random.randint(m)
# 为了处理维度问题,在索引屈指
xi = X_b[random_index:random_index+1]
yi = y[random_index:random_index+1]
gradients = 2*xi.T.dot(xi.dot(theta)-yi)
learning_rate = learning_schedule(epoch*m + i)#跟着迭代次数添加,学习率逐步减小。
theta = theta - learning_rate * gradients
print(theta)
SGDRegressor

解说下:np.random.seed(1),确认随机种子,这是不是万年不变的老三样,没有什么改变,然后咱们仍是n_iterations,一共迭代一千次。n_epochs = 1000。为什么是两层for循环?我详尽的给咱们说,首要我是不是随机梯度下降,我要有一个随机,我要随机选出一条数据来,我在这一部分

 random_index = np.random.randint(m)
xi = X_b[random_index:random_index+1]
yi = y[random_index:random_index+1]

都是在随机的选X和Y,randint(m)代表从0到99随机选出一个数字来作为index,作为索引,选出来之后,我的X是不是要从X里边把这个随机位的索引给取出来,所以我取出来X的索引。那么Y是不是为了随机取出来索引,这两个xi = X_b[random_index:random_index+1], yi = y[random_index:random_index+1]便是把对应的那一条X和对应的Y给搞出来。那么梯度就经过那一个X乘以了一个Y, gradients = 2*xi.T.dot(xi.dot(theta)-yi)得到了单个核算出来的梯度,你说这个表达式怎样没变,表达式是不必变,只不过本来的X矩阵是一百行两列,现在X矩阵变成一行两列,你表达式是不必变的,一行主动指出来一个数就不再是一个向量了,那么此刻用learning_rate,我本来是不是定死了便是0.1,而现在我的learning_rate变成了learning_schedule回来的一个成果,我看我界说的learning_schedule是什么?

 def learning_schedule(t):
return t0 / (t + t1)

界说了两个超参数,别离是t0和t1,你丢进一个t来,你看t越大,return这个值会怎样样? 越小,那么咱们看t一共能到多少?是不是epoch*m+i, epoch从哪来的?是不是从n_epochs来的,也便是上来循环榜首次的时分它是多少?0,此刻你看return成果这算算是多少,是不是便是零?那么你看此刻的t是零,此刻的learning_schedule回来的是一个多大的数,是不是0.1?也便是榜首次履行的时分学习率是多少?0.1。当我内层循环第101次履行的时分此刻epoch等于多少? 等于1。epoch*m+i越来越大,那么此刻的学习率learning_schedule是上升了仍是下降了?变大了仍是变小了? 变小了一点,也便是说跟着迭代的加深,epoch是不是越来越大?传到这里边数也越来越大,学习率是越来越小的,所以这个也是梯度下降的一种变种。它会把学习率跟着迭代的次数推动,让学习率越来越小,这样确保你就能够设置一个初始的时分比较大的学习率,这样你学习率假设设大了,它也不会一向震动越远,由于跟着迭代越多,梯度越来越小。在咱们sklearn 里边的SGDRegressor函数是有相关的超参数能够设置的。

 def __init__(self, loss="squared_loss", penalty="l2", alpha=0.0001,
l1_ratio=0.15, fit_intercept=True, max_iter=None, tol=None,
shuffle=True, verbose=0, epsilon=DEFAULT_EPSILON,
random_state=None, learning_rate="invscaling", eta0=0.01,
power_t=0.25, warm_start=False, average=False, n_iter=None):
super(SGDRegressor, self).__init__(loss=loss, penalty=penalty,
alpha=alpha, l1_ratio=l1_ratio,
fit_intercept=fit_intercept,
max_iter=max_iter, tol=tol,
shuffle=shuffle,
verbose=verbose,
epsilon=epsilon,
random_state=random_state,
learning_rate=learning_rate,
eta0=eta0, power_t=power_t,
warm_start=warm_start,
average=average, n_iter=n_iter)

loss="squared_loss",这个是什么? 便是说SGDRegressor是一个通用的机器学习的办法,你能够自己通知他我的丢失函数是什么,你别管丢失函数是什么,我给你经过SG的方向一向下降得到一个成果,你要把MSE传给我,你得到便是一个线性回归的成果,你要把一个mse加L2正则的丢失函数给我,我得到的便是一个岭回归的成果,就丢失函数不同,你的算法其实就改变了,那么在SGD它是不绑缚算法自身的,你给我什么丢失函数履行出来什么样,我便是一个帮你下降做核算题的机器。那么默许的便是squared_loss,alpha实践上是指的l1跟l2中心的一个超参数,l1_ratio也相同,这两个超参数是依附在penalty之上的一个超参数,咱们讲完了正则化之后,你就明它什么意思了。

fit_intercept=True,这个什么意思,截距是不是要帮你搞出来。max_iter=None,什么意思?最大迭代次数,它没设。tol是什么意思,收敛次数。shuffle=True,shuffle什么意思?shuffle实践上把数据乱序。你上来不是给了我一堆X吗?我帮你先洗个牌乱一下序再进行练习,关于咱们这种算法来说是否乱序不影响终究核算成果。random_state=None便是随机种子.learning_rate="invscaling", learning_rate是学习率,那么看learning_rate都有哪些能够挑选的当地?constant什么意思?常数,那么此刻的eta学习率一般也用eta表明就等于eta0,后边是不是还有一个eta0,假设你在这写一个learning_rate=constant,后边eta0赋一个值,实践上便是一个定值的学习率。然后它有两种变种的,一个叫optimal,优化的,用1.0/(alpha*(t+t0))。别的一个是什么?T的power T次方,便是T的N次方,这种办法叫invscaling。它们都是差不多,它们都是想让这学习率越往下走越小,这么一种可变学习率的调整办法,那么默许是运用invscaling倒置缩放的这种办法来做的,也便是说实践上咱们现在就了解到,在sklearn中并没有运用这种定值的学习率,默许的完成里边,并不是运用固定的学习率来做梯度下降的,而是运用这种可变学习率来做的。

聊了这么多梯度下降的逻辑和进程,有没有对其底层原理感兴趣,所以下一节咱们将解说梯度下降的底层原理。

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

最近发表

    优德88客户端_优德88游戏_w88优德官网登录

    http://www.lcsjm.com/

    |

    Powered By

    使用手机软件扫描微信二维码

    关注我们可获取更多热点资讯

    w88出品