【问题标题】:Using the optimal learning rate results in random guessing accuracy使用最佳学习率会导致随机猜测准确度
【发布时间】:2020-09-03 17:26:40
【问题描述】:

我正在通过 Aurélien Géron 的 使用 Scikit-Learn、Keras 和 TensorFlow 进行机器学习实践,我正在尝试在解决练习时弄清我做错了什么.这是第 11 章中的练习 8。我要做的是在 CIFAR10 数据集上训练一个有 20 个隐藏层,每个 100 个神经元的神经网络,使用激活函数 ELU 和权重初始化器 He Normal(我知道 100 个神经元的 20 个隐藏层是很多,但这就是练习的重点,所以请耐心等待)。我必须使用 Early Stopping 和 Nadam 优化器。

我的问题是我不知道要使用什么学习率。在解决方案笔记本中,作者列出了一堆他尝试并使用了他找到的最好的学习率。我对此并不满意,我决定自己尝试找到最佳学习率。所以我使用了书中推荐的一种技术:将网络训练一个 epoch,在每次迭代中成倍增加学习率。然后将损失绘制为学习率的函数,查看损失达到最小值的位置,然后选择稍小的学习率(因为这是上限)。

这是我模型中的代码:

model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=[32, 32, 3]))
for _ in range(20):
    model.add(keras.layers.Dense(100,
                             activation="elu",
                             kernel_initializer="he_normal"))

model.add(keras.layers.Dense(10, activation="softmax"))
optimizer = keras.optimizers.Nadam(lr=1e-5)
model.compile(loss="sparse_categorical_crossentropy",
              optimizer=optimizer,
              metrics=["accuracy"])

(忽略学习率的值,这没关系,因为我正在尝试找到正确的。)

这里是用于找到最佳学习率的代码:

class ExponentialLearningRate(keras.callbacks.Callback):
    def __init__(self, factor):
        self.factor = factor
        self.rates = []
        self.losses = []
    def on_batch_end(self, batch, logs):
        self.rates.append(keras.backend.get_value(self.model.optimizer.lr))
        self.losses.append(logs["loss"])
        keras.backend.set_value(self.model.optimizer.lr, self.model.optimizer.lr * self.factor)

def find_learning_rate(model, X, y, epochs=1, batch_size=32, min_rate=10**-5, max_rate=10):
    init_weights = model.get_weights()
    init_lr = keras.backend.get_value(model.optimizer.lr)
    iterations = len(X) // batch_size * epochs
    factor = np.exp(np.log(max_rate / min_rate) / iterations)
    keras.backend.set_value(model.optimizer.lr, min_rate)
    exp_lr = ExponentialLearningRate(factor)
    history = model.fit(X, y, epochs = epochs, batch_size = batch_size, callbacks = [exp_lr])
    keras.backend.set_value(model.optimizer.lr, init_lr)
    model.set_weights(init_weights)
    return exp_lr.rates, exp_lr.losses

def plot_lr_vs_losses(rates, losses):
    plt.figure(figsize=(10, 5))
    plt.plot(rates, losses)
    plt.gca().set_xscale("log")
    plt.hlines(min(losses), min(rates), max(rates))
    plt.axis([min(rates), max(rates), min(losses), losses[0] + min(losses) / 2])
    plt.xlabel("Learning rate")
    plt.ylabel("Loss")

find_learning_rate() 函数在每次迭代中以指数方式提高学习率,从最小学习率 10^(-5) 到最大学习率 10。之后,我使用 function plot_lr_vs_losses() 绘制了曲线这就是我得到的:

看起来使用 1e-2 的学习率会很棒,对吧?但是当我重新编译模型时,以1e-2 的学习率,模型在训练集和验证集上的准确率都在 10% 左右,这就像随机选择一样,因为我们有 10 个类。我使用了提前停止,所以我不能说我让模型训练了太多 epoch(我用了 100 个)。但即使在训练期间,模型也没有学到任何东西,训练集和验证集的准确率始终在 10% 左右。

当我使用更小的学习率(作者在解决方案笔记本中使用的那个)时,整个问题就消失了。当我使用5e-5 的学习率时,模型正在学习并在验证集上达到大约 50% 的准确度(这是练习所期望的,与作者得到的准确度相同)。但是,使用图中指示的学习率怎么会这么糟糕呢?我在网上看了一点,这种成倍增加学习率的方法似乎被很多人使用,所以我真的不明白我做错了什么。

【问题讨论】:

    标签: python machine-learning keras deep-learning neural-network


    【解决方案1】:

    您正在对未知探索空间使用启发式搜索方法。如果没有关于模型/数据特征的更多信息,很难说出了什么问题。

    我的第一个担心是损失突然上升到有效无穷大;您在 yoru 探索空间中的边缘平滑,这表明较大的空间(包括许多训练时期)具有高度干扰性的边界。任何接近 epoch-=1 边界的学习率都有可能在以后的 epoch 中跌跌撞撞,给你留下随机分类。

    您使用的启发式方法基于几个假设。

    • 作为学习率函数的收敛速度相对平滑
    • 最终准确度几乎与学习率无关。 您的模型似乎没有表现出这些特征。

    启发式训练只在一个时期;在不同的学习率下收敛模型需要多少个 epoch?如果学习率太大,模型可能会非常缓慢地完成最终收敛,因为它会围绕最佳点。也有可能您从未以太大的速率接近该点。

    如果没有针对那个 epoch-1 测试映射收敛空间,我们就无法正确分析问题。但是,您可以尝试相关实验:可能从 10^-4 开始,完全训练您的模型(检测收敛并停止)。重复,每次将 LR 乘以 3。当您在 0.0081 附近进入非收敛状态时,您会感觉到不再收敛。

    现在按照您认为合适的方式细分该范围 [.0027, .0081]。一旦你找到一个确实收敛的上端点,你就可以使用它来指导最终搜索最佳学习率。

    【讨论】:

    • 那么这种方法怎么样(我一般在想,对于未来的问题也是如此):我尝试这种方法,在 3-5 个 epoch 的跨度内以指数方式提高学习率(我不会t 像我在这里做的那样只使用 1 个 epoch),然后将损失绘制为学习率的函数。如果我看到任何可疑的东西(比如损失突然上升到无穷大,或者模型没有收敛的事实),我开始尝试各种学习率,从小到大,只训练 10-20 个 epoch。然后我使用在验证集上获得最佳准确性的那个。这个呢?
    • 对 Stack Overflow 的工作效果的推测是题外话。对于某些实验空间来说,这种方法是一种合理的方法。如果不知道更多关于模型和数据的信息,我们就无法预测。我可以说明这将是一个非常好的或非常坏的方法的条件,但是这样做对于这个论坛来说太宽泛了。
    • 我明白了。但是你能指出我学习这些东西的正确方向吗?如何选择正确的学习率以及与之相关的一切?你有什么可以推荐给我的资源吗?非常感谢您抽出宝贵时间!
    • (1) 询问此类资源对于 Stack Overflow 来说是题外话。 (2) 不,这不是单一来源的东西。这是您在一般情况下学习并学习应用于您的特定情况的“背景艺术”。
    猜你喜欢
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    • 2020-02-01
    • 2019-01-01
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多