损失函数(Loss Function)
损失函数是用来估量模型的预测值与真实值的不一致程度,是一个非负实值函数, 损失函数越小,模型的鲁棒性就越好。损失函数越小表示算法达到意义上的最优。
nn.CrossEntropyLoss(多分类交叉熵损失函数)
深度神经网络中的优化器有各种各样的方法
梯度下降
参考:梯度下降法
梯度下降法(gradient descent)或最速下降法(steepest descent),是求解无约束最优化问题的一种最常用的方法。梯度下降法是一种迭代算法, 每一步会求解目标函数的梯度向量。
梯度的本意是一个向量, 表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向的变化最快, 变化率最大(梯度的模)
对于函数来说, 其梯度就是
。对于给定点
的附近处, 它在
方向变化率最大。在点
附近处, 其梯度方向就是
, 朝着这个方向移动,会使得函数值增加的速率最快。
例:
, 这里,
是
在
的梯度。
假定设置了一个初始值, 现在需要确定一个
, 代入上式可得:
, 为了使得
最小(贪心策略), 应该有:
可以得到
其中定义为学习率,它实际上步长除以梯度的模。因此当学习率一定时, 步长其实是一直变化的。当梯度较大时,步长也较大;而当梯度较小时,步长也较小。这往往是我们希望的性质, 因为当接近于局部最优解时,梯度变得较小, 这时往往也需要步长变得更小,以有利于找到局部最优解。
其中,学习率要足够小,使得(1)满足泰勒公式所需要的精度。(2)能够很好地捕捉到极小值。
然而, 局限性
由于“梯度过小”,梯度下降法可能无法确定前进的方向了。即使人为增加收敛条件中的精度,也会由于梯度过小,导致迭代中前进的步长距离过小,循环时间过长。
梯度下降法实现简单,原理也易于理解,但它有自身的局限性,因此有了后面很多算法对它的改进。对于梯度过小的情况,梯度下降法可能难以求解。
此外,梯度下降法适合求解只有一个局部最优解的目标函数,对于存在多个局部最优解的目标函数,一般情况下梯度下降法不保证得到全局最优解(由于凸函数有个性质是只存在一个局部最优解,所有也有文献的提法是:当目标函数是凸函数时,梯度下降法的解才是全局最优解)。
由于泰勒公式的展开是近似公式,要求迭代步长要足够小,因此梯度下降法的收敛速度并非很快的。
利用梯度下降法求根号2的值
梯度下降法用来求函数的极值。假设一个函数可导,要计算其极值,求解过程为
。对于一般的函数,我们可以使用梯度下降法来迭代计算。具体地, 不断进行如下更新:
直到,求得函数的极值。
倘若一个函数的极小值是根号2, 我们即可通过梯度下降法找到这个极值点。这个函数应该满足以下条件:【函数在某个区间内,只有根号2这一个极值点。假设求根号2为极小值点】
解:
如果函数的极小值是根号2, 那么它的导函数是以根号2为根。在上述区间内,导函数单调递增且经过零点
梯度下降法代码:
def gradient_descent(y):
x = 1
alpha = 0.001
deta = 1
count = 1
while abs(deta) > 0.00001:
deta = 4 * x * (x * x - y)
x -= alpha * deta
count = count + 1
return x
y = 2
ans = gradient_descent(y)
print(ans)
利用二分法求根号2的值
使用二分法求解开根号的值比较简单,但是运行的效率较低,花费较长的时间。
def binary_search(y):
l = 0
r = y
mid = (l + r) / 2
while True:
if mid * mid <= y and (mid + 0.00001) * (mid + 0.00001) > y:
break
if mid * mid <= y:
l = mid + 0.00001;
mid = (l + r) / 2;
elif mid * mid > y:
r = mid - 0.00001
mid = (l + r) / 2
return mid
y = 2
ans = binary_search(y)
print(ans)
利用牛顿迭代法求根号2的值
牛顿法不仅可以用来求解函数的极值问题, 还可以用来求解方程的根。二者在本质上是一个问题。因为求解函数极值的思路是寻找导数为0的点, 如果要求的极值, 也就是求
的根。
机器学习中的优化器
求解根号2的值, 转化成函数
, 求解该函数的近似正根。
def deal_num(y):
# 初始化x值
x = 2
fx = x ** 2 - y
while 1:
if fx < 0.0000001:
break
else:
x = x - fx / (2.0 * x)
fx = x ** 2 - y
return x
y = 2
ans = binary_search(y)
print(ans)