【问题标题】:passing keras optimizer as string parameter to keras optimizer function将 keras 优化器作为字符串参数传递给 keras 优化器函数
【发布时间】:2020-03-14 05:25:17
【问题描述】:

我正在借助包含超参数的 config.json 文件调整 keras 深度学习模型的超参数。

    { “opt: “Adam”,
      “lr”: 0.01,
       “grad_clip”: 0.5
    }

Keras 允许通过两种方式指定优化器:

  1. 在调用函数时作为字符串参数,不带附加参数。
model.compile(loss='categorical_crossentropy’,
              optimizer=’Adam’, 
              metrics=['mse'])
  1. 作为带有附加参数的同名函数。
model.compile(loss='categorical_crossentropy',
              optimizer=optimizers.Adam(lr=0.01, clipvalue=0.5), 
              metrics=['mse'])

我的问题是:如何将优化器(SGD、Adam 等)作为参数从配置文件与子参数一起传递,并使用 (2) 中的 keras.optimizers.optimizer() 函数调用?

from keras.models import Sequential
from keras.layers import LSTM, Dense, TimeDistributed, Bidirectional
from keras import optimizers

def train(X,y, opt, lr, clip):

   model = Sequential()
   model.add(Bidirectional(LSTM(100, return_sequences=True), input_shape=(500, 300)))    
   model.add(TimeDistributed(Dense(5, activation='sigmoid')))

   model.compile(loss='categorical_crossentropy',
                  optimizer=optimizers.opt(lr=lr, clipvalue=clip), 
                  metrics=['mse'])

   model.fit(X, y, epochs=100, batch_size=1, verbose=2)

   return(model)

当我尝试将配置文件中的参数传递给上述train() 函数时,出现以下错误:

AttributeError: module 'keras.optimizers' has no attribute 'opt'

如何将字符串中的优化器解析为函数?

【问题讨论】:

  • 您的最新编辑应该可以修复您在问题底部提出的错误。您现在遇到什么错误(如果有的话)?
  • 我在重新运行代码后更新了错误。它与我在问题中提出的问题更直接相关:如何将字符串解析为属性?

标签: python optimization keras deep-learning parameter-passing


【解决方案1】:

您可以使用这样的类来构造优化器:

class Optimizer:
    def __init__(self, lr, clip):
        self.lr=lr
        self.clip = clip

    def get_opt(self, opt):
        """Dispatch method"""
        method_name = 'opt_' + str(opt)
        # Get the method from 'self'. Default to a lambda.
        method = getattr(self, method_name, lambda: "Invalid optimizier")
        # Call the method as we return it
        return method()

    def opt_Adam(self):
        return optimizers.Adam(lr=self.lr, clipvalue=self.clip)

    def opt_example(self):
        return  optimizers.example(lr=self.lr, clipvalue=self.clip)

    #and so on for how many cases you would need

那么你可以这样称呼它:

a=Optimizer(lr, clip)
model.compile(loss='categorical_crossentropy',
              optimizer=a.get_opt(opt=opt), 
              metrics=['mse'])

【讨论】:

  • 我是否需要将“lr”和“clip”定义为类属性,如下所示:def __init__(self): self.lr = .0 self.clip = .0,然后引用它们作为方法中的“self.lr”和“self.clip”?如果是这样,这种变化对通话有何影响?就目前而言,解释器会抱怨类声明中未定义的变量名,并在执行代码时抛出错误。
  • 嘿!我更新了代码,抱歉一开始我没有测试就写了,它现在应该可以工作了:)
  • 如果解决了您的问题,请选择已接受的答案
【解决方案2】:

您可以初始化一个包含优化器初始化的 json 配置文件: 例如:

"Adam": {
    "lr":0.001, 
    "beta_1":0.9, 
    "beta_2":0.999, 
    "epsilon":None, 
    "decay":0.0, 
    "amsgrad":False
    }

然后您可以使用以下行从配置中解析它:

with open('configuration.json') as json_data_file:
    data = json.load(json_data_file)

在数据结构中你会发现优化器的参数设置:

optimizer = data["Adam"]

毕竟,您可以访问所选优化器的所有参数:

lr = data["lr"]
beta_1 = data["beta_1"]
etc...

另一种方法是仅使用配置文件来访问优化器的配置。使用 Keras,您可以使用优化器调度程序从配置文件中选择特定的优化器来编译您的神经网络:

optimizer= {"Adam": keras.optimizers.Adam(**config}

请记住,配置文件中的 keras 优化器名称应该相同。

【讨论】:

    【解决方案3】:

    确保您的 csl 对象(配置对象)的键实际上与类的那些参数匹配。然后,以下将创建优化器对象,从配置对象中搜索适当的参数,并将它们传递给它

    csl = { "opt": "Adam",
      "lr": 0.01,
       "grad_clip": 0.5}
    optimizer = eval(f"keras.optimizers.{csl["opt"]}")()
    optimizer = optimizer.from_config({k:v for k,v in csl.items() if hasattr(optimizer, k)})
    

    【讨论】:

      猜你喜欢
      • 2019-09-27
      • 2019-12-23
      • 1970-01-01
      • 2020-05-18
      • 1970-01-01
      • 1970-01-01
      • 2020-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多