Optimization


Mini-Batch Gradient Descent


Mini-Batch


ミニレイアウトの紹介を続ける前に、レイアウト傾斜降下法について説明しましょう.m個の試験例からなる訓練集合において、各訓練過程段階においてすべてのm個の試験例を適用する場合、配置傾斜降下法と呼ばれる.すなわち,我々がよく知っている傾斜降下法はそうである.しかし、場合によっては、傾斜降下法の導入は非常に非効率的な役割を果たすことがあります.mが大きすぎる場合、1段階の訓練にかかる時間費用です.このため,すべてのm個の試験例を分離し,これらのすべての例を一次時代(epoch)に設定して訓練した.これがミニ配置傾斜降下法である.

上の図は、トレーニング例を64個のミニ構成で分割した様子です.まず、このような状況を作り出すためには、サンプルの混合プロセスを訓練する必要がある.訓練例題はバイアス分布を呈する可能性があるため,有効なミニ配置傾斜降下法のためにランダム混合の過程を先に行わなければならない.

Stochastic Gradient Descent


確率傾斜降下法は、一例をミニ構成に設定して訓練することによって行われる.確率傾斜降下法は最適化過程が乱雑でベクトル化高速並列計算の利点が得られず,最適化過程で速度を向上させることができないため,低効率な方法である.
def random_mini_batches(X, Y, mini_batch_size = 64, seed = 0):
    m = X.shape[1]
    mini_batches = []
        
    # Step 1: Shuffle (X, Y)
    permutation = list(np.random.permutation(m))
    shuffled_X = X[:, permutation]
    shuffled_Y = Y[:, permutation].reshape((1, m))
    
    inc = mini_batch_size

    # Step 2 - Partition (shuffled_X, shuffled_Y).
    num_complete_minibatches = math.floor(m / mini_batch_size)
    for k in range(0, num_complete_minibatches):
        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]

        mini_batch = (mini_batch_X, mini_batch_Y)
        mini_batches.append(mini_batch)
    
    if m % mini_batch_size != 0:
        mini_batch_X = shuffled_X[:, num_complete_minibatches * mini_batch_size :]
        mini_batch_Y = shuffled_Y[:, num_complete_minibatches * mini_batch_size :]

        mini_batch = (mini_batch_X, mini_batch_Y)
        mini_batches.append(mini_batch)
    
    return mini_batches

Momentum


Exponentially Weighted Average


指数移動平均(Exponetially Weighted Average)は、気温や株価などのデータが時間とともに変化する傾向を決定するために使用されます.β\betaβ一定期間の価値を考慮する過程を設定する.VTV tVTトレンドの値を決定します.θt\theta_tθtの特定の時間の値、最後にβ\betaβパラメータを調整すると仮定します.
 Vt=βVt−1+(1−β)θt\V_t =\beta V_{t-1} + (1-\beta)\theta_t Vt​=βVt−1​+(1−β)θt​
上の儀式を見てください.β\betaβの値によって、平均的に考える時間が変わります.このデータを用いて,最近のn日間の気温,株価の傾向を把握し,トレンドマップを描くことができる.

Why Momentum?


では、なぜ運動量という概念が必要なのでしょうか.ミニ配置傾斜降下法を利用する利点は,大きな訓練セットを利用しても迅速に訓練できることであるが,訓練の易変性は配置傾斜降下法よりも大きい.

上図を見ると最適化中の振幅が大きいことがわかります.単純に赤線に沿って最適化するのではなく,従来の傾向(速度)を考慮して傾斜降下法を行い,振幅を小さくした場合には,既存の運動方向を考慮し,加えて滑らかな最適化点を達成することができる.
この方法の利点は,鞍点(鞍点)での訓練過程が遅くなるという問題が,持続運動の方向に値を修正することによって増加するため,鞍点からより速く脱出できることである.
def update_parameters_with_momentum(parameters, grads, v, beta, learning_rate):
    L = len(parameters) // 2 # number of layers in the neural networks
   
    # Momentum update for each parameter
    for l in range(1, L + 1):
        v["dW" + str(l)] = beta * v["dW" + str(l)] + (1-beta) * grads["dW" + str(l)]
        v["db" + str(l)] = beta * v["db" + str(l)] + (1-beta) * grads["db" + str(l)]

        parameters["W" + str(l)] = parameters["W" + str(l)] - learning_rate * v["dW" + str(l)]
        parameters["b" + str(l)] = parameters["b" + str(l)] - learning_rate * v["db" + str(l)]
        
    return parameters, v

Adam


