Keras入门-下篇

Keras

Posted by Wwt on August 19, 2017

网络配置

损失函数

目标函数,或称损失函数,是编译一个模型必须的两个参数之一,可以通过传递预定义目标函数名字指定目标函数也可以传递一个Theano/TensorFlow的符号函数作为目标函数,该函数对每个数据点应该只返回一个标量值,并以下列两个参数为参数:

  • y_true:真实的数据标签,Theano/TensorFlow张量
  • y_pred:预测值,与y_true相同shape的Theano/TensorFlow张量
from keras import losses

model.compile(loss=losses.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()时传递一个预定义优化器名、在后者情形下,优化器的参数将使用默认值。

#默认参数被使用
model.compile(loss='mean_squared_error', optimizer='sgd')

所有优化器都可用的参数

参数clipnorm和clipvalue是所有优化器都可以使用的参数,用于对于梯度进行裁剪,示例如下:

from keras import optimizers

# 所有参数梯度被裁剪
# 最大范围为1 
sgd = optimizers.SGD(lr=0.01, clipnorm=1.)
from keras import optimizers

# 所有参数梯度被裁剪
# 最大范围为0.5
#最小范围为-0.5
sgd = optimizers.SGD(lr=0.01, clipvalue=0.5)
SGD

随机梯度下降法,支持动量参数,支持学习衰减率,支持Nesterov动量

keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)

参数

  • lr:大于0的浮点数,学习率
  • momentum:大于0的浮点数,动量参数
  • decay:大于0的浮点数,每次更新后的学习率衰减值
  • nesterov:布尔值,确定是否使用Nesterov动量
RMSprop
keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-06)

除学习率可调整外,建议保持优化器的其他默认参数不变

该优化器通常是面对递归神经网络时的一个良好选择

参数

  • lr:大于0的浮点数,学习率
  • rho:大于0 的浮点数
  • epsilon:大于0的小浮点数,防止除0错误
Adagrad
keras.optimizers.Adagrad(lr=0.01, epsilon=1e-06)

建议保持优化器的默认参数不变

参数

  • lr:大于0的浮点数,学习率
  • epsilon:大于0的小浮点数,防止除0错误
Adadelta
keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=1e-06)

建议保持优化器的默认参数不变

参数

  • lr:大于0的浮点数,学习率
  • rho:大于0的浮点数
  • epsilon:大于0的小浮点数,防止除0错误
Adam
keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)

该优化器的默认值来源于参考文献

参数

  • lr:大于0的浮点数,学习率
  • beta_1/beta_2:浮点数, 0<beta<1,通常很接近1
  • epsilon:大于0的小浮点数,防止除0错误

激活函数

激活函数可以通过设置单独的激活层实现,也可以在构造层对象时通过传递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])

参数

  • y_true:真实标签,Theano/thensorflow张量
  • y_pred:预测值,与y_pred形式相同的theano/tensorflow张量

返回值

单个用以代表输出各个数据点上的均值的值

可用预定义张量

除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)))

# 使用默认参数
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))

正态分布初始化

  • mean:均值
  • stddev:标准差
  • seed:随机种子
RandomUniform
keras.initializers.RandomUniform(minval=-0.05, maxval=0.05, seed=None)

均匀分布初始化 *minval:均匀分布下边界 *maxval:均匀分布上边界 * seed:随机数种子

自定义初始化器

如果需要传递自定义的初始化器,则该初始化器必须是callable的,并且接收shape(将被初始化的张量shape)和dtype(数据类型)两个参数,并返回符合shapedtype的张量。

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))

正则项

正则项在优化过程中层的参数或层的激活值添加惩罚项,这些惩罚项将于损失函数一起作为网络的最终优化目标。

惩罚项基于层进行惩罚,目前惩罚项的接口与层有关,但Dense, Conv1D, Conv2D, Conv3D具有共同的接口。

