梯度下降法
1.基本思想
函数变化最快的方向及函数的梯度方向。故想要找到函数的一个最低点,就可以沿函数的负梯度方向进行搜素,并不断改变当前x的值,再沿梯度方向进行搜素。直到达到自己设定的步数或者小于自己设定的损失差时停止搜索。
梯度下降法步骤:
1.确定损失函数
假设函数: h θ ( x ) = θ 0 + θ 1 x h_\theta(x)=\theta_0+\theta_1x hθ(x)=θ0+θ1x
均方差代价函数: j ( θ 0 , θ 1 ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 j(\theta_0,\theta_1)=\frac{1}{2m}\sum_{i=1}^{m}({h_\theta(x^{(i)})-y^{(i)})^2} j(θ0,θ1)=2m1∑i=1m(hθ(x(i))−y(i))2
2.对损失函数求偏导
∂ ∂ θ j J ( θ 0 , θ 1 ) = ∂ ∂ θ j 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 \frac{\partial }{\partial \theta_j}J(\theta_0,\theta_1)=\frac{\partial}{\partial \theta_j}\frac{1}{2m}\sum_{i=1}^{m}({h_\theta(x^{(i)})-y^{(i)})^2} ∂θj∂J(θ0,θ1)=∂θj∂2m1∑i=1m(hθ(x(i))−y(i))2
θ 0 : j = 0 \theta_0:j=0 θ0:j=0: ∂ ∂ θ 0 J ( θ 0 , θ 1 ) = 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) \frac{\partial }{\partial \theta_0}J(\theta_0,\theta_1)=\frac{1}{m}\sum_{i=1}^{m}({h_\theta(x^{(i)})-y^{(i)})} ∂θ0∂J(θ0,θ1)=m1∑i=1m(hθ(x(i))−y(i))
θ 1 : j = 1 \theta_1:j=1 θ1:j=1: ∂ ∂ θ 1 J ( θ 0 , θ 1 ) = 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) ∗ x ( i ) \frac{\partial }{\partial \theta_1}J(\theta_0,\theta_1)=\frac{1}{m}\sum_{i=1}^{m}({h_\theta(x^{(i)})-y^{(i)})*x^{(i)}} ∂θ1∂J(θ0,θ1)=m1∑i=1m(hθ(x(i))−y(i))∗x(i)
3.应用梯度下降法修改不断当前值
θ 0 \theta_0 θ0= θ 0 − α ∗ \theta_0-\alpha* θ0−α∗ ∂ ∂ θ 0 J ( θ 0 , θ 1 ) = 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) \frac{\partial }{\partial \theta_0}J(\theta_0,\theta_1)=\frac{1}{m}\sum_{i=1}^{m}({h_\theta(x^{(i)})-y^{(i)})} ∂θ0∂J(θ0,θ1)=m1∑i=1m(hθ(x(i))−y(i))
θ 1 \theta_1 θ1= θ 1 − α ∗ \theta_1-\alpha* θ1−α∗ ∂ ∂ θ 0 J ( θ 0 , θ 1 ) = 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) ∗ x ( i ) \frac{\partial }{\partial \theta_0}J(\theta_0,\theta_1)=\frac{1}{m}\sum_{i=1}^{m}({h_\theta(x^{(i)})-y^{(i)})*x^{(i)}} ∂θ0∂J(θ0,θ1)=m1∑i=1m(hθ(x(i))−y(i))∗x(i)
注: α \alpha α为学习速率(learning rate),自行设置
2.例子:
1.以 y = x 2 − 1 y=x^2-1 y=x2−1求解其最小值
#f(x)=x^2-1
def fun_1(x):
return x**2+1
#grad(f)=2x
def grad_1(x):
return 2*x
#grad_1 导数函数,cur_x x的起始值,lr 学习速率 ,precssion , max_step 最大步数
def grad_descent(grad_1,cur_x=0.1,learning_rate=0.03,precision=0.0000001,max_steps=1000):
for i in range(max_steps):
grad=grad_1(cur_x)
deleta=cur_x*grad
# if(abs(grad)<precision):
# break;
if(abs(deleta)<precision):
break;
cur_x=cur_x-grad*learning_rate
print('第',i,'次x的值为:',cur_x)
print('局部最小值为:',cur_x)
return cur_x
grad_descent(grad_1,10,0.02)
其中,learn-rate需要自行尝试确定出合适的值
2.作业: y = ( x − 2.5 ) 2 + 3 y=(x-2.5)^2+3 y=(x−2.5)2+3
def fun_2(x):
return (x-2.5)**2+3
def grad_2(x):
return 2*(x-2.5)
#grad_1 导数函数,cur_x x的起始值,lr 学习速率 ,precssion , max_step 最大步数
def grad_descent_1(grad_1,cur_x=0.1,learning_rate=0.03,precision=0.0000001,max_steps=1000):
for i in range(max_steps):
grad=grad_1(cur_x)
deleta=cur_x*grad
# if(abs(grad)<precision):
# break;
if(abs(deleta)<precision):
break;
cur_x=cur_x-grad*learning_rate
print('第',i,'次x的值为:',cur_x)
print('局部最小值为:',cur_x)
return cur_x
grad_descent_1(grad_2,10)
3. y = − e − ( x 2 + y 2 ) y=-e^{-(x^2+y^2)} y=−e−(x2+y2)
def fun_3(x):
return -math.exp(-(x[0]**2+x[1]**2))
def grad_3(x):
x_1=2*x[0]*math.exp(-(x[0]**2+x[1]**2))
x_2=2*x[1]*math.exp(-(x[0]**2+x[1]**2))
return np.array([x_1,x_2])
def grad_descent_2(grad_1,cur_x=np.array([0.1,0.1]),learning_rate=0.03,precision=np.array([0.00001,0.00001]),max_steps=100000):
for i in range(max_steps):
grad=grad_1(cur_x)
print(grad)
deleta=learning_rate*grad
print(deleta)
# if(abs(grad)<precision):
# break;
# if np.linalg.norm(grad, ord=2) < precision:
# break # 当梯度趋近为 0 时,视为收敛
if((abs(deleta[0])<precision[0])&abs((deleta[1])<precision[1])):
break;
cur_x=cur_x-grad*learning_rate
#cur_x=cur_x-np.multiply(grad,learning_rate)
#print(grad)
#print(deleta[0],' ',deleta[1])
print('第',i,'次x的值为:',cur_x)
print('局部最小值为:',cur_x)
return cur_x
grad_descent_2(grad_3,cur_x=np.array([1,1]))
3.梯度下降法分类
1.批量梯度下降(也称为原始梯度下降)计算训练数据集中每个样本的误差,但是每次更新参数都会使用所有的训练样本:
w j , w_j^, wj,= = w j − 1 m ∑ i = 1 m ( ∑ j = 0 n w j x i j − y i ) x i j =w_j- \frac{1}{m}\sum_{i=1}^{m}(\sum_{j=0}^{n}w_jx_{ij}-y_i)x_{ij} =wj−m1∑i=1m(∑j=0nwjxij−yi)xij
它的优点是它具有计算效率,它可以产生稳定的误差梯度和稳定的收敛。 批量梯度下降的缺点是稳定的误差梯度有时会导致收敛状态不是模型可以达到的最佳状态。 它还要求整个训练数据集在内存中并可供算法使用。也就是说对内存的要求很高。每一次迭代下对每个参数进行更新的时候,都要计算所有的数据,因此在样本数量很大的时候比较耗时
2.相反,随机梯度下降(SGD)对数据集中的每个训练样本都进行更新操作。这意味着它会逐个更新每个训练样本的参数。这可以使SGD比批量梯度下降更快,具体取决于问题。 一个优点是频繁的更新使我们有一个非常详细的改进率。
事实上,频繁更新作为批量梯度下降的方法在计算上更加昂贵。这些更新的频率也可能导致噪声梯度,这可能导致错误率跳跃,而不是缓慢下降。因此,它的下降过程是个杂乱的过程,看起来没有顺序。
以上述为例,我们写出每个样本(这里以第 i 个样本为例)的目标函数(损失函数):
1 2 ( ∑ j − 0 n w i j − y i ) 2 \frac{1}{2}(\sum_{j-0}^{n}w_{ij}-y_i)^2 21(∑j−0nwij−yi)2
每个样本都会更新所有的参数: w j , = w j − ( ∑ j = 0 n w j x i j − y i ) x i j w_j^,=w_j-(\sum_{j=0}^{n}w_jx_{ij}-y_i)x_{ij} wj,=wj−(∑j=0nwjxij−yi)xij
随机梯度下降在每一次迭代的时候,先循环每个样本,对每个样本都更新所有的权重。
3小批量梯度下降是首选方法,因为它结合了随机梯度下降(SGD)和批量梯度(BGD)下降的概念。 它只是将训练数据集拆分成小批量,并为每个批次执行更新。 因此,它在随机梯度下降的稳健性和批量梯度下降的效率之间创造了平衡。
常见的小批量大小介于50到256之间,但与任何其他机器学习技术一样,没有明确的规则,因为它们可能因不同的应用而异。 请注意,它是您训练神经网络时的首选算法,它是深度学习中最常见的梯度下降类型。
它的迭代首先需要将样本数据划分成很多个组,对每一次迭代来说,先循环所有的组,对每个组内的数据采用批量梯度下降的方式循环。
总结一下,随机梯度下降可能不是很快能找到最优的结果,因为它是跳跃着进行的,而批量梯度下降能快速的找到最优解,但是对内存要求较高。