我从Coursera课程中了解了LearningRateScheduler,但如果直接照搬使用,模型性能会很差。可能是由于我设置的范围问题。Keras网站上的说明有限。
def duo_LSTM_model(X_train, y_train, X_test,y_test,num_classes,batch_size=68,units=128, learning_rate=0.005, epochs=20, dropout=0.2, recurrent_dropout=0.2 ): model = tf.keras.models.Sequential() model.add(tf.keras.layers.Masking(mask_value=0.0, input_shape=(X_train.shape[1], X_train.shape[2]))) model.add(tf.keras.layers.Bidirectional(LSTM(units, dropout=dropout, recurrent_dropout=recurrent_dropout,return_sequences=True))) model.add(tf.keras.layers.Bidirectional(LSTM(units, dropout=dropout, recurrent_dropout=recurrent_dropout))) model.add(Dense(num_classes, activation='softmax')) adamopt = tf.keras.optimizers.Adam(lr=learning_rate, beta_1=0.9, beta_2=0.999, epsilon=1e-8) RMSopt = tf.keras.optimizers.RMSprop(lr=learning_rate, rho=0.9, epsilon=1e-6) SGDopt = tf.keras.optimizers.SGD(lr=learning_rate, momentum=0.9, decay=0.1, nesterov=False) lr_schedule = tf.keras.callbacks.LearningRateScheduler( lambda epoch: 1e-8 * 10**(epoch / 20)) model.compile(loss='binary_crossentropy', optimizer=adamopt, metrics=['accuracy']) history = model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_data=(X_test, y_test), verbose=1, callbacks=[lr_schedule]) score, acc = model.evaluate(X_test, y_test, batch_size=batch_size) yhat = model.predict(X_test) return history, that
我有两个问题。
-
1e-8 * 10**(epoch / 20)
这是如何工作的? -
我们应该如何为三种不同的优化器选择范围?
回答:
在回答你帖子中的两个问题之前,让我们先澄清,LearningRateScheduler
并不是用来选择“最佳”学习率的。
我想你真正想问的是“如何确定最佳的初始学习率”。如果我的理解正确,那么你需要学习关于超参数调优的知识。
对问题1的回答:
为了解释1e-8 * 10**(epoch / 20)
是如何工作的,让我们创建一个简单的回归任务
import tensorflow as tf import tensorflow.keras.backend as Kfrom sklearn.model_selection import train_test_splitfrom tensorflow.keras.models import Modelfrom tensorflow.keras.layers import Input,Densex = np.linspace(0,100,1000)y = np.sin(x) + x**2x_train,x_val,y_train,y_val = train_test_split(x,y,test_size=0.3)input_x = Input(shape=(1,))y = Dense(10,activation='relu')(input_x)y = Dense(1,activation='relu')(y)model = Model(inputs=input_x,outputs=y)adamopt = tf.keras.optimizers.Adam(lr=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-8)def schedule_func(epoch): print() print('在第 %i 个epoch调用lr_scheduler' % epoch) print('当前学习率 %.8f' % K.eval(model.optimizer.lr)) print('返回值 %.8f' % (1e-8 * 10**(epoch / 20))) return 1e-8 * 10**(epoch / 20) lr_schedule = tf.keras.callbacks.LearningRateScheduler(schedule_func)model.compile(loss='mse',optimizer=adamopt,metrics=['mae'])history = model.fit(x_train,y_train, batch_size=8, epochs=10, validation_data=(x_val, y_val), verbose=1, callbacks=[lr_schedule])
在上面的脚本中,我没有使用lambda
函数,而是编写了一个schedule_func
函数。运行脚本,你会看到1e-8 * 10**(epoch / 20)
只是为每个epoch
设置学习率,并且学习率在增加。
对问题2的回答:
有很多不错的文章,例如