模型构建

Keras定义模型一般有两种方法,一种是使用Sequential类,一般用于层的线性堆叠;另一种是函数式API,一般用于层组成的有向无环图,来组建任意形式的架构。在定义好模型架构之后,接下来的处理步骤就是配置学习过程。学习过程的配置需要指定模型要使用的优化器和损失函数,并且指定学习过程中计划要监控的指标。学习过程配置好后,就可以将数据传入模型开始学习迭代了。Keras中的模型构建一般是通过定义模型类型和数据处理层来完成的。

使用Sequential类构建神经网络模型是最常用的选择,它位于keras.models包中。要使用Sequential模型,只需要使用以下语句即可完成模型的实例化。

from keras import models
from keras import layers


model = models.Sequential()
# 以下是处理层的定义
model.add(layers.Dense(32, activation="relu", input_shape=(5,))) # 这里定义了输入数据的预期形状
model.add(layers.Dense(10, activation="softmax")) # 这里定义了输出张量处理

实例化后的模型即可开始向其中加入处理层。如果使用函数式API定义模型,则是需要先定义模型要操作的层,再将层传入模型的构造函数中。以下模型的定义与上例中的定义相同。

from keras import models
from keras import layers


# 定义输入张量
input_tensor = layers.Input(shape=(5,))
# 定义第一层处理
x = layers.Dense(32, activation="relu")(input_tensor)
# 定义输出张量处理
output_tensor = layers.Dense(10, activation="softmax")(x)

# 定义模型
model = models.Model(inputs=input_tensor, outputs=output_tensor)

使用函数式API定义模型,可以突破Sequential顺序模型的限制,允许建立更多种类型的模型,例如多输入多输出模型、有向无环图、共享层、Inception模型、残差网络等。并且函数式API允许将一个预训练模型作为一个层来使用,也就是说,Keras中任何层和模型都可以当做一个函数来使用,或者说任何一个Keras层都可以写为函数形式,通过连续调用函数,不断的接受一个张量作为参数,返回另一个张量,就构成了一个复杂的神经网络。

神经网络的基本数据结构是层。层是一个数据处理模块,主要用于将一个张量转换为另一个或另几个张量。层可以理解为搭建神经网络的积木,组建深度学习模型就是将相互兼容的多个层拼接在一起,建立有用的数据变换流程。大部分层是有状态的,这个状态即是层的权重,权重是利用随机梯度下降学到的一个或者多个张量,其中包含的是神经网络学习到的知识。

不同的张量格式和不同的数据处理类型需要用到不同的层。一般层的选择如下:

  • 简单的向量数据保存在2D张量中,处理时可采用{\bfseries 密集连接层},对应Keras中的Dense类。
  • 序列数据保存在3D张量中,处理时可采用{\bfseries 循环层},对应Keras中的LSTM类。
  • 图像数据保存在4D张量中,处理时可采用{\bfseries 二维卷积层},对应Keras中的Conv2D类。

在选择拼接层的时候要注意层之间的兼容性,也就是输入张量和输出张量的形状,相邻的层要匹配。Keras中的层位于keras.layers包中,关于其他常用的层将在后文进行详细的介绍。

完成模型架构的定义后,接下来的步骤就与模型的架构没有关系了。

一套模型最好只解决一个问题,要同时解决不同的问题,可以通过构建多套模型来联合实现。不要妄想构建一个超级智能的模型来同时获取多种不同问题的答案。

Keras模型常用方法

Keras有两类模型:顺序模型(Sequential)和泛型模型(Model)。这两类模型都有一些共通的常用方法。

  • .summary(),打印输出模型概况。
  • .get_config(),返回包含模型配置的字典。
  • .get_weights(),返回模型的权重张量列表,类型为Numpy array。
  • .set_weights(),从Numpy array中载入权重给模型。
  • .to_json(),将模型的网络结构输出为JSON字符串,可以用keras.models.model_from_json()方法重构模型。
  • .to_yaml(),将模型的网络结构输出为YAML字符串,可以用keras.models.model_from_yaml()方法重构模型。
  • .save_weights(filepath),将模型权重保存到指定路径,文件格式为HDF5。
  • .load_weights(filepath, by_name=False),从HDF5文件中载入权重,不改变模型的结构,如果权重与模型的结构不同,可以设置by_name=True按照层名称匹配载入权重。
  • .add(),向模型中添加一个层。
  • .compile(optimizer, loss, metrics=[], sample_weight_mode=None),配置模型的学习过程。该函数只为训练服务,如果只是加载模型用于预测值,则不必进行编译。
    • optimizer,预定义的优化器名称或优化器对象。
    • loss,预定义的损失函数名或目标函数。
    • metrics,指定评估模型在训练和测试时的评估指标。
    • sample_weight_mode,指定按何种方式为样本赋权。
  • .fit(x, y, batch_size=32, nb_epoch=10, verbose=1, callbacks=[], validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None),将模型训练nb_epoch轮。
    • x,输入数据,一个输入的类型为Numpy array,多个输入的类型为List[Numpy array]。
    • y,标签,类型为Numpy array。
    • batch_size,进行梯度下降时每个batch包含的样本数。
    • nb_epoch,训练的轮数。
    • verbose,日志显示。
    • callbacks,在训练过程中的不同时机调用的回调函数。
    • validation_split,用来指定一定比例的数据作为验证集,取值区间为$[0,1]$。
    • validation_data,指定验证集,形式为(x, y)的元组。
    • shuffle,训练过程中随机打乱样本。
    • class_weight,将不同的类别映射成不同的权重值,只在训练中用于调整损失函数。
    • sample_weight,给样本进行加权,只在训练中用于调整损失函数。
  • .evaluate(x, y, batch_size=32, verbose=1, sample_weight=None),计算在指定输入数据上的模型误差。参数含义与.fit()方法相同。本方法返回一个测试误差的标量值或者标量列表。
  • .predict(x, batch_size=32, verbose=0),在未知输入数据上应用模型以获取预测结果。本方法的返回值为Numpy array。