學習一時爽,一直學習一直爽
Hello,大家好,我是 もうり,一個從無到有的技術+語言小白。
學習率是深度學習中的一個重要的超參,如何調整學習率是訓練出好模型的關鍵要素之一。
關于學習率的大小
在訓練過程中,一般根據訓練輪數設置動態變化的學習率。
剛開始訓練時:學習率以 0.01 ~ 0.001 為宜。
一定輪數過后:逐漸減緩。
接近訓練結束:學習速率的衰減應該在 100 倍以上。
兩種學習率衰減模式,一種為線性衰減,一種為指數衰減。
如果學習率過小,梯度下降很慢,如果學習率過大,如 Andrew Ng 的 Stanford 公開課程所說梯度下降的步子過大可能會跨過最優值。不同的學習率對 loss 的影響如下圖所示:
常見學習率衰減方式
https://www.jianshu.com/p/125fe2ab085b
線性衰減
momentum 動量法
網絡權值時,存在一些不確定因素,并不能保證每一次初始化操作都能使得網絡的初始權值處在一個合適的狀態。不恰當的初始權值可能使得網絡的損失函數在訓練過程中陷入局部最小值,達不到全局最優的狀態。
momentum 動量能夠在一定程度上解決這個問題。momentum 動量是依據物理學的勢能與動能之間能量轉換原理提出來的。
當 momentum 動量越大時,其轉換為勢能的能量也就越大,就越有可能擺脫局部凹域的束縛,進入全局凹域。momentum 動量主要用在權重更新的時候。
一般,神經網絡在更新權值時,采用如下公式:
w = w - learning_rate * dw
引入 momentum 后,采用如下公式:
v = mu * v - learning_rate * dw
w = w + v
其中,v 初始化為 0,mu 是設定的一個超變量,最常見的設定值是 0.9。
先看源碼,其實主要改幾個參數就可以
基于 Iris 數據集
''' @authot:?毛利 ''' from?sklearn?import?datasets import?numpy?as?np from?keras.models?import?Sequential from?keras.layers?import?Dense from?keras.optimizers?import?SGD from?keras.wrappers.scikit_learn?import?KerasClassifier dataset?=?datasets.load_iris() x?=?dataset.data Y?=?dataset.target seed?=?4 np.random.seed(seed) def?create_model(): ????model?=?Sequential() ????model.add(Dense(units=4,?activation='relu',?input_dim=4)) ????model.add(Dense(units=6,?activation='relu')) ????model.add(Dense(units=3,?activation='softmax'?)) ????#?定義優化器 ????learningRate?=?0.1 ????momentum?=?0.9??????#?動量參數 ????decay_rate?=?0.005??#?學習率衰減 ????sgd?=?SGD(lr=learningRate,?momentum=momentum,?decay=decay_rate,?nesterov=False) ????model.compile(loss='categorical_crossentropy',?optimizer=sgd,?metrics=['accuracy']) ????return?model model?=?KerasClassifier(build_fn=create_model,?epochs=200,?batch_size=5,?verbose=1) model.fit(x,Y)
線性衰減的最終的結果為:loss: 0.4630 - acc: 0.6467
因此指數衰減相對于線性衰減效果會更好
通過固定的 epoch 周期將學習速率降低 50% 來實現的。例如,初始學習率設定為 0.1,每 10 個 epochs 降低 50%。前 10 個 epochs 使用 0.1 的學習率,接下來的 10 個 epochs 使用 0.05 的學習率,學習率以指數級進行衰減。
lrate?=?init_lrate?*?pow(drop,?floor(1?+?epoch)?/?epochs_drop)
需要導入?from keras.callbacks import LearningRateScheduler
用于動態設置學習率
''' @author:毛利 ''' from?sklearn?import?datasets import?numpy?as?np from?keras.models?import?Sequential from?keras.layers?import?Dense from?keras.optimizers?import?SGD from?keras.wrappers.scikit_learn?import?KerasClassifier from?keras.callbacks?import?LearningRateScheduler from?math?import?pow,?floor dataset?=?datasets.load_iris() x?=?dataset.data Y?=?dataset.target seed?=?4 np.random.seed(seed) #?計算學習率 def?step_decay(epoch): ????init_lrate?=?0.01 ????drop?=?0.05 ????epochs_drop?=?10 ????lrate?=?init_lrate?*?pow(drop,?floor(1+epoch)?/?epochs_drop) ????return?lrate def?create_model(init='glorot_uniform'): ????model?=?Sequential() ????model.add(Dense(units=4,?activation='relu',?input_dim=4,?kernel_initializer=init)) ????model.add(Dense(units=6,?activation='relu',?kernel_initializer=init)) ????model.add(Dense(units=3,?activation='softmax',?kernel_initializer=init)) ????#?定義優化器 ????learningRate?=?0.01 ????momentum?=?0.9??????#?動量參數 ????decay_rate?=?0.0????#?學習率衰減 ????sgd?=?SGD(lr=learningRate,?momentum=momentum,?decay=decay_rate,?nesterov=False) ????model.compile(loss='categorical_crossentropy',?optimizer=sgd,?metrics=['accuracy']) ????return?model """ keras.callbacks.LearningRateScheduler(schedule)? 該回調函數是用于動態設置學習率? 參數:? ●?schedule:函數,該函數以epoch號為參數(從0算起的整數),返回一個新學習率(浮點數) """ lrate?=?LearningRateScheduler(step_decay) model?=?KerasClassifier(build_fn=create_model,?epochs=200,?batch_size=5,?verbose=1,?callbacks=[lrate]) model.fit(x,?Y)
指數衰減的最終結果為 loss: 0.3393 - acc: 0.9000