model.compile(loss='mean_squared_error', optimizer='sgd')
可用的目标函数
优化器是编译Keras模型必要的两个参数之一
from keras import optimizers
model = Sequential()
model.add(Dense(64, init='uniform', input_shape=(10,)))
model.add(Activation('tanh'))
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()时传递一个预定义优化器名。在后者情形下,优化器的参数将使用默认值。
# pass optimizer by name: default parameters will be used
model.compile(loss='mean_squared_error', optimizer='sgd')
参数clipnorm和clipvalue是所有优化器都可以使用的参数,用于对梯度进行裁剪.示例如下:
from keras import optimizers
# All parameter gradients will be clipped to
# a maximum norm of 1.
sgd = optimizers.SGD(lr=0.01, clipnorm=1.)
from keras import optimizers
# All parameter gradients will be clipped to
# a maximum value of 0.5 and
# a minimum value of -0.5.
sgd = optimizers.SGD(lr=0.01, clipvalue=0.5)
keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)
随机梯度下降法,支持动量参数,支持学习衰减率,支持Nesterov动量
keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-06)
除学习率可调整外,建议保持优化器的其他默认参数不变
该优化器通常是面对递归神经网络时的一个良好选择
keras.optimizers.Adagrad(lr=0.01, epsilon=1e-06)
建议保持优化器的默认参数不变
keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=1e-06)
建议保持优化器的默认参数不变
keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
该优化器的默认值来源于参考文献
keras.optimizers.Adamax(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
Adamax优化器来自于Adam的论文的Section7,该方法是基于无穷范数的Adam方法的变体。
默认参数由论文提供
keras.optimizers.Nadam(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08, schedule_decay=0.004)
Nesterov Adam optimizer: Adam本质上像是带有动量项的RMSprop,Nadam就是带有Nesterov 动量的Adam RMSprop
默认参数来自于论文,推荐不要对默认参数进行更改。
keras.optimizers.TFOptimizer(optimizer)
TF优化器的包装器
激活函数可以通过设置单独的激活层实现,也可以在构造层对象时通过传递activation参数实现。
from keras.layers import Activation, Dense
model.add(Dense(64))
model.add(Activation('tanh'))
等价于
model.add(Dense(64, activation='tanh'))
也可以通过传递一个逐元素运算的Theano/TensorFlow函数来作为激活函数:
from keras import backend as K
def tanh(x):
return K.tanh(x)
model.add(Dense(64, activation=tanh))
model.add(Activation(tanh)
对于简单的Theano/TensorFlow不能表达的复杂激活函数,如含有可学习参数的激活函数,可通过高级激活函数实现,如PReLU,LeakyReLU等
性能评估模块提供了一系列用于模型性能评估的函数,这些函数在模型编译时由metrices关键字设置。
性能评估函数类似与目标函数, 只不过该性能的评估结果讲不会用于训练.
可以通过字符串来使用域定义的性能评估函数
model.compile(loss='mean_squared_error',
optimizer='sgd',
metrics=['mae', 'acc'])
也可以自定义一个Theano/TensorFlow函数并使用之
from keras import metrics
model.compile(loss='mean_squared_error',
optimizer='sgd',
metrics=[metrics.mae, metrics.categorical_accuracy])
除fbeta_score额外拥有默认参数beta=1外,其他各个性能指标的参数均为y_true和y_pred
定制的评估函数可以在模型编译时传入,该函数应该以(y_true, y_pred)为参数,并返回单个张量,或从metric_name映射到metric_value的字典,下面是一个示例:
(y_true, y_pred) as arguments and return a single tensor value.
import keras.backend as K
def mean_pred(y_true, y_pred):
return K.mean(y_pred)
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy', mean_pred])
初始化方法定义了对Keras层设置初始化权重的方法
不同的层可能使用不同的关键字来传递初始化方法,一般来说指定初始化方法的关键字是kernel_initializer 和 bias_initializer,例如:
model.add(Dense(64,
kernel_initializer='random_uniform',
bias_initializer='zeros'))
一个初始化器可以由字符串指定(必须是下面的预定义初始化器之一),或一个callable的函数,例如
from keras import initializers
model.add(Dense(64, kernel_initializer=initializers.random_normal(stddev=0.01)))
# also works; will use the default parameters.
model.add(Dense(64, kernel_initializer='random_normal'))
Initializer是所有初始化方法的父类,不能直接使用,如果想要定义自己的初始化方法,请继承此类。
keras.initializers.Zeros()
全零初始化
keras.initializers.Ones()
全1初始化
keras.initializers.Constant(value=0)
初始化为固定值value
keras.initializers.RandomNormal(mean=0.0, stddev=0.05, seed=None))
正态分布初始化
keras.initializers.RandomUniform(minval=-0.05, maxval=0.05, seed=None)
均匀分布初始化
minval:均匀分布下边界
maxval:均匀分布上边界
seed:随机数种子
keras.initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None)
截尾高斯分布初始化,该初始化方法与RandomNormal类似,但位于均值两个标准差以外的数据将会被丢弃并重新生成,形成截尾分布。该分布是神经网络权重和滤波器的推荐初始化方法。
keras.initializers.VarianceScaling(scale=1.0, mode='fan_in', distribution='normal', seed=None)
该初始化方法能够自适应目标张量的shape。
keras.initializers.Orthogonal(gain=1.0, seed=None)
用随机正交矩阵初始化
keras.initializers.Identity(gain=1.0)
使用单位矩阵初始化,仅适用于2D方阵
lecun_uniform(seed=None)
LeCun均匀分布初始化方法,参数由[-limit, limit]的区间中均匀采样获得,其中limit=sqrt(3 / fan_in), fin_in是权重向量的输入单元数(扇入)
glorot_normal(seed=None)
Glorot正态分布初始化方法,也称作Xavier正态分布初始化,参数由0均值,标准差为sqrt(2 / (fan_in + fan_out))的正态分布产生,其中fan_in和fan_out是权重张量的扇入扇出(即输入和输出单元数目)
he_normal(seed=None)
He正态分布初始化方法,也称作Xavier正态分布初始化,参数由0均值,标准差为sqrt(2 / fan_in) 的正态分布产生,其中fan_in权重张量的扇入
he_normal(seed=None)
LeCun均匀分布初始化方法,参数由[-limit, limit]的区间中均匀采样获得,其中limit=sqrt(6 / fan_in), fin_in是权重向量的输入单元数(扇入)
如果需要传递自定义的初始化器,则该初始化器必须是callable的,并且接收shape(将被初始化的张量shape)和dtype(数据类型)两个参数,并返回符合shape和dtype的张量。
from keras import backend as K
def my_init(shape, dtype=None):
return K.random_normal(shape, dtype=dtype)
model.add(Dense(64, init=my_init))
正则项在优化过程中层的参数或层的激活值添加惩罚项,这些惩罚项将与损失函数一起作为网络的最终优化目标
例子
from keras import regularizers
model.add(Dense(64, input_dim=64,
kernel_regularizer=regularizers.l2(0.01),
activity_regularizer=regularizers.l1(0.01)))
keras.regularizers.l1(0.)
keras.regularizers.l2(0.)
keras.regularizers.l1_l2(0.)
任何以权重矩阵作为输入并返回单个数值的函数均可以作为正则项,示例:
from keras import backend as K
def l1_reg(weight_matrix):
return 0.01 * K.sum(K.abs(weight_matrix))
model.add(Dense(64, input_dim=64,
kernel_regularizer=l1_reg)
可参考源代码keras/regularizer.py
来自constraints模块的函数在优化过程中为网络的参数施加约束
from keras.constraints import maxnorm
model.add(Dense(64, kernel_constraint=max_norm(2.)))
回调函数是一组在训练的特定阶段被调用的函数集,你可以使用回调函数来观察训练过程中网络内部的状态和统计信息。通过传递回调函数列表到模型的.fit()中,即可在给定的训练阶段调用该函数集中的函数。
keras.callbacks.Callback()
这是回调函数的抽象类,定义新的回调函数必须继承自该类
目前,模型的.fit()中有下列参数会被记录到logs中:
keras.callbacks.BaseLogger()
该回调函数用来对每个epoch累加metrics指定的监视指标的epoch平均值
该回调函数在每个Keras模型中都会被自动调用
keras.callbacks.ProgbarLogger()
该回调函数用来将metrics指定的监视指标输出到标准输出上
keras.callbacks.History()
该回调函数在Keras模型上会被自动调用,History对象即为fit方法的返回值
keras.callbacks.ModelCheckpoint(filepath, monitor='val_loss', verbose=0, save_best_only=False, save_weights_only=False, mode='auto', period=1)
该回调函数将在每个epoch后保存模型到filepath
filepath可以是格式化的字符串,里面的占位符将会被epoch值和传入on_epoch_end的logs关键字所填入
例如,filepath若为weights.{epoch:02d-{val_loss:.2f}}.hdf5,则会生成对应epoch和验证集loss的多个文件。
keras.callbacks.EarlyStopping(monitor='val_loss', patience=0, verbose=0, mode='auto')
当监测值不再改善时,该回调函数将中止训练
keras.callbacks.RemoteMonitor(root='http://localhost:9000')
该回调函数用于向服务器发送事件流,该回调函数需要requests库
keras.callbacks.LearningRateScheduler(schedule)
该回调函数是学习率调度器
keras.callbacks.TensorBoard(log_dir='./logs', histogram_freq=0, write_graph=True, write_images=False, embeddings_freq=0, embeddings_layer_names=None, embeddings_metadata=None)
该回调函数是一个可视化的展示器
TensorBoard是TensorFlow提供的可视化工具,该回调函数将日志信息写入TensorBorad,使得你可以动态的观察训练和测试指标的图像以及不同层的激活值直方图。
如果已经通过pip安装了TensorFlow,我们可通过下面的命令启动TensorBoard:
tensorboard --logdir=/full_path_to_your_logs
keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=10, verbose=0, mode='auto', epsilon=0.0001, cooldown=0, min_lr=0)
当评价指标不在提升时,减少学习率
当学习停滞时,减少2倍或10倍的学习率常常能获得较好的效果。该回调函数检测指标的情况,如果在patience个epoch中看不到模型性能提升,则减少学习率
keras.callbacks.CSVLogger(filename, separator=',', append=False)
将epoch的训练结果保存在csv文件中,支持所有可被转换为string的值,包括1D的可迭代数值如np.ndarray.
keras.callbacks.LambdaCallback(on_epoch_begin=None, on_epoch_end=None, on_batch_begin=None, on_batch_end=None, on_train_begin=None, on_train_end=None)
用于创建简单的callback的callback类
示例
# Print the batch number at the beginning of every batch.
batch_print_callback = LambdaCallback(
on_batch_begin=lambda batch,logs: print(batch))
# Plot the loss after every epoch.
import numpy as np
import matplotlib.pyplot as plt
plot_loss_callback = LambdaCallback(
on_epoch_end=lambda epoch, logs: plt.plot(np.arange(epoch),
logs['loss']))
# Terminate some processes after having finished model training.
processes = ...
cleanup_callback = LambdaCallback(
on_train_end=lambda logs: [
p.terminate() for p in processes if p.is_alive()])
model.fit(...,
callbacks=[batch_print_callback,
plot_loss_callback,
cleanup_callback])
我们可以通过继承keras.callbacks.Callback编写自己的回调函数,回调函数通过类成员self.model访问访问,该成员是模型的一个引用。
这里是一个简单的保存每个batch的loss的回调函数:
class LossHistory(keras.callbacks.Callback):
def on_train_begin(self, logs={}):
self.losses = []
def on_batch_end(self, batch, logs={}):
self.losses.append(logs.get('loss'))
例子:记录损失函数的历史数据
class LossHistory(keras.callbacks.Callback):
def on_train_begin(self, logs={}):
self.losses = []
def on_batch_end(self, batch, logs={}):
self.losses.append(logs.get('loss'))
model = Sequential()
model.add(Dense(10, input_dim=784, kernel_initializer='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
history = LossHistory()
model.fit(X_train, Y_train, batch_size=128, epochs=20, verbose=0, callbacks=[history])
print history.losses
# outputs
'''
[0.66047596406559383, 0.3547245744908703, ..., 0.25953155204159617, 0.25901699725311789]
例子:模型检查点
from keras.callbacks import ModelCheckpoint
model = Sequential()
model.add(Dense(10, input_dim=784, kernel_initializer='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
'''
saves the model weights after each epoch if the validation loss decreased
'''
checkpointer = ModelCheckpoint(filepath="/tmp/weights.hdf5", verbose=1, save_best_only=True)
model.fit(X_train, Y_train, batch_size=128, epochs=20, verbose=0, validation_data=(X_test, Y_test), callba