Adam Optimization(Adam Optimization)は、平均平方根伝播(RMSPOP)および運動量(Momentum)方式を用いた最も効果的な最適化方法の1つである.従来の最適化方式とは異なり,各プロセスに誤差補正(bias correction)プログラムが加わる.指数移動平均の問題は,初期値から考慮した以前の値が不足しているため,予測傾向では予測値が実際の値より小さいことである.この問題を修正するためにβt1-\beta^t1−βtにより誤差を修正する.

RMSprop


平均平方根伝搬(RMSProp)は指数移動平均であり,後方伝搬により生じた結果,値を二乗(elementwise square)することにより後方伝搬値を分配する.直感的には,この方式は変動の大きい後方伝搬値の変化幅を減少させ,小さい方向には急速に変化する更新が絶えず行われる.
 SdW=β2SdW+(1−β2)dW2W=W−αdbSdW+ϵ\S_{dW}=\beta_2 S_{dW}+(1-\beta_2)dW^2\\W=W-\alpha\frac{db}{\sqrt{S_{dW}}+\epsilon} SdW​=β2​SdW​+(1−β2​)dW2W=W−αSdW​​+ϵdb​

Adam optimization


平均再平方根伝搬と運動量を傾斜降下法に適用し,アダム最適化を以下の方法にまとめることができる.
{vdW[l]=β1vdW[l]+(1−β1)∂J∂W[l]vdW[l]corrected=vdW[l]1−(β1)tsdW[l]=β2sdW[l]+(1−β2)(∂J∂W[l])2sdW[l]corrected=sdW[l]1−(β2)tW[l]=W[l]−αvdW[l]correctedsdW[l]corrected+ε\begin{cases} v_{dW^{[l]}} =\beta_1 v_{dW^{[l]}} + (1 -\beta_1)\frac{\partial\mathcal{J} }{\partial W^{[l]} }\\v^{corrected}_{dW^{[l]}} =\frac{v_{dW^{[l]}}}{1 - (\beta_1)^t}\\s_{dW^{[l]}} =\beta_2 s_{dW^{[l]}} + (1 -\beta_2) (\frac{\partial\mathcal{J} }{\partial W^{[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]}}} +\varepsilon}\end{cases}⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧​vdW[l]​=β1​vdW[l]​+(1−β1​)∂W[l]∂J​vdW[l]corrected​=1−(β1​)tvdW[l]​​sdW[l]​=β2​sdW[l]​+(1−β2​)(∂W[l]∂J​)2sdW[l]corrected​=1−(β2​)tsdW[l]​​W[l]=W[l]−αsdW[l]corrected​​+εvdW[l]corrected​​​
def update_parameters_with_adam(parameters, grads, v, s, t, learning_rate = 0.01,
                                beta1 = 0.9, beta2 = 0.999,  epsilon = 1e-8):
    
    L = len(parameters) // 2
    v_corrected = {}
    s_corrected = {}
    
    # Perform Adam update on all parameters
    for l in range(1, L + 1):
        v["dW" + str(l)] = beta1 * v["dW" + str(l)] + (1 - beta1) * grads["dW" + str(l)]
        v["db" + str(l)] = beta1 * v["db" + str(l)] + (1 - beta1) * grads["db" + str(l)]
       
        v_corrected["dW" + str(l)] = v["dW" + str(l)] / (1 - beta1 ** t)
        v_corrected["db" + str(l)] = v["db" + str(l)] / (1 - beta1 ** t)

        s["dW" + str(l)] = beta2 * s["dW" + str(l)] + (1 - beta2) * (grads["dW" + str(l)] ** 2)
        s["db" + str(l)] = beta2 * s["db" + str(l)] + (1 - beta2) * (grads["db" + str(l)] ** 2)
        
        s_corrected["dW" + str(l)] = s["dW" + str(l)] / (1 - beta2 ** t)
        s_corrected["db" + str(l)] = s["db" + str(l)] / (1 - beta2 ** t)

        parameters["W" + str(l)] = parameters["W" + str(l)] - learning_rate * (v_corrected["dW" + str(l)]) / (np.sqrt(s_corrected["dW" + str(l)]) + epsilon)
        parameters["b" + str(l)] = parameters["b" + str(l)] - learning_rate * (v_corrected["db" + str(l)]) / (np.sqrt(s_corrected["db" + str(l)]) + epsilon)

    return parameters, v, s, v_corrected, s_corrected

Reference

  • deeplearning.ai
  • Kiank_partition
  • Opt_momentum
  • Gradient Descent & Momentum