随机梯度下降(Stochastic Gradient Descent,SGD)

技术

定义

梯度是一个矢量,它告诉我们权重的方向。更准确地说,它告诉我们如何改变权重,使损失变化最快。我们称这个过程为梯度下降,因为它使用梯度使损失曲线下降到最小值。随机的意思是“由偶然决定的”。我们的训练是随机的,因为小批量是数据集中的随机样本。这就是为什么它被称为SGD!

如果我们能成功地训练一个网络做到这一点,它的权重必须以某种方式表示这些特征和在训练数据中表示目标之间的关系。除了训练数据,我们还需要两件事:

  • 一个“损失函数”(loss function),用来衡量网络的预测有多好。
  • 一个“优化器”(optimizer),可以告诉网络如何改变其权重。
Loss Function

损失函数测量目标的真实值和模型预测值之间的差距。不同的问题需要不同的损失函数。

  • 一个常见的损失函数回归问题是平均绝对误差(MAE)。对于每个预测y_pred, MAE通过绝对差异abs(y_true - y_pred)衡量与真实目标y_true的差异。
  • 数据集上的MAE总损失是所有这些绝对差异的平均值。

picture.image平均绝对误差是拟合曲线与数据点之间的平均长度。

除了MAE,你可能看到的其他回归问题的损失函数是均方误差(MSE)或Huber损失(Keras中都有)。

Optimizer - Stochastic Gradient Descent

我们已经描述了我们希望网络解决的问题,但现在我们需要说如何解决它。优化器是一种调整权重以使损失最小化的算法。

几乎所有用于深度学习的优化算法都属于随机梯度下降法。它们是迭代算法,以步骤训练网络。训练的一个步骤是这样的:

  • 1.对一些训练数据进行采样,通过网络进行预测
  • 2.衡量预测值和真实值之间的损失
  • 3.最后,调整权重,使损失变小。

然后反复这样做,直到损失小到你想要的程度为止(或者直到它不会再减少)。

picture.image用随机梯度下降法训练神经网络

  • 每次迭代的训练数据样本称为小批(mini-batch)处理(常说“批处理”),而一次完整的训练数据一轮称为epoch。你训练的epoch的数量是网络将看到每个训练示例的次数。
  • 动图显示了第1个中的线性模型正在用SGD进行训练。淡红色的点表示整个训练集,而实红色的点是小批量。每一次SGD看到一个新的小批,它就会将权重(w是斜率,b是y轴截距)移向该批上的正确值。一批又一批,直线最终收敛到它的最佳拟合。您可以看到,随着权重越来越接近它们的真实值,损失会越来越小。
学习率和批大小(Learning Rate and Batch Size)

这条线只在每个批处理的方向上做了一个小的移动(而不是一直移动)。这些转变的大小取决于学习速度。较小的学习率意味着网络需要看到更多的小批量,才能使其权值收敛到最佳值。

学习率和批量的大小是影响SGD训练进行的两个最大的参数。它们之间的相互作用通常是微妙的,而这些参数的正确选择并不总是显而易见的。

对于大多数工作来说,不需要进行广泛的超参数搜索来获得满意的结果。 Adam是一种SGD算法,它具有自适应的学习率 ,使其适用于大多数问题,无需任何参数调整(在某种意义上,它是“自调整”)。Adam是一个优秀的通用优化器。

添加Loss and Optimizer

定义一个模型之后,你可以用模型的compile方法添加一个loss函数和优化器:


        
          
model.compile(  
    optimizer="adam",  
    loss="mae",  
)  

      

注:我们可以用一个字符串指定损失和优化器。也可以通过Keras API直接访问这些参数。

完整使用案例-红酒质量预测
  • 输入到神经网络中的数据进行了归一化处理,保证模型能够更快收敛

        
          
import pandas as pd  
from IPython.display import display  
  
red_wine = pd.read_csv('red-wine.csv')  
  
# Create training and validation splits  
df_train = red_wine.sample(frac=0.7, random_state=0)  
df_valid = red_wine.drop(df_train.index)  
display(df_train.head(4))  
  
# Scale to [0, 1]  
max_ = df_train.max(axis=0)  
min_ = df_train.min(axis=0)  
df_train = (df_train - min_) / (max_ - min_)  
df_valid = (df_valid - min_) / (max_ - min_)  
  
# Split features and target  
X_train = df_train.drop('quality', axis=1)  
X_valid = df_valid.drop('quality', axis=1)  
y_train = df_train['quality']  
y_valid = df_valid['quality']  
  
from tensorflow import keras  
from tensorflow.keras import layers  
  
model = keras.Sequential([  
    layers.Dense(512, activation='relu', input_shape=[11]),  
    layers.Dense(512, activation='relu'),  
    layers.Dense(512, activation='relu'),  
    layers.Dense(1),  
])  
  
model.compile(  
    optimizer='adam',  
    loss='mae',  
)  
  
  
history = model.fit(  
    X_train, y_train,  
    validation_data=(X_valid, y_valid),  
    batch_size=256,  
    epochs=10,  
)  
  
import pandas as pd  
  
# convert the training history to a dataframe  
history_df = pd.DataFrame(history.history)  
# use Pandas native plot method  
history_df['loss'].plot();  

      

picture.image

结论

我们通过损失函数和优化器的选择说明了梯度下降的过程,并通过mini-batch随机选择训练样本,完整的解释了随机梯度下降的工作过程,本文没有过多的公式说明,也是为了便于读者更加容易明白其实际应用。

如果你感觉这对你的工作生活有帮助,欢迎点赞关注一键三连,支持我的工作!

扫码加我好友进微信群|QQ群

picture.image picture.image

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
边缘云原生技术实践
《边缘云原生技术实践》 李明浩 | 火山引擎边缘云原生负责人
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论