如何在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等)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。