Dropout与学习率衰减

模型出现过拟合,可采取 Dropout的方式进行效率解决(仅针对神经网络模型的正则化方法)。该方法主要是在训练模型的过程中,随机抛弃一些神经元,使其不参与正向和反向传播过程。神经网络在训练过程中,权重对于某些特征的依赖关系较强,每次训练都随机抛下一些特征(对于非输入层则是神经元),将会强迫每一个神经元和随机挑选出来的其他神经元共同工作,据此网络模型对于神经元的特定权重不那么敏感,由此提高了模型整体泛化能力。

from sklearn import datasets
import numpy as np
from keras.models import Sequential
from keras.layers import Dropout
from keras.layers import Dense
from tensorflow.keras.optimizers import SGD
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold

导入数据
dataset = datasets.load_iris()

x = dataset.data
Y = dataset.target

设定随机种子
seed = 7
np.random.seed(seed)

可在输入层后加入一层Dropout,或是在隐藏层间加入。

构建模型函数
def create_model(init='glorot_uniform'):
    # 构建模型
    model = Sequential()

    '''
    # 在输入层后加入一层Dropout层,其速率0.2表示每一个更新周期将会有20%的特征被随即排除
    model.add(Dropout(rate=0.2, input_shape=(4,)))
    model.add(Dense(units=4, activation='relu', kernel_initializer=init))
    model.add(Dense(units=6, activation='relu', kernel_initializer=init))
    model.add(Dense(units=3, activation='softmax', kernel_initializer=init))
    '''

    # 在隐藏层加入Dropout层,并且对权重约束,是其最大限度不超过3
    model.add(Dense(units=4,activation='relu',input_dim=4, kernel_initializer=init, kernel_constraint=maxnorm(3)))
    # 在第一隐藏层到第二隐藏层间增加
    model.add(Dropout(rate=0.2))
    model.add(Dense(units=6,activation='relu', kernel_initializer=init,kernel_constraint=maxnorm(3)))
    # 在第二隐藏层至输出层间增加
    model.add(Dropout(rate=0.2))
    model.add(Dense(units=3,activation='softmax', kernel_initializer=init))

    # 定义optimizer
    sgd = SGD(lr=0.01, momentum=0.8, decay=0.0, 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=0)
kfold = KFold(n_splits=10, shuffle=True, random_state=seed)
results = cross_val_score(model, x, Y, cv=kfold)
print('Accuracy: %.2f%% (%.2f)' % (results.mean()*100, results.std()))

此外,此外梯度下降也非常耗费时间,可用 学习率衰减来解决。学习率指参数移动到最优值的速度,如果学习率过大,很可能直接越过最优值,如果学习率过小,优化效率过低,使得算法长时间无法收敛。使用学习率衰减的基本原理是:学习率随着训练的进行逐渐衰减。目前有两种学习率衰减方法: 线性衰减(根据epoch逐步降低学习率)指数衰减(在特定epoch使用分数快速减低学习率)

基于时间的学习率线性衰减,使用SGD类中的随机梯度下降优化算法实现,主要是调节decay衰减率参数。

Dropout与学习率衰减
from sklearn import datasets
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from tensorflow.keras.optimizers import SGD

导入数据
dataset = datasets.load_iris()

x = dataset.data
Y = dataset.target

设定随机种子
seed = 7
np.random.seed(seed)

创建模型函数
def creat_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.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

epochs=200
model = KerasClassifier(build_fn=create_model,epochs=epochs,batch_size=10,verbose=1)
model.fit(x,Y)

学习率指数衰减,通过在固定的epoch周期将学习速率降低50%实现。例如初始学习速率(initial learningrate)为0.1,设定每10个epochs(epoch drop)降低50%(drop rate),则前10个epochs的学习速率为0.1,后10个epochs的学习速率为0.05。 使用LearningR ateScheduler回调实现。

Dropout与学习率衰减
from sklearn import datasets
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from tensorflow.keras.optimizers import SGD
from keras.callbacks import LearningRateScheduler
from math import pow, floor

导入数据
dataset = datasets.load_iris()

x = dataset.data
Y = dataset.target

设定随机种子
seed = 7
np.random.seed(seed)

计算学习率
def step_decay(epoch):
    init_lrate=0.1 #初始学习率
    drop = 0.5 #衰减速率
    epochs_drop = 10 #衰减速率更新周期
    lrate = init_lrate * pow(drop, floor(1+epoch)/epochs_drop)
    return lrate

创建模型函数
def creat_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.1 # 初始学习率
    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

学习率指数衰减回调
lrate = LearningRateScheduler(step_decay)
epochs = 200
model = KerasClassifier(build_fn=create_model,epochs=epochs,batch_size=5,verbose=1,callbacks=[lrate])
model.fit(x,Y)

需要注意:

神经网络一般使用 20%-50%的Dropout率,且使用 较高学习率、配合 学习率衰减和巨大的动量值(momenum=0.8)。并且需要 限制网络权重的大小(Dense中的kernel_constrin=maxnorm(x))。

该文代码源自魏贞原《深度学习:基于Keras的Python实践》

Original: https://blog.csdn.net/weixin_42196948/article/details/123542744
Author: 叽叽贝贝
Title: Dropout与学习率衰减

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/691970/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球