标题来自张玉宏老师书的目录《深度学习之美》
之前的推文中使用最小二乘法求损失函数的最小值,但是在机器学习和深度学习中更通用的方法是使用梯度下降方法找到最优解。
梯度下降:核心就是希望能够通过数学意义上的迭代运算,从一个随机点出发,一步步逼近最优解。
梯度:有大小和方向,用导数求得大小,目标函数变化最快的方向的反方向作为移动的方向
方向:往哪个方向走
步长:每一步走多远
学习率:在梯度下降过程中,学习率乘以梯度大小为步长。学习率如果过小,损失函数的变化速度很慢,会大大增加网络的收敛复杂度,并且很容易被困在局部最小值或者鞍点
迭代:数学上的迭代,第一步运算的结果带入到第二步的函数中,以此类推
其实是预测值减去真实值的平方除以2倍的样本数m(即0.5*MSE),多乘以0.5可以消除掉平方求导后的系数2
x是特征,只有一个;y是真实标签
如果需要对$y=wx=ax+b$建模的话,需要找到一个a和b,使得损失函数L最小
x | y |
---|---|
1 | 2 |
2 | 4 |
3 | 6 |
设步长$\alpha = 0.01$, 初始点$w_0=0$,迭代次数为10000
import torch
def g(X, y, alpha = torch.tensor(0.01, requires_grad = True), n = 10000):
b=torch.ones(X.shape[0], requires_grad = True,dtype=torch.float32).reshape(-1,1)
X = torch.cat([X,b],1)
m, nc = X.shape
w = torch.zeros(nc, 1, requires_grad = True)
for _ in range(n):
grad = torch.mm(X.t(), (torch.mm(X, w) - y))/m
w = w - alpha * grad
return w
因为函数g中,可以给X增加一列全为1所以输入的时候就不需要写了
X = torch.tensor([[1],[2],[3]], requires_grad = True,dtype=torch.float32)
X
# tensor([[1.],
# [2.],
# [3.]], requires_grad=True)
y = torch.tensor([2,4,6], requires_grad = True,dtype=torch.float32).reshape(-1,1)
y
# tensor([[2.],
# [4.],
# [6.]], grad_fn=<ReshapeAliasBackward0>)
计算结果$a\approx2, b\approx0$,其实用最小二乘法令一阶导数为0即可求的a=2,b=0
g(X,y, n = 10000)
# tensor([[2.0000e+00],
# [1.9127e-05]], grad_fn=<SubBackward0>)
计算此时的损失函数值,改写原来的g函数
def g(X, y, alpha = torch.tensor(0.01, requires_grad = True), n = 10000):
b=torch.ones(X.shape[0], requires_grad = True,dtype=torch.float32).reshape(-1,1)
X = torch.cat([X,b],1)
m, nc = X.shape
w = torch.zeros(nc, 1, requires_grad = True)
for _ in range(n):
grad = torch.mm(X.t(), (torch.mm(X, w) - y))/m
w = w - alpha * grad
loss = torch.mm((torch.mm(X,w)-y).t(), torch.mm(X,w)-y)/m*0.5
return w,loss
此时的损失函数非常接近于0
w,loss=g(X,y)
loss
# tensor([[2.9644e-11]], grad_fn=<MulBackward0>))
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。