keras简明教程

  本教程适用于Keras的入门与提升。本教程所用Keras版本为2.1.0,backend是Tensorflow,Keras的详细内容应该结合Keras官方文档源代码一同学习。目前Tensorflow 1.9.0及以上版本将Keras集成为tf.keras,本教程将不对此项进行扩展。

  我认为Keras是个轻量级的高级API,学习的捷径就是尽可能的阅读其源码。当然这对于初学者难度也不是很大。Keras的很多功能函数的源码复杂度并不高,功能类耦合性弱,可学习性强,可扩展性灵活。可以将其部分功能模块剥离成独立的工具,对算法原理的理解都有一定的帮助。

使用Keras 构建模型

  Keras设计了俩种构建模型的方式函数式模型API顺序式模型API官网称30s入门。

顺序式模型API构建模型示例:

1
2
3
4
5
6
7
from keras.models import Sequential#从models导入Sequential
model = Sequential()
from keras.layers import Dense
model.add(Dense(units=64, activation='relu', input_dim=100))
model.add(Dense(units=10, activation='softmax'))
model.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])
model.fit(data,labels, batch_size=32, nb_epoch=10, verbose=1)

函数式模型API构建模型示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from keras.layers import Input, Dense
from keras.models import Model
# 这部分返回一个张量
inputs = Input(shape=(784,))
# 层的实例是可调用的,它以张量为参数,并且返回一个张量
x = Dense(64, activation='relu')(inputs)
x = Dense(64, activation='relu')(x)
predictions = Dense(10, activation='softmax')(x)
# 这部分创建了一个包含输入层和三个全连接层的模型
model = Model(inputs=inputs, outputs=predictions)
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(data, labels) # 开始训练

模型编译参数设置

主要配置包括
  • loss:损失函数–MSE、KL散度、交叉熵、对数损失函数等;源码:losses.py
  • optimizer:优化函数–常用SGD、RMSprop、Adam等;源码:optimizers.py
  • metrics:模型评估方法–准确率、AUC、F-score、包括损失函数代表的指标;源码:metrics.py

Tricks:

自定义评估函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#可以参照metrics.py定义评估函数的写法编写自己的评估函数
#F-Score
def fbeta(y_true, y_pred, beta = 1, threshold_shift=0):
# 枝剪预测标签的范围
y_pred = K.clip(y_pred, 0, 1)
# 调整阈值
y_pred_bin = K.round(y_pred + threshold_shift)
tp = K.sum(K.round(y_true * y_pred_bin), axis=1) + K.epsilon()
fp = K.sum(K.round(K.clip(y_pred_bin - y_true, 0, 1)), axis=1)
fn = K.sum(K.round(K.clip(y_true - y_pred_bin, 0, 1)), axis=1)
precision = tp / (tp + fp)
recall = tp / (tp + fn)

beta_squared = beta ** 2
return K.mean((beta_squared + 1) * (precision * recall) / (beta_squared * precision + recall + K.epsilon()))
自定义损失函数
1
2
3
4
5
6
7
#参考losses.py编写自己的损失函数
#Retinanet 针对正负样本不均衡问题设计的损失函数focal_loss
#Keras 以tf为后端;可以使用Keras的math方法或者tf的math方法写都可以keras被识别
def focal_loss(y_true, y_pred,gamma=2., alpha=.25):
pt_1 = tf.where(tf.equal(y_true, 1), y_pred, tf.ones_like(y_pred))
pt_0 = tf.where(tf.equal(y_true, 0), y_pred, tf.zeros_like(y_pred))
return K.mean(-alpha * K.pow(1 - pt_1, gamma) * K.log(pt_1)-(1-alpha) * K.pow( pt_0, gamma) * K.log(1 - pt_0),axis=-1)
多任务(多头)训练编译配置
1
2
3
#定义模型的输出是:sigmoid_1,sigmoid_2
model.compile(loss={'sigmoid_1':"binary_crossentropy",'sigmoid_2':"mse" },
loss_weights={'sigmoid_1':0.5,'sigmoid_2':0.5},optimizer=opt,metrics={'Normout':f2_score,'FMlayer':f2_score})

模型训练参数设置

模型训练接口
  1. model.fit为例:
