学习内容:B站 刘二大人 《pytorch深度学习实践》课程系列
问题的引入:
上一讲我们提到了如何找权重w,采用的方法:在一个范围内对w进行搜索,使得目标函数最小!!!但在实际问题中存在两方面的问题:1)w的范围并不能确定;2)另一如果模型的权重有多个w1,w2,w3……,搜索空间也会成倍的扩增。如果还是搜索显然不是明智之举。那么这一讲将会介绍一种新的方法 ——“梯度下降”。
定义:我们将 " 找使得目标函数最小的权重组合 " 这样的任务叫做“优化问题”
Gradient Descent Algorithm:
主要思想:给定一个w的随机初始值,每次对w进行更新。更新的方式:权重w沿着当前梯度的反方向前进,w更新的公式如上图,即 w - 学习率*(cost对w的导数)。
注意:
- 1)学习率不要太低(训练慢),也不要太高(会越过最低点)。
- 2)梯度下降法,得到的可能是局部最优解,除非该函数时凸函数(就只有一个全局最优)。
- 3)鞍点:导数等于0的点,w无法继续更新。在高维空间中可能时一个维度的最高点,同时也是一个维度的最低点。
公式:
代码:
import matplotlib.pyplot as plt
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]
w = 1.0
def forward(x):
return x*w
def cost(xs,ys):
cost = 0
for x,y in zip(xs,ys):
y_pred = forward(x)
cost += (y_pred - y)**2
return cost/len(xs)
def gradient(xs,ys):
grad = 0
for x,y in zip(xs,ys):
grad += 2 * x * (x*w - y)
return grad/len(xs)
#方便后边画图
epoch_list = []
Loss_list = []
print('Predict before training:',4,forward(4))
for epoch in range(100):
cost_val = cost(x_data,y_data)
grad_val = gradient(x_data,y_data)
w -= 0.01*grad_val
print('Epoch:',epoch,'w=',w,'loss=',cost_val)
#方便后边画图
epoch_list.append(epoch)
Loss_list.append(cost_val)
print('Predict after training:',4,forward(4))
plt.plot(epoch_list,Loss_list)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.grid()
plt.show()
训练过程中损失变化:
注:在训练过程中,随着epoch的增加,loss逐渐减小,并趋于一定值,说明我们的训练是有效的。
随机梯度下降
优点:
- 速度快:随机梯度下降算法每次仅使用一个样本进行梯度计算和参数更新,因此计算速度非常快。在大规模数据集上,随机梯度下降算法通常比批量梯度下降算法更快。
- 占用内存少:随机梯度下降算法每次只需要处理一个样本,所以它的内存占用量非常小。
- 能够逃离局部最优解:由于随机梯度下降算法每次仅使用一个样本进行梯度计算和参数更新,因此它有可能跳出局部最优解,找到全局最优解
缺点:
- 收敛速度慢:由于随机梯度下降算法每次仅使用一个样本进行梯度计算和参数更新,因此它的收敛速度通常比批量梯度下降算法慢。
- 不稳定:随机梯度下降算法的梯度估计通常比批量梯度下降算法更不准确,因此它的参数更新也更不稳定。这可能导致模型在训练过程中出现震荡或发散。
- 需要调节学习率:随机梯度下降算法需要调节学习率,以确保模型能够收敛。如果学习率设置得太高,模型可能会发散;如果学习率设置得太低,模型可能会收敛得非常慢。
- 对数据的依赖性强:随机梯度下降算法每次仅使用一个样本进行梯度计算和参数更新,因此它对数据的依赖性非常强。如果数据集中存在噪声或异常值,随机梯度下降算法可能会受到影响,导致模型学习得不够准确。
随机梯度与之前方法不同:每次w的更新只需要计算一个样本的loss值就可以,而需要计算loss的总和。
随机梯度下降的代码:
- 将cost改成了loss,因为每次只需要计算每个样本loss
x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]
w = 1.0
def forward(x):
return x*w
def loss(x,y):
return (forward(x) - y)**2
def gradient(x,y):
return 2 * x * (x * w - y)
print('Predict before training:',4,forward(4))
for epoch in range(100):
for x,y in zip(x_data, y_data):
grad = gradient(x,y)
w = w - 0.01*grad
print('\tgrad:',x,y,grad)
l = loss(x,y)
print('epoch:',epoch,'w=',w,'loss=',l)
print('Predict after training:',4,forward(4))
因为纯随机梯度下降算法和梯度下降算法各有不好的地方,所以在这两者取个平衡。在深度学习中随机梯度下降算法,采用的是Batch梯度的方法。
小结:这讲主要引入了随机梯度下降算法,在pytorch中使用的随机梯度下降算法,原理就是Batch方法。