损失函数
model.compile(loss='mean_squared_error', optimizer='sgd')
可用的目标函数
- mean_squared_error或mse
- mean_absolute_error或mae
- mean_absolute_percentage_error或mape
- mean_squared_logarithmic_error或msle
- squared_hinge
- hinge
- binary_crossentropy(亦称作对数损失,logloss)
- logcosh
- categorical_crossentropy:亦称作多类的对数损失,注意使用该目标函数时,需要将标签转化为形如(nb_samples, nb_classes)的二值序列
- sparse_categorical_crossentrop:如上,但接受稀疏标签。注意,使用该函数时仍然需要你的标签与输出值的维度相同,你可能需要在标签数据上增加一个维度:np.expand_dims(y,-1)
- kullback_leibler_divergence:从预测值概率分布Q到真值概率分布P的信息增益,用以度量两个分布的差异.
- poisson:即(predictions - targets * log(predictions))的均值
- cosine_proximity:即预测值与真实标签的余弦距离平均值的相反数
优化器optimizers
优化器是编译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)
SGD
keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)
随机梯度下降法,支持动量参数,支持学习衰减率,支持Nesterov动量
RMSprop
keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-06)
除学习率可调整外,建议保持优化器的其他默认参数不变
该优化器通常是面对递归神经网络时的一个良好选择
Adagrad
keras.optimizers.Adagrad(lr=0.01, epsilon=1e-06)
建议保持优化器的默认参数不变
Adadelta
keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=1e-06)
建议保持优化器的默认参数不变
Adam
keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
该优化器的默认值来源于参考文献
Adamax
keras.optimizers.Adamax(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
Adamax优化器来自于Adam的论文的Section7,该方法是基于无穷范数的Adam方法的变体。
默认参数由论文提供
Nadam
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
默认参数来自于论文,推荐不要对默认参数进行更改。
TFOptimizer
keras.optimizers.TFOptimizer(optimizer)
TF优化器的包装器
激活函数Activations
激活函数可以通过设置单独的激活层实现,也可以在构造层对象时通过传递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)
预定义激活函数
- softmax:对输入数据的最后一维进行softmax,输入数据应形如(nb_samples, nb_timesteps, nb_dims)或(nb_samples,nb_dims)
- elu
- softplus
- softsign
- relu
- tanh
- sigmoid
- hard_sigmoid
- linear
高级激活函数
对于简单的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
- binary_accuracy: 对二分类问题,计算在所有预测值上的平均正确率
- categorical_accuracy:对多分类问题,计算再所有预测值上的平均正确率
- sparse_categorical_accuracy:与categorical_accuracy相同,在对稀疏的目标值预测时有用
- top_k_categorical_accracy: 计算top-k正确率,当预测值的前k个值中存在目标类别即认为预测正确
定制评估函数
定制的评估函数可以在模型编译时传入,该函数应该以(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
Initializer是所有初始化方法的父类,不能直接使用,如果想要定义自己的初始化方法,请继承此类。
预定义初始化方法
Zeros
keras.initializers.Zeros()
全零初始化
Ones
keras.initializers.Ones()
全1初始化
Constant
keras.initializers.Constant(value=0)
初始化为固定值value
RandomNormal
keras.initializers.RandomNormal(mean=0.0, stddev=0.05, seed=None))
正态分布初始化
RandomUniform
keras.initializers.RandomUniform(minval=-0.05, maxval=0.05, seed=None)
均匀分布初始化
minval:均匀分布下边界
maxval:均匀分布上边界
seed:随机数种子
TruncatedNormal
keras.initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None)
截尾高斯分布初始化,该初始化方法与RandomNormal类似,但位于均值两个标准差以外的数据将会被丢弃并重新生成,形成截尾分布。该分布是神经网络权重和滤波器的推荐初始化方法。
VarianceScaling
keras.initializers.VarianceScaling(scale=1.0, mode='fan_in', distribution='normal', seed=None)
该初始化方法能够自适应目标张量的shape。
Orthogonal
keras.initializers.Orthogonal(gain=1.0, seed=None)
用随机正交矩阵初始化
Identiy
keras.initializers.Identity(gain=1.0)
使用单位矩阵初始化,仅适用于2D方阵
lecun_uniform
lecun_uniform(seed=None)
LeCun均匀分布初始化方法,参数由[-limit, limit]的区间中均匀采样获得,其中limit=sqrt(3 / fan_in), fin_in是权重向量的输入单元数(扇入)
glorot_normal
glorot_normal(seed=None)
Glorot正态分布初始化方法,也称作Xavier正态分布初始化,参数由0均值,标准差为sqrt(2 / (fan_in + fan_out))的正态分布产生,其中fan_in和fan_out是权重张量的扇入扇出(即输入和输出单元数目)
he_normal
he_normal(seed=None)
He正态分布初始化方法,也称作Xavier正态分布初始化,参数由0均值,标准差为sqrt(2 / fan_in) 的正态分布产生,其中fan_in权重张量的扇入
he_uniform
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.)))
预定义约束项
- max_norm(m=2):最大模约束
- non_neg():非负性约束
- unit_norm():单位范数约束, 强制矩阵沿最后一个轴拥有单位范数
回调函数Callbacks
回调函数是一组在训练的特定阶段被调用的函数集,你可以使用回调函数来观察训练过程中网络内部的状态和统计信息。通过传递回调函数列表到模型的.fit()中,即可在给定的训练阶段调用该函数集中的函数。
keras.callbacks.Callback()
这是回调函数的抽象类,定义新的回调函数必须继承自该类
目前,模型的.fit()中有下列参数会被记录到logs中:
- 在每个epoch的结尾处(on_epoch_end),logs将包含训练的正确率和误差,acc和loss,如果指定了验证集,还会包含验证集正确率和误差val_acc)和val_loss,val_acc还额外需要在.compile中启用metrics=[‘accuracy’]。
- 在每个batch的开始处(on_batch_begin):logs包含size,即当前batch的样本数
- 在每个batch的结尾处(on_batch_end):logs包含loss,若启用accuracy则还包含acc
BaseLogger
keras.callbacks.BaseLogger()
该回调函数用来对每个epoch累加metrics指定的监视指标的epoch平均值
该回调函数在每个Keras模型中都会被自动调用
ProgbarLogger
keras.callbacks.ProgbarLogger()
该回调函数用来将metrics指定的监视指标输出到标准输出上
History
keras.callbacks.History()
该回调函数在Keras模型上会被自动调用,History对象即为fit方法的返回值
ModelCheckpoint
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的多个文件。
EarlyStopping
keras.callbacks.EarlyStopping(monitor='val_loss', patience=0, verbose=0, mode='auto')
当监测值不再改善时,该回调函数将中止训练
RemoteMonitor
keras.callbacks.RemoteMonitor(root='http://localhost:9000')
该回调函数用于向服务器发送事件流,该回调函数需要requests库
LearningRateScheduler
keras.callbacks.LearningRateScheduler(schedule)
该回调函数是学习率调度器
TensorBoard
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
ReduceLROnPlateau
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中看不到模型性能提升,则减少学习率
CSVLogger
keras.callbacks.CSVLogger(filename, separator=',', append=False)
将epoch的训练结果保存在csv文件中,支持所有可被转换为string的值,包括1D的可迭代数值如np.ndarray.
LambdaCallback
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