这些层有三个关键字参数以施加正则项:

  • kernel_regularizer:施加在权重上的正则项,为keras.regularizer.Regularizer对象
  • bias_regularizer:施加在偏置向量上的正则项,为keras.regularizer.Regularizer对象
  • activity_regularizer:施加在输出上的正则项,为keras.regularizer.Regularizer对象

例子

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.)

约束项

来自constraints模块的函数在优化过程中为网络的参数约束。

惩罚项基于层进行惩罚,目前惩罚项的接口与层有关,但Dense, Conv1D, Conv2D, Conv3D具有共同的接口。

这些层通过以下关键字施加约束项

  • kernel_constraint:对主权重矩阵进行约束
  • bias_constraint:对偏置向量进行约束
from keras.constraints import maxnorm
model.add(Dense(64, kernel_constraint=max_norm(2.)))
预定义约束项
  • max_norm(m=2):最大模约束
  • non_neg():非负性约束
  • unit_norm():单位范数约束, 强制矩阵沿最后一个轴拥有单位范数

回调函数

回调函数是一组在训练的特定阶段被调用的函数集,你可以使用回调函数来观察训练过程中网络内部的状态和统计信息。通过传递回调函数列表模型的.fit()中,即可在给定的训练阶段调用该函数集中的函数。

Callback

keras.callbacks.Callback()

类属性

  • params:字典,训练参数集(如信息显示方法verbosity,batch大小,epoch数)
  • model:keras.models.Model对象,为正在训练的模型的引用

目前,模型的.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

该回调函数将在每个epoch后保存模型到filepath,filepath可以是格式化的字符串,里面的占位符将会被epoch值和传入on_epoch_end的logs关键字所填入,例如,filepath若为weights.{epoch:02d-{val_loss:.2f}}.hdf5,则会生成对应epoch和验证集loss的多个文件。

keras.callbacks.ModelCheckpoint(filepath, monitor='val_loss', verbose=0, save_best_only=False, save_weights_only=False, mode='auto', period=1)

参数

  • filename:字符串,保存模型的路径
  • monitor:需要监视的值
  • verbose:信息展示模式,0或1
  • save_best_only:当设置为True时,将只保存在验证集上性能最好的模型
  • mode:‘auto’,‘min’,‘max’之一,在save_best_only=True时决定性能最佳模型的评判准则,例如,当监测值为val_acc时,模式应为max,当检测值为val_loss时,模式应为min。在auto模式下,评价准则由被监测值的名字自动推断。
  • save_weights_only:若设置为True,则只保存模型权重,否则将保存整个模型(包括模型结构,配置信息等)
  • period:CheckPoint之间的间隔的epoch数

数据预处理

序列预处理

填充序列pad_sequences

将长为nb_samples的序列(标量序列)转化为形如(nb_samples,nb_timesteps)2D numpy array.如果提供了参数maxlen,nb_timesteps=maxlen,否则其值为最长序列的长度。其他短于该长度的序列都会在后部填充0以达到该长度。长于nb_timesteps的序列会被阶段,以使其匹配目标长度。padding和截断发生的位置分别取决于padding和truncating。

keras.preprocessing.sequence.pad_sequences(sequences, maxlen=None, dtype='int32',
    padding='pre', truncating='pre', value=0.)

参数

  • sequences:浮点数或整数构成的两层嵌套列表
  • maxlen:None或整数,为序列的最大长度。大于此长度的序列将被截短,小于此长度的序列将在后部填0
  • dtype:返回的numpy array的数据类型
  • padding:‘pre’或‘post’,确定当需要补0时,在序列的起始还是结尾补
  • truncating:‘pre’或‘post’,确定当需要截断序列时,从起始还是结尾截断
  • value:浮点数,此值将在填充时代替默认的填充值0

返回值

返回形如(nb_samples,nb_timesteps)的2D张量

文本预处理

句子分割

下述函数是将一个句子拆分成单词构成的列表

keras.preprocessing.text.text_to_word_sequence(text,
                                               filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
                                               lower=True,
                                               split=" ")

