优化算法
梯度下降
一次性对整个训练集进行梯度更新,更新方法:
W
[
l
]
=
W
[
l
]
−
α
d
W
l
b
[
l
]
=
b
[
l
]
−
α
d
b
[
l
]
W^{[l]} = W^{[l]}-{\alpha}dW^{l}\\ b^{[l]} = b^{[l]}-{\alpha}db^{[l]}
W[l]=W[l]−αdWlb[l]=b[l]−αdb[l]
随机梯度下降
一次性只处理一个训练集的样本,永远不会收敛,存在一直波动。
SGD
造成许多振荡以达到收敛。但是每个step中,计算SGD
比使用GD
更快,因为它仅使用一个训练示例(相对于GD
的整个批次)。
Mini-Batch梯度下降
从训练集(X,Y)中构建小批次数据进行学习和训练。
-
shuffled:创建训练集(X,Y)的随机打乱版本。X和Y中的每一列代表一个训练示例。
注意:随机打乱是在X和Y之间同步完成的。这样,在随机打乱之后,X的 i t h i^{th} ith列就是对应于Y中 i t h i^{th} ith标签的示例。打乱步骤可确保该示例将随机分为不同小批。
-
Partition:将打乱后的(X,Y)划分为大小为
mini_batch_size
(一般为2的倍数)的小批处理。请注意,训练示例的数量并不总是可以被mini_batch_size
整除。最后的小批量可能较小,但是你不必担心,当最终的mini
批处理小于完整的mini_batch_size
时,它将作为最后一列数据。
def random_mini_batches(X, Y, mini_batch_size = 64, seed = 0):
"""
Creates a list of random minibatches from (X, Y)
Arguments:
X -- input data, of shape (input size, number of examples)
Y -- true "label" vector (1 for blue dot / 0 for red dot), of shape (1, number of examples)
mini_batch_size -- size of the mini-batches, integer
Returns:
mini_batches -- list of synchronous (mini_batch_X, mini_batch_Y)
"""
np.random.seed(seed) # To make your "random" minibatches the same as ours
m = X.shape[1] # number of training examples
mini_batches = []
# Step 1: Shuffle (X, Y)
permutation = list(np.random.permutation(m))
shuffled_X = X[:, permutation]
shuffled_Y = Y[:, permutation].reshape((1,m))
# Step 2: Partition (shuffled_X, shuffled_Y). Minus the end case.
num_complete_minibatches = math.floor(m/mini_batch_size) # number of mini batches of size mini_batch_size in your partitionning
for k in range(0, num_complete_minibatches):
### START CODE HERE ### (approx. 2 lines)
mini_batch_X = shuffled_X[:, k * mini_batch_size : (k+1) * mini_batch_size]
mini_batch_Y = shuffled_Y[:, k * mini_batch_size : (k+1) * mini_batch_size]
### END CODE HERE ###
mini_batch = (mini_batch_X, mini_batch_Y)
mini_batches.append(mini_batch)
# Handling the end case (last mini-batch < mini_batch_size)
if m % mini_batch_size != 0:
### START CODE HERE ### (approx. 2 lines)
mini_batch_X = shuffled_X[:, num_complete_minibatches * mini_batch_size : m]
mini_batch_Y = shuffled_Y[:, num_complete_minibatches * mini_batch_size : m]
### END CODE HERE ###
mini_batch = (mini_batch_X, mini_batch_Y)
mini_batches.append(mini_batch)
return mini_batches
Momentum优化
侧重于动量的优化方法。
因为小批量梯度下降仅在看到示例的子集后才进行参数更新,所以更新的方向具有一定的差异,因此小批量梯度下降所采取的路径将“朝着收敛”振荡。利用冲量则可以减少这些振荡。冲量考虑了过去的梯度以平滑更新。
{
v
d
W
[
l
]
=
β
v
+
(
1
−
β
)
d
W
[
l
]
W
[
l
]
=
W
[
l
]
−
α
v
d
W
[
l
]
{
v
d
b
[
l
]
=
β
v
+
(
1
−
β
)
d
b
[
l
]
b
[
l
]
=
W
[
l
]
−
α
v
d
b
[
l
]
\begin{cases} v_{dW^{[l]}}={\beta}v+(1-{\beta})dW^{[l]}\\ W^{[l]}=W^{[l]}-{\alpha}v_{dW^{[l]}} \end{cases}\\ \begin{cases} v_{db^{[l]}}={\beta}v+(1-{\beta})db^{[l]}\\ b^{[l]}=W^{[l]}-{\alpha}v_{db^{[l]}} \end{cases}
{vdW[l]=βv+(1−β)dW[l]W[l]=W[l]−αvdW[l]{vdb[l]=βv+(1−β)db[l]b[l]=W[l]−αvdb[l]
- 其中L是层数, β \beta β是动量, α \alpha α是学习率。
- 速度用零初始化。因此,该算法将花费一些迭代来“提高”速度并开始采取更大的步骤。
- 若 β \beta β=0,则它变为没有冲量的标准梯度下降。
- 冲量将过去的梯度考虑在内,以平滑梯度下降的步骤。它可以应用于批量梯度下降,小批次梯度下降或随机梯度下降。
注意:
- 冲量 β \beta β越大,更新越平滑,因为我们对过去的梯度的考虑也更多。但是如果太大,也可能使更新变得过于平滑。
- β \beta β的常用值范围是0.8到0.999。如果你不想调整它,则 β \beta β=0.9通常是一个合理的默认值。
- 调整模型的最佳可能需要尝试几个值,以了解在降低损失函数的值方面最有效的方法。
Adam
Adam
结合了RMSProp
和Momentum
的优点
- 计算过去梯度的指数加权平均值,并将其存储在变量
v
(使用偏差校正之前)和 v c o r r e c t e d v^{corrected} vcorrected(使用偏差校正)中。 - 计算过去梯度的平方的指数加权平均值,并将其存储在变量
s
(偏差校正之前)和 s c o r r e c t e d s^{corrected} scorrected(偏差校正中)中。 - 更新
{ v d W [ l ] = β 1 v + ( 1 − β 1 ) d W [ l ] v d W [ l ] c o r r e c t e d = v d W [ l ] 1 − ( β 1 ) t s d W [ l ] = β 2 s + ( 1 − β 2 ) ( d W [ l ] ) 2 s d W [ l ] c o r r e c t e d = s d W [ l ] 1 − ( β 2 ) t W [ l ] = W [ l ] − α v d W [ l ] c o r r e c t e d s d W [ l ] c o r r e c t e d + ϵ \begin{cases} v_{dW^{[l]}}={\beta}_1v+(1-{\beta}_1)dW^{[l]}\\ v^{corrected}_{dW^{[l]}}=\frac{v_{dW^{[l]}}}{1-({\beta}_1)^t}\\ s_{dW^{[l]}}={\beta}_2s+(1-{\beta}_2)(dW^{[l]})^2\\ s^{corrected}_{dW^{[l]}}=\frac{s_{dW^{[l]}}}{1-({\beta}_2)^t}\\ W^{[l]}=W^{[l]}-{\alpha}\frac{v^{corrected}_{dW^{[l]}}}{\sqrt{s^{corrected}_{dW^{[l]}}}+{\epsilon}} \end{cases} ⎩ ⎨ ⎧vdW[l]=β1v+(1−β1)dW[l]vdW[l]corrected=1−(β1)tvdW[l]sdW[l]=β2s+(1−β2)(dW[l])2sdW[l]corrected=1−(β2)tsdW[l]W[l]=W[l]−αsdW[l]corrected+ϵvdW[l]corrected
Adam的优势包括:
- 相对较低的内存要求(尽管高于梯度下降和带冲量的梯度下降)
- 即使很少调整超参数,通常也能很好地工作(除外 α \alpha α)
注:
冲量通常会有所帮助,但是鉴于学习率低和数据集过于简单,其影响几乎可以忽略不计。同样,你看到损失的巨大波动是因为对于优化算法,某些小批处理比其他小批处理更为困难。
另一方面,Adam明显胜过小批次梯度下降和冲量。如果你在此简单数据集上运行更多epoch,则这三种方法都将产生非常好的结果。但是,Adam收敛得更快。