模型构建
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。