参数

  • text:字符串,待处理的文本
  • filters:需要滤除的字符的列表或连接形成的字符串,例如标点符号。默认值为 ‘!”#$%&()*+,-./:;<=>?@[]^_`{ }~\t\n’,包含标点符号,制表符和换行符等
  • lower:布尔值,是否将序列设为小写形式
  • split:字符串,单词的分隔符,如空格

返回值

字符串列表

one-hot编码

下述函数将一段文本编码为one-hot形式的码,即仅记录词在词典中的下标。

keras.preprocessing.text.one_hot(text,
                                 n,
                                 filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
                                 lower=True,
                                 split=" ")

【注意】从定义上,当字典长度为n时,每个单位应形成一个长为n的向量,其中仅有单词本身在字典下标的位置为1,其余均为0,这称为one-hot。

为了方便起见,函数在这里仅把“1”的位置,即字典中词的下标记录下来。

参数

  • n:整数,字典长度

返回值

整数列表,每个整数是[1,n]之间的值,代表一个单词(不保证唯一性,即如果词典长度不够,不同的单词可能会被编为同一个码)。

特征哈希

将文本转换为固定大小的哈希空间中的索引序列

keras.preprocessing.text.hashing_trick(text,
                                       n,
                                       hash_function=None,
                                       filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
                                       lower=True,
                                       split=' ')

参数

  • n:哈希空间的维度
  • hash_function: 默认为 python hash 函数, 可以是 ‘md5’ 或任何接受输入字符串, 并返回 int 的函数. 注意 hash 不是一个稳定的哈希函数, 因此在不同执行环境下会产生不同的结果, 作为对比, ‘md5’ 是一个稳定的哈希函数.

返回值

整数列表

分词器

Tokenizer是一个用于向量化文本,或将文本转换为序列(即单词在字典的下标构成列表,从1算起)的类。

keras.preprocessing.text.Tokenizer(num_words=None,
                                   filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
                                   lower=True,
                                   split=" ",
                                   char_level=False)

参数

  • text_to_word_sequence同名参数含义相同
  • num_words:None或整数,处理的最大单词数量。若被设置为整数,则分词器将被限制为待处理数据集中最常见的num_words个单词
  • char_level: 如果为 True, 每个字符将被视为一个标记

类方法

  • fit_on_texts(texts)
    • texts:要用以训练的文本列表
  • texts_to_sequences(texts)
    • texts:待转为序列的文本列表
    • 返回值:序列的列表,列表中每个序列对应于一段输入文本
  • texts_to_sequences_generator(texts)
    • 本函数是texts_to_sequences的生成器函数版
    • texts:待转为序列的文本列表
    • 返回值:每次调用返回对应于一段输入文本的序列
  • texts_to_matrix(texts, mode)
    • texts:待向量化的文本列表
    • mode:‘binary’,‘count’,‘tfidf’,‘freq’之一,默认为‘binary’
    • 返回值:形如(len(texts), nb_words)的numpy array
  • fit_on_sequences(sequences)
    • sequences:要用以训练的序列列表
  • sequences_to_matrix(sequences)
    • sequences:待向量化的序列列表
    • mode:‘binary’,‘count’,‘tfidf’,‘freq’之一,默认为‘binary’
    • 返回值:形如(len(sequences), nb_words)的numpy array

属性

  • word_counts:字典,将单词(字符串)映射为它们在训练期间出现的次数。仅在调用fit_on_texts之后设置
  • word_docs: 字典,将单词(字符串)映射为它们在训练期间所出现的文档或文本的数量。仅在调用fit_on_texts之后设置
  • word_index: 字典,将单词(字符串)映射为它们的排名或者索引。仅在调用fit_on_texts之后设置
  • document_count: 整数。分词器被训练的文档(文本或者序列)数量。仅在调用fit_on_texts或fit_on_sequences之后设置

参考

Keras中文文档