【Keras】学习笔记10:Dropout 与学习率衰减

一、神经网络中的dropout

dropout是一种针对神经网络模型的正则化方法。是在训练过程中,随机的忽略部分神经元。它强迫一个神经元单元和随机挑选出来的其他神经单元共同工作,达到较好的效果,减弱了神经节点间的联合适应性,增强了泛化能力。经过验证,隐含节点dropout率等于0.5的时候效果最好。此时dropout随机生成的网络结构最多,dropout也可以用在输入层,作为一种添加噪音的方法。输入层设为更接近1的数字,使得输入变换不会太大(如0.8)。

在keras的每个权重更新周期中,按照给定概率(如20%),随机选择要丢弃的节点,以实现dropout。dropout只能在模型的训练过程中使用,在评估模型时不能使用。

1.1 输入层使用dropout

Dropout可以应用在输入层的神经元。下例在输入层之后添加一个新的dropout层,dropout率设置为20%,这意味着每个更新周期中20%的输入将被随机排除。

SGD(随机梯度下降优化器)

keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)

包含扩展功能的支持: - 动量(momentum)优化, - 学习率衰减(每次参数更新后) - Nestrov 动量 (NAG) 优化

参数说明

lr: float >= 0. 。
momentum: float >= 0. 参数,用于加速 SGD 在相关方向上前进,并抑制震荡。
decay: float >= 0. 每次参数更新后学习率衰减值。
nesterov: boolean. 是否使用 Nesterov 动量。

Dropout也可用于可见层,如神经网络的输入。在这种情况下,就要把Dropout层作为网络的第一层,并将input_shape参数添加到层中,来制定预期输入

model.add(Dropout(rate=0.2, input_shape=(4,)))
from sklearn import datasets
import numpy as np
from keras.models import Sequential
from keras.layers import Dropout
from keras.layers import Dense
from 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)

# 构建模型函数
def create_model(init='glorot_uniform'):
    # 构建模型
    model = Sequential()
    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
    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()))

1.2 隐藏层使用dropout

Dropout也可以应用于神经网络模型中的隐藏层神经元。下例中,将在两个隐藏层之间,以及最后一个隐藏层和输出层之间使用dropout,将dropout率设置为20%,并对权重进行约束,使其最大限度不超过3。

from sklearn import datasets
import numpy as np
from keras.models import Sequential
from keras.layers import Dropout
from keras.layers import Dense
from keras.constraints import maxnorm
from 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)

# 构建模型函数
def create_model(init='glorot_uniform'):
    # 构建模型
    model = Sequential()
    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))

    # 定义Dropout
    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()))

1.3、dropout的使用技巧

(1)dropout率:20%-50%,太低(作用有限),太高(训练不充分)。
(2)较大网络上使用,可能会有更好的表现,因为降低了模型训练过程中的干扰。在网络的每一层使用效果都很好。
(3)使用较高的学习率,并使用学习率衰减和巨大的动量值,将学习率提高10-100倍,且使用0.9或0.99的高动量值。
(4)限制网络权重的大小。大的学习率可能导致非常大的网络权重。对网络权重的大小施加约束,例如大小为4或5的最大范数正则化。通过指定dense中kernel_constraint=maxnorm(3) 来限制网络权重。

二、学习率衰减

学习率过大(可能会越过最优值),学习率过小(长时间无法收敛)。
学习率衰减的基本思想是:学习率随着训练的进行逐渐衰减。
两种流行方法:线性衰减(根据epoch逐步降低学习率)和指数衰减(在特定epoch使用分数快速降低学习率)

2.1、学习率线性衰减

在keras中,基于时间的线性学习率衰减是通过SGD类中的随机梯度下降优化算法实现的,该类具有一个decay衰减率参数。该参数的线性学习率衰减方程如下:

learning rate = learning rate * 1/1+decay * epoch)

当decay衰减率为0(默认)的时候,对学习率没有影响;当使用非零学习率衰减的时候,学习率呈线性衰减。如学习率为0.1时,学习率衰减为0的结果如下:

 learning rate = 0.1* 1/1+0.0*1)
 learning rate = 0.1

当decay衰减率为0.001时,最初的5个epoch的学习率如下:

epoch     learning rate
1         0.1
2         0.0999000999
3         0.0997006985
4         0.09940249103
5         0.09900646517

下例学习率设定为较高的值0.1,epochs为200,decay为0.005,另外,动量值为0.9.

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 keras.optimizers import SGD


# 导入数据
dataset = datasets.load_iris()

x = dataset.data
Y = dataset.target

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

# 构建模型函数
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.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=5, verbose=1)
model.fit(x, Y)

2.2、学习率指数衰减

通过固定的epoch周期将学习速率降低50%来实现的。例如,初始学习率设定为0.1,每10个epochs降低50%。前10个epochs使用0.1的学习率,接下来的10个epochs使用0.05的学习率,学习率以指数级进行衰减。在Keras中,使用LearningRateScheduler回调来实现学习率的指数衰减。LearningRateScheduler回调使用预定义的回调函数来实现学习率的衰减,函数将epoch数作为一个参数,并将学习率返回到随机梯度下降算法中使用。
学习率指数衰减公式:

lrate = init_lrate * pow(drop, floor(1 + epoch) / epochs_drop)
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 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 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.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)

2.3、学习率衰减的使用技巧

提高初始学习率。 更大的学习率,在开始学习时会快速更新权重值,而且随着学习率的衰减可以自动调整学习率,这可以提高梯度下降的性能。
使用大动量。 使用较大的动量值将有助于优化算法在学习率缩小到小值时,继续向正确的方向更新权重值。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zking~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值