1
model.fit(x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#重点查看 注释部分高亮字
参数:
x: 训练数据的 Numpy 数组(如果模型只有一个输入), 或者是 Numpy 数组的列表(如果模型有多个输入)。 如果模型中的输入层被命名,你也可以传递一个字典,将输入层名称映射到 Numpy 数组。 如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,x 可以是 None(默认)。
y: 目标(标签)数据的 Numpy 数组(如果模型只有一个输出), 或者是 Numpy 数组的列表(如果模型有多个输出)。 如果模型中的输出层被命名,你也可以传递一个字典,将输出层名称映射到 Numpy 数组。 如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,y 可以是 None(默认)。
batch_size: 整数或 None。每次梯度更新的样本数。如果未指定,默认为 32
epochs: 整数。训练模型迭代轮次。一个轮次是在整个 x 和 y 上的一轮迭代。 请注意,与 initial_epoch 一起,epochs 被理解为 「最终轮次」。模型并不是训练了 epochs 轮,而是到第 epochs 轮停止训练。
verbose: 0, 12。日志显示模式。 0 = 安静模式, 1 = 进度条, 2 = 每轮一行。
#callbacks: 一系列的 keras.callbacks.Callback 实例。一系列可以在训练时使用的回调函数。 详见 callbacks。
validation_split: 在 01 之间浮动。用作验证集的训练数据的比例。 模型将分出一部分不会被训练的验证数据,并将在每一轮结束时评估这些验证数据的误差和任何其他模型指标。 验证数据是混洗之前 x 和y 数据的最后一部分样本中。
validation_data: 元组 (x_val,y_val) 或元组 (x_val,y_val,val_sample_weights), 用来评估损失,以及在每轮结束时的任何模型度量指标。 模型将不会在这个数据上进行训练。这个参数会覆盖 validation_split。
shuffle: 布尔值(是否在每轮迭代之前混洗数据)或者 字符串 (batch)。 batch 是处理 HDF5 数据限制的特殊选项,它对一个 batch 内部的数据进行混洗。 #当 steps_per_epoch 非 None 时,这个参数无效。
#class_weight: 可选的字典,用来映射类索引(整数)到权重(浮点)值,用于加权损失函数(仅在训练期间)。 这可能有助于告诉模型 「更多关注」来自代表性不足的类的样本。
#sample_weight: 训练样本的可选 Numpy 权重数组,用于对损失函数进行加权(仅在训练期间)。 您可以传递与输入样本长度相同的平坦(1D)Numpy 数组(权重和样本之间的 1:1 映射), 或者在时序数据的情况下,可以传递尺寸为 (samples, sequence_length) 的 2D 数组,以对每个样本的每个时间步施加不同的权重。 在这种情况下,你应该确保在 compile() 中指定 sample_weight_mode="temporal"。
#initial_epoch: 整数。开始训练的轮次(有助于恢复之前的训练)。
steps_per_epoch: 整数或 None。 在声明一个轮次完成并开始下一个轮次之前的总步数(样品批次)。 使用 TensorFlow 数据张量等输入张量进行训练时,默认值 None 等于数据集中样本的数量除以 batch 的大小,如果无法确定,则为 1
validation_steps: 只有在指定了 steps_per_epoch时才有用。停止前要验证的总步数(批次样本)。
返回
一个 History 对象。其 History.history 属性是连续 epoch 训练损失和评估值,以及验证集损失和评估值的记录(如果适用)。
#训练函数的返回是一个字典;训练的损失和评估值都在这个字典里面;训练参数可视化可用pyplot
  1. model.train_on_batch

    1
    2
    train_on_batch(x, y, sample_weight=None, class_weight=None)
    #以batch的形式训练数据,相当于tf的feed_dict,一次训练一个step
  2. model.fit_generator

    1
    2
    model.fit_generator(self, generator, steps_per_epoch=None, epochs=1, verbose=1, callbacks=None, validation_data=None, validation_steps=None, class_weight=None, max_queue_size=10, workers=1, use_multiprocessing=False, shuffle=True, initial_epoch=0)
    #以生成器的形式喂数据,节省内存,以及兼容实时数据扩增

模型预测

model.predict

1
predict(x, batch_size=None, verbose=0, steps=None)

保存和加载模型

保存和加载整个模型

1
2
3
4
5
from keras.models import load_model
model.save("x_model.hdf5") #创建一个文件my_model.hdf5
del model #删除模型
#返回一个已经编译过的模型,和之前的模型一模一样
model = load_model("x_model.hdf5")

只保存/加载权重

1
2
3
4
#使用hdf5来只加载权重(需要先安装HDF5和h5py)
model.save_weights("x_model_weights.h5")
#定义好模型之后,加载权重
model.load_weights("x_model_weights.h5")

Keras模型中间阶段

获取中间层输出

1
2
3
4
5
from keras.models import Model
model = Model(inputs=inp,outputs=y_hat)
layer_name = "Conv2D_1"
Middle_layer_out_model = Model(inputs=model.input, outputs=model.get_layer(layer_name).output)
Middle_layer_out = Middle_layer_out_model.predict(x)

固定层参数

1
2
3
4
5
6
7
8
9
10
11
#固定层的参数是否可训练在微调和迁移学习中是很关键的一步
#可以定义层以后再固定
a = Conv1D(1,2)
a.trainable = False
#也可以在定义层的时候固定参数
layer = Conv1D(1,2,trainable = False)
#fine tune参数设置
for layer in base_model.layers[:25]:
layer.trainable = False
sgd = Adam(lr=1e-3, decay=lr/10)
model.compile(optimizer=sgd, loss='binary_crossentropy', metrics=['acc'])

总结

  本章主要讲述了Keras是如何构建模型,如何设置优化算法,评估函数,训练参数的基本使用方法;在此基础上扩展了多任务学习,获取中间层参数,fine tune方法等。本教程结合keras 案例 运行其部分代码对学习Keras帮助巨大。

Reference

本文所有参考均来自Keras官方手册