1. 程式人生 > 程式設計 >如何在keras中新增自己的優化器(如adam等)

如何在keras中新增自己的優化器(如adam等)

本文主要討論windows下基於tensorflow的keras

1、找到tensorflow的根目錄

如果安裝時使用anaconda且使用預設安裝路徑,則在 C:\ProgramData\Anaconda3\envs\tensorflow-gpu\Lib\site-packages\tensorflow處可以找到(此處為GPU版本),cpu版本可在C:\ProgramData\Anaconda3\Lib\site-packages\tensorflow處找到。若並非使用預設安裝路徑,可參照根目錄檢視找到。

2、找到keras在tensorflow下的根目錄

需要特別注意的是找到keras在tensorflow下的根目錄而不是找到keras的根目錄。一般來說,完成tensorflow以及keras的配置後即可在tensorflow目錄下的python目錄中找到keras目錄,以GPU為例keras在tensorflow下的根目錄為C:\ProgramData\Anaconda3\envs\tensorflow-gpu\Lib\site-packages\tensorflow\python\keras

3、找到keras目錄下的optimizers.py檔案並新增自己的優化器

找到optimizers.py中的adam等優化器類並在後面新增自己的優化器類

以本文來說,我在第718行新增如下程式碼

@tf_export('keras.optimizers.adamsss')
class Adamsss(Optimizer):

 def __init__(self,lr=0.002,beta_1=0.9,beta_2=0.999,epsilon=None,schedule_decay=0.004,**kwargs):
 super(Adamsss,self).__init__(**kwargs)
 with K.name_scope(self.__class__.__name__):
  self.iterations = K.variable(0,dtype='int64',name='iterations')
  self.m_schedule = K.variable(1.,name='m_schedule')
  self.lr = K.variable(lr,name='lr')
  self.beta_1 = K.variable(beta_1,name='beta_1')
  self.beta_2 = K.variable(beta_2,name='beta_2')
 if epsilon is None:
  epsilon = K.epsilon()
 self.epsilon = epsilon
 self.schedule_decay = schedule_decay

 def get_updates(self,loss,params):
 grads = self.get_gradients(loss,params)
 self.updates = [state_ops.assign_add(self.iterations,1)]

 t = math_ops.cast(self.iterations,K.floatx()) + 1

 # Due to the recommendations in [2],i.e. warming momentum schedule
 momentum_cache_t = self.beta_1 * (
  1. - 0.5 *
  (math_ops.pow(K.cast_to_floatx(0.96),t * self.schedule_decay)))
 momentum_cache_t_1 = self.beta_1 * (
  1. - 0.5 *
  (math_ops.pow(K.cast_to_floatx(0.96),(t + 1) * self.schedule_decay)))
 m_schedule_new = self.m_schedule * momentum_cache_t
 m_schedule_next = self.m_schedule * momentum_cache_t * momentum_cache_t_1
 self.updates.append((self.m_schedule,m_schedule_new))

 shapes = [K.int_shape(p) for p in params]
 ms = [K.zeros(shape) for shape in shapes]
 vs = [K.zeros(shape) for shape in shapes]

 self.weights = [self.iterations] + ms + vs

 for p,g,m,v in zip(params,grads,ms,vs):
  # the following equations given in [1]
  g_prime = g / (1. - m_schedule_new)
  m_t = self.beta_1 * m + (1. - self.beta_1) * g
  m_t_prime = m_t / (1. - m_schedule_next)
  v_t = self.beta_2 * v + (1. - self.beta_2) * math_ops.square(g)
  v_t_prime = v_t / (1. - math_ops.pow(self.beta_2,t))
  m_t_bar = (
   1. - momentum_cache_t) * g_prime + momentum_cache_t_1 * m_t_prime

  self.updates.append(state_ops.assign(m,m_t))
  self.updates.append(state_ops.assign(v,v_t))

  p_t = p - self.lr * m_t_bar / (K.sqrt(v_t_prime) + self.epsilon)
  new_p = p_t

  # Apply constraints.
  if getattr(p,'constraint',None) is not None:
  new_p = p.constraint(new_p)

  self.updates.append(state_ops.assign(p,new_p))
 return self.updates

 def get_config(self):
 config = {
  'lr': float(K.get_value(self.lr)),'beta_1': float(K.get_value(self.beta_1)),'beta_2': float(K.get_value(self.beta_2)),'epsilon': self.epsilon,'schedule_decay': self.schedule_decay
 }
 base_config = super(Adamsss,self).get_config()
 return dict(list(base_config.items()) + list(config.items()))

然後修改之後的優化器呼叫類新增我自己的優化器adamss

需要修改的有(下面的兩處修改依舊在optimizers.py內)

# Aliases.

sgd = SGD
rmsprop = RMSprop
adagrad = Adagrad
adadelta = Adadelta
adam = Adam
adamsss = Adamsss
adamax = Adamax
nadam = Nadam

以及

def deserialize(config,custom_objects=None):
 """Inverse of the `serialize` function.

 Arguments:
  config: Optimizer configuration dictionary.
  custom_objects: Optional dictionary mapping
   names (strings) to custom objects
   (classes and functions)
   to be considered during deserialization.

 Returns:
  A Keras Optimizer instance.
 """
 if tf2.enabled():
 all_classes = {
  'adadelta': adadelta_v2.Adadelta,'adagrad': adagrad_v2.Adagrad,'adam': adam_v2.Adam,'adamsss': adamsss_v2.Adamsss,'adamax': adamax_v2.Adamax,'nadam': nadam_v2.Nadam,'rmsprop': rmsprop_v2.RMSprop,'sgd': gradient_descent_v2.SGD
 }
 else:
 all_classes = {
  'adadelta': Adadelta,'adagrad': Adagrad,'adam': Adam,'adamax': Adamax,'nadam': Nadam,'adamsss': Adamsss,'rmsprop': RMSprop,'sgd': SGD,'tfoptimizer': TFOptimizer
 }

這裡我們並沒有v2版本,所以if後面的部分不改也可以。

4、呼叫我們的優化器對模型進行設定

model.compile(loss = 'crossentropy',optimizer = 'adamss',metrics=['accuracy'])

5、訓練模型

train_history = model.fit(x,y_label,validation_split = 0.2,epoch = 10,batch = 128,verbose = 1)

補充知識:keras設定學習率--優化器的用法

優化器的用法

優化器 (optimizer) 是編譯 Keras 模型的所需的兩個引數之一:

from keras import optimizers
 
model = Sequential()
model.add(Dense(64,kernel_initializer='uniform',input_shape=(10,)))
model.add(Activation('softmax'))
 
sgd = optimizers.SGD(lr=0.01,decay=1e-6,momentum=0.9,nesterov=True)
model.compile(loss='mean_squared_error',optimizer=sgd)

你可以先例項化一個優化器物件,然後將它傳入 model.compile(),像上述示例中一樣, 或者你可以通過名稱來呼叫優化器。在後一種情況下,將使用優化器的預設引數。

# 傳入優化器名稱: 預設引數將被採用
model.compile(loss='mean_squared_error',optimizer='sgd')

以上這篇如何在keras中新增自己的優化器(如adam等)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。