我如何创建基于批次而非年代更新的Keras学习率计划

我如何创建基于批次而非年代更新的Keras学习率计划,keras,keras-2,Keras,Keras 2,我正在与Keras合作,并试图创建一个学习速率调度器,该调度器根据处理的批次数而不是历代数进行调度。为此,我将调度代码插入到我的“优化器”的get\u updates方法中。在大多数情况下,我尝试对在给定的训练运行期间保持不变的值使用常规Python变量,对实际变化的参数使用计算图节点 我的两个问题是: 如果将下面的代码放在Keras优化器的get\u updates方法中,它是否应该作为学习率计划程序正常运行 如何将此代码嵌入到类似于LearningRateScheduler的类中,但该类是基

我正在与Keras合作,并试图创建一个学习速率调度器,该调度器根据处理的批次数而不是历代数进行调度。为此,我将调度代码插入到我的“优化器”的
get\u updates
方法中。在大多数情况下,我尝试对在给定的训练运行期间保持不变的值使用常规Python变量,对实际变化的参数使用计算图节点

我的两个问题是:

  • 如果将下面的代码放在
    Keras
    优化器的
    get\u updates
    方法中,它是否应该作为学习率计划程序正常运行

  • 如何将此代码嵌入到类似于
    LearningRateScheduler
    的类中,但该类是基于批数而非纪元数进行调度的


  • #复制存储学习率原始值的图形节点
    lr=self.lr
    #检查是否使用学习率计划
    如果自初始衰减>0:
    #这种衰变模拟了从一开始的指数衰变
    #tensorflow/python/keras/optimizer\u v2/指数衰减
    #从图形节点获取当前已处理批次数的值
    #并将其转换为数值,以便在K.pow()中使用
    curr\u batch=float(K.get\u值(self.iterations))
    #创建包含lr衰减因子的图形节点
    #注意:self.lr_decation_steps是一个数字,而不是节点
    #self.lr_decay是一个节点,而不是一个数字
    衰减系数=K.pow(自衰减(当前批次/自衰减步数))
    #将lr重新分配给由
    #含衰减因子的图结点的乘积
    #以及包含原始学习率的图节点。
    lr=lr*衰减系数
    #获取两个数字的乘积以计算处理的批次数
    #热身期
    num_warmup_batches=self.steps_per_epoch_num*self.warmup_epoch
    #对数据进行比较,以确定我们是否处于预热期
    如果(自预热时间>0)和(当前批次<数量预热批次):
    #通过乘以一个数字创建具有学习率值的节点
    #由一个节点,然后除以一个数字
    lr=(自初始值)*
    K.cast(self.iterations,K.floatx())/curr\u batch)
    
    比处理Keras源代码更容易(这是可能的,但复杂而合理),您可以使用回调

    from keras.callbacks import LambdaCallback
    
    total_batches = 0
    def what_to_do_when_batch_ends(batch, logs):
       total_batches += 1 #or use the "batch" variable,
                          #which is the batch index of the last finished batch
    
       #change learning rate at will
       if your_condition == True:
           keras.backend.set_value(model.optimizer.lr, newLrValueAsPythonFloat)
    
    培训时,使用回调函数:

    lrUpdater = LambdaCallback(on_batch_end = what_to_do_when_batch_ends)
    model.fit(........, callbacks = [lrUpdater, ...other callbacks...])
    

    -谢谢,我会读到LambdaCallback的。但我不能只使用model.optimizer.iterations来跟踪我的批处理吗?在培训期间,这不是很容易,它是一个符号张量,您无法对其进行评估,然后您将需要使用基于张量函数的条件,而不是ifs和更新函数。这很复杂。可能,但复杂。嗨,Daniel,我在这里遇到了同样的问题(希望使学习速率根据批次而不是历元衰减)。你的答案中的解决方案很清楚。但是我还有一个问题,关于“keras.backend.set_value(model.optimizer.lr,newlrvaluaseaspythonfloat)”中用于获取学习率的“model”变量“。在一个不是回调的函数中调用model是否可行。我的意思是,在回调中,我可以从self.model调用model,但在我可以直接建模的函数中,会有一个关于未解析”model的错误“。期待您的答复。提前感谢。抱歉,错误不是未解析的模型,而是未定义名称“model”。如果未定义
    model
    ,请使用定义为model的名称。如您所见,lambda回调不接受“self”。因此,您可以选择创建自己的回调,然后从创建的自定义回调中获取
    self.model
    ,也可以使用定义模型的变量。幸运的是,您可以使用
    lrUpdater从回调中获取模型。从未测试过的模型可能有一些怪癖。
    
    lrUpdater = LambdaCallback(on_batch_end = what_to_do_when_batch_ends)
    model.fit(........, callbacks = [lrUpdater, ...other callbacks...])