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衰减率参数。

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。 使用LearningRateScheduler回调实现。

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实践》

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值