Keras学习笔记2——keras.models
在 Keras 中有两类主要的模型:Sequential 顺序模型 和 使用函数式 API 的 Model 类模型。参考:Keras中文文档
keras.models.Sequential()
顺序模型 Sequential 采用多个网络层堆叠
第一步,模型初始化
from keras.models import Sequential
from keras.layers import Dense
方式一:使用 .add() 逐层堆叠模型
# step1 :模型初始化
model = Sequential()
# 使用 .add() 来堆叠模型,一层一层加入,构建所需的神经网络
# 模型需要知道它所期望的输入的尺寸,顺序模型中的第一层需要接收关于其输入尺寸的信息。
model.add(Dense(units=32, activation='relu', input_dim=784))
# 下面的层不需要输入尺寸的信息,可以自动地推断尺寸。
model.add(Dense(units=10, activation='softmax'))
方式二:使用 layer 的 list 直接创建模型
model = Sequential([
Dense(32, input_shape=(784,)),
Activation('relu'),
Dense(10),
Activation('softmax'),
])
- 传递一个 input_shape 参数给第一层,顺序模型中的第一层需要接收关于其输入尺寸的信息。它是一个表示尺寸的元组 (一个由整数或 None 组成的元组,其中 None 表示可能为任何正整数)。
- 在 input_shape 中不包含数据的 batch 大小。如果你需要为你的输入指定一个固定的 batch 大小,你可以传递一个 batch_size 参数给一个层。如果你同时将 batch_size=32 和 input_shape=(6, 8) 传递给一个层,那么每一批输入的尺寸就为 (32,6,8)。
- 某些 2D 层,例如 Dense,支持通过参数 input_dim 指定输入尺寸,
input_dim=784
等价于input_shape=(784,)
第二步,模型编译
# step2:使用 .compile() 来配置学习过程
model.compile(loss='categorical_crossentropy',
optimizer='sgd',
metrics=['accuracy'])
# 或者,也可以进一步可以配置优化器
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.SGD(lr=0.01, momentum=0.9, nesterov=True))
compile
用于配置训练模型
参数说明:
compile(optimizer, loss=None, metrics=None, loss_weights=None,
sample_weight_mode=None, weighted_metrics=None, target_tensors=None)
- 优化器 optimizer:可以是字符串(现有优化器名,如’sgd’、‘Adam’),或者是优化器对象(Optimizer 类的实例)。
- 损失函数 loss:字符串(目标函数名)或目标函数,模型试图最小化的目标函数, 如mse、mae等。 如果模型具有多个输出,则可以通过传递损失函数的字典或列表,在每个输出上使用不同的损失。模型将最小化的损失值将是所有单个损失的总和。
- 评估标准 metrics,可以是现有的标准的字符串标识符,如 metrics = [‘accuracy’],也可以是自定义的评估标准函数。在训练和测试期间的模型评估标准。多输出模型的不同输出指定不同的评估标准,还可以传递一个字典,如 metrics = {‘output_a’:‘accuracy’}。
- loss_weights: 指定标量系数(Python浮点数)的可选列表或字典,用于加权不同模型输出的损失贡献。 模型将要最小化的损失值将是所有单个损失的加权和,由 loss_weights 系数加权。 如果是列表,则期望与模型的输出具有 1:1 映射。 如果是张量,则期望将输出名称(字符串)映射到标量系数。
- sample_weight_mode: 如果你需要执行按时间步采样权重(2D 权重),请将其设置为 temporal。 默认为 None,为采样权重(1D)。如果模型有多个输出,则可以通过传递 mode 的字典或列表,以在每个输出上使用不同的 sample_weight_mode。
- weighted_metrics: 在训练和测试期间,由 sample_weight 或 class_weight 评估和加权的度量标准列表。
- target_tensors: 默认情况下,Keras 将为模型的目标创建一个占位符,在训练过程中将使用目标数据。相反,如果你想使用自己的目标张量(反过来说,Keras 在训练期间不会载入这些目标张量的外部 Numpy 数据),您可以通过 target_tensors 参数指定它们。它应该是单个张量(对于单输出 Sequential 模型)。
- **kwargs: 当使用 Theano/CNTK 后端时,这些参数被传入 K.function。当使用 TensorFlow 后端时,这些参数被传递到 tf.Session.run。
举例:
# 多分类问题
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 二分类问题
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
# 均方误差回归问题
model.compile(optimizer='rmsprop',
loss='mse')
# 自定义评估标准函数
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])
第三步,模型训练
# step3:批量地在训练数据上进行迭代
# x_train 和 y_train 是 Numpy 数组 -- 就像在 Scikit-Learn API 中一样??
model.fit(x_train, y_train, epochs=5, batch_size=32)
# 或者,可以手动地将批次的数据提供给模型
model.train_on_batch(x_batch, y_batch)
fit
以固定数量的轮次(数据集上的迭代)训练模型。
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)
参数说明:
- x: 训练数据的 Numpy 数组。 如果模型中的输入层被命名,你也可以传递一个字典,将输入层名称映射到 Numpy 数组。 如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,x 可以是 None(默认)。
- y: 目标(标签)数据的 Numpy 数组。 如果模型中的输出层被命名,你也可以传递一个字典,将输出层名称映射到 Numpy 数组。 如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,y 可以是 None(默认)。
- batch_size: 整数或 None。每次提度更新用到的样本数。如果未指定,默认为 32.
- epochs: 整数。训练模型迭代轮次。一个轮次是在整个 x 或 y 上的一轮迭代。请注意,与 initial_epoch 一起,epochs 被理解为 「最终轮次」。模型并不是训练了 epochs 轮,而是到第 epochs 轮停止训练。
- verbose: 0, 1 或 2。日志显示模式。 0 = 安静模式, 1 = 进度条, 2 = 每轮一行。
- callbacks: 一系列的 keras.callbacks.Callback 实例。一系列可以在训练时使用的回调函数。
- validation_split: 在 0 和 1 之间浮动。用作验证集的训练数据的比例。模型将分出一部分不会被训练的验证数据,并将在每一轮结束时评估这些验证数据的误差和任何其他模型指标。验证数据是混洗之前 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: 在声明一个轮次完成并开始下一个轮次之前的总步数(样品批次)。使用 TensorFlow 数据张量等输入张量进行训练时,默认值 None 等于数据集中样本的数量除以 batch 的大小,如果无法确定,则为 1。
- validation_steps: 只有在指定了 steps_per_epoch时才有用。停止前要验证的总步数(批次样本)。
返回:
- 一个 History 对象。其 History.history 属性是连续 epoch 训练损失和评估值,以及验证集损失和评估值的记录(如果适用)。
第四步,模型评估
# step4:评估模型性能
loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128)
# 或者,对新的数据生成预测
classes = model.predict(x_test, batch_size=128)
evaluate
在测试模式,逐批次计算batch数据上的误差值和评估标准值。
evaluate(x=None, y=None, batch_size=None, verbose=1, sample_weight=None, steps=None)
参数:
- x: 输入数据。
- y: 目标(标签)数据。
- batch_size: 整数或 None。每次提度更新的样本数。如果未指定,默认为 32.
- verbose: 0, 1。日志显示模式。0 = 安静模式, 1 = 进度条。
- sample_weight: 权重数组,用于对损失函数进行加权(仅在训练期间)。
- steps: 整数或 None。声明评估结束之前的总步数(批次样本)。默认值None。
返回:
标量测试误差(如果模型只有单个输出且没有评估指标)或标量列表(如果模型具有多个输出和/或指标)。 属性 model.metrics_names 将提供标量输出的显示标签。
predict
按batch计算输入数据对应的输出预测。
predict(x, batch_size=None, verbose=0, steps=None)
参数:
- x: 输入数据,Numpy 数组(或者如果模型有多个输入,则为 Numpy 数组列表)。
- batch_size: 整数。如未指定,默认为 32。
- verbose: 日志显示模式,0 或 1。
- steps: 声明预测结束之前的总步数(批次样本)。默认值 None。
返回:
预测的 Numpy 数组。
其他函数
train_on_batch
一批样品的单次梯度更新。
train_on_batch(x, y, sample_weight=None, class_weight=None)
参数:
- x: 训练数据的 Numpy 数组,如果模型具有多个输入,则为 Numpy 数组列表。如果模型中的所有输入都已命名,你还可以传入输入名称到 Numpy 数组的映射字典。
- y: 目标数据的 Numpy 数组,如果模型具有多个输入,则为 Numpy 数组列表。如果模型中的所有输出都已命名,你还可以传入输出名称到 Numpy 数组的映射字典。
- sample_weight: 训练样本的可选 Numpy 权重数组,用于对损失函数进行加权(仅在训练期间)。 您可以传递与输入样本长度相同的平坦(1D)Numpy 数组(权重和样本之间的 1:1 映射),或者在时序数据的情况下,可以传递尺寸为 (samples, sequence_length) 的 2D 数组,以对每个样本的每个时间步施加不同的权重。在这种情况下,你应该确保在 compile() 中指定 sample_weight_mode=“temporal”。
- class_weight: 可选的字典,用来映射类索引(整数)到权重(浮点)值,用于加权损失函数(仅在训练期间)。这可能有助于告诉模型 「更多关注」来自代表性不足的类的样本。
返回:
标量训练误差(如果模型只有单个输出且没有评估指标)或标量列表(如果模型具有多个输出和/或指标)。 属性 model.metrics_names 将提供标量输出的显示标签。
test_on_batch
在一批样本上评估模型。
test_on_batch(x, y, sample_weight=None)
参数:
- x: 训练数据的 Numpy 数组,如果模型具有多个输入,则为 Numpy 数组列表。如果模型中的所有输入都已命名,你还可以传入输入名称到 Numpy 数组的映射字典。
- y: 目标数据的 Numpy 数组,如果模型具有多个输入,则为 Numpy 数组列表。如果模型中的所有输出都已命名,你还可以传入输出名称到 Numpy 数组的映射字典。
- sample_weight: 训练样本的可选 Numpy 权重数组,用于对损失函数进行加权(仅在训练期间)。 您可以传递与输入样本长度相同的平坦(1D)Numpy 数组(权重和样本之间的 1:1 映射),或者在时序数据的情况下,可以传递尺寸为 (samples, sequence_length) 的 2D 数组,以对每个样本的每个时间步施加不同的权重。在这种情况下,你应该确保在 compile() 中指定 sample_weight_mode=“temporal”。
返回:
标量测试误差(如果模型只有单个输出且没有评估指标)或标量列表(如果模型具有多个输出和/或指标)。 属性 model.metrics_names 将提供标量输出的显示标签。
predict_on_batch
返回一批样本的模型预测值。
predict_on_batch(x)
参数:
x: 输入数据,Numpy 数组或列表(如果模型有多输入)。
返回:
预测值的 Numpy 数组。
fit_generator
fit_generator(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)
使用 Python 生成器或 Sequence 实例逐批生成的数据,按批次训练模型。
生成器与模型并行运行,以提高效率。 例如,这可以让你在 CPU 上对图像进行实时数据增强,以在 GPU 上训练模型。
keras.utils.Sequence 的使用可以保证数据的顺序, 以及当 use_multiprocessing=True 时 ,保证每个输入在每个 epoch 只使用一次。
参数:
- generator: 一个生成器或 Sequence (keras.utils.Sequence) 对象的实例,以避免在使用多进程时出现重复数据。 生成器的输出应该为以下之一:
一个 (inputs, targets) 元组
一个 (inputs, targets, sample_weights) 元组。 这个元组(生成器的单个输出)表示一个独立批次。因此,此元组中的所有数组必须具有相同的长度(等于此批次的大小)。不同的批次可能具有不同的大小。例如,如果数据集的大小不能被批量大小整除,则最后一批时期通常小于其他批次。生成器将无限地在数据集上循环。当运行到第 steps_per_epoch 时,记一个 epoch 结束。 - steps_per_epoch: 整数。在声明一个 epoch 完成并开始下一个 epoch 之前从 generator 产生的总步数(批次样本)。它通常应该等于你的数据集的样本数量除以批量大小。可选参数 Sequence:如果未指定,将使用 len(generator) 作为步数。
- epochs: 整数,数据的迭代总轮数。一个 epoch 是对所提供的整个数据的一轮迭代,由 steps_per_epoch 所定义。请注意,与 initial_epoch 一起,参数 epochs 应被理解为 「最终轮数」。模型并不是训练了 epochs 轮,而是到第 epochs 轮停止训练。
- verbose: 日志显示模式。0,1 或 2。0 = 安静模式,1 = 进度条,2 = 每轮一行。
- callbacks: keras.callbacks.Callback 实例列表。在训练时调用的一系列回调。详见 callbacks。
- validation_data: 它可以是以下之一:
验证数据的生成器或 Sequence 实例
一个 (inputs, targets) 元组
一个 (inputs, targets, sample_weights) 元组。 - validation_steps: 仅当 validation_data 是一个生成器时才可用。 每个 epoch 结束时验证集生成器产生的步数。它通常应该等于你的数据集的样本数量除以批量大小。可选参数 Sequence:如果未指定,将使用 len(generator) 作为步数。
- class_weight: 可选的字典,用来映射类索引(整数)到权重(浮点)值,用于加权损失函数(仅在训练期间)。这可能有助于告诉模型 「更多关注」来自代表性不足的类的样本。
- max_queue_size: 整数。生成器队列的最大尺寸。如果未指定,max_queue_size 将默认为 10。
- workers: 整数。使用基于进程的多线程时启动的最大进程数。如果未指定,worker 将默认为 1。如果为 0,将在主线程上执行生成器。
use_multiprocessing: 如果 True,则使用基于进程的多线程。如果未指定,use_multiprocessing 将默认为 False。请注意,因为此实现依赖于多进程,所以不应将不可传递的参数传递给生成器,因为它们不能被轻易地传递给子进程。 - shuffle: 布尔值。是否在每轮迭代之前打乱 batch 的顺序。只能与 Sequence (keras.utils.Sequence) 实例同用。在 steps_per_epoch 不为 None 是无效果。
- initial_epoch: 整数。开始训练的轮次(有助于恢复之前的训练)。
返回:
一个 History 对象。其 History.history 属性是连续 epoch 训练损失和评估值,以及验证集损失和评估值的记录(如果适用)。
例子:
def generate_arrays_from_file(path):
while True:
with open(path) as f:
for line in f:
# 从文件中的每一行生成输入数据和标签的 numpy 数组
x1, x2, y = process_line(line)
yield ({'input_1': x1, 'input_2': x2}, {'output': y})
model.fit_generator(generate_arrays_from_file('/my_file.txt'),
steps_per_epoch=10000, epochs=10)
evaluate_generator
evaluate_generator(generator, steps=None, max_queue_size=10, workers=1, use_multiprocessing=False, verbose=0)
在数据生成器上评估模型。
这个生成器应该返回与 test_on_batch 所接收的同样的数据。
参数:
- generator: 生成器,生成 (inputs, targets) 或 (inputs, targets, sample_weights),或 Sequence (keras.utils.Sequence) 对象的实例,以避免在使用多进程时出现重复数据。
- steps: 在停止之前,来自 generator 的总步数 (样本批次)。 可选参数 Sequence:如果未指定,将使用len(generator) 作为步数。
- max_queue_size: 生成器队列的最大尺寸。
- workers: 整数。使用基于进程的多线程时启动的最大进程数。如果未指定,worker 将默认为 1。如果为 0,将在主线程上执行生成器。
- use_multiprocessing: 如果 True,则使用基于进程的多线程。 请注意,因为此实现依赖于多进程,所以不应将不可传递的参数传递给生成器,因为它们不能被轻易地传递给子进程。
- verbose:日志显示模式,0 或 1。
返回:
标量测试误差(如果模型只有单个输出且没有评估指标)或标量列表(如果模型具有多个输出和/或指标)。 属性 model.metrics_names 将提供标量输出的显示标签。
predict_generator
predict_generator(generator, steps=None, max_queue_size=10, workers=1, use_multiprocessing=False, verbose=0)
为来自数据生成器的输入样本生成预测。
这个生成器应该返回与 predict_on_batch 所接收的同样的数据。
参数:
- generator: 返回批量输入样本的生成器,或 Sequence (keras.utils.Sequence) 对象的实例,以避免在使用多进程时出现重复数据。
- steps: 在停止之前,来自 generator 的总步数 (样本批次)。 可选参数 Sequence:如果未指定,将使用len(generator) 作为步数。
- max_queue_size: 生成器队列的最大尺寸。
- workers: 整数。使用基于进程的多线程时启动的最大进程数。如果未指定,worker 将默认为 1。如果为 0,将在主线程上执行生成器。
- use_multiprocessing: 如果 True,则使用基于进程的多线程。 请注意,因为此实现依赖于多进程,所以不应将不可传递的参数传递给生成器,因为它们不能被轻易地传递给子进程。
- verbose: 日志显示模式, 0 或 1。
返回:
预测值的 Numpy 数组。
get_layer
get_layer(name=None, index=None)
根据名称(唯一)或索引值查找网络层。
如果同时提供了 name 和 index,则 index 将优先。
根据网络层的名称(唯一)或其索引返回该层。索引是基于水平图遍历的顺序(自下而上)。
参数:
- name: 字符串,层的名字。
- index: 整数,层的索引。
返回:
一个层实例。
实例分析
例子1:二分类问题
# 对于具有 2 个类的单输入模型(二进制分类):
model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
# 生成虚拟数据
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(2, size=(1000, 1))
# 训练模型,以 32 个样本为一个 batch 进行迭代
model.fit(data, labels, epochs=10, batch_size=32)
例子2:多分类问题
# 对于具有 10 个类的单输入模型(多分类分类):
model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 生成虚拟数据
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(10, size=(1000, 1))
# 将标签转换为分类的 one-hot 编码
one_hot_labels = keras.utils.to_categorical(labels, num_classes=10)
# 训练模型,以 32 个样本为一个 batch 进行迭代
model.fit(data, one_hot_labels, epochs=10, batch_size=32)
例子3:基于多层感知器 (MLP) 的 softmax 多分类
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.optimizers import SGD
# 生成虚拟数据
import numpy as np
x_train = np.random.random((1000, 20))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(1000, 1)), num_classes=10)
x_test = np.random.random((100, 20))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)
model = Sequential()
# Dense(64) 是一个具有 64 个隐藏神经元的全连接层。
# 在第一层必须指定所期望的输入数据尺寸:
# 在这里,是一个 20 维的向量。
model.add(Dense(64, activation='relu', input_dim=20))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy',
optimizer=sgd,
metrics=['accuracy'])
model.fit(x_train, y_train,
epochs=20,
batch_size=128)
score = model.evaluate(x_test, y_test, batch_size=128)
例子4:基于多层感知器的二分类
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout
# 生成虚拟数据
x_train = np.random.random((1000, 20))
y_train = np.random.randint(2, size=(1000, 1))
x_test = np.random.random((100, 20))
y_test = np.random.randint(2, size=(100, 1))
model = Sequential()
model.add(Dense(64, input_dim=20, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.fit(x_train, y_train,
epochs=20,
batch_size=128)
score = model.evaluate(x_test, y_test, batch_size=128)
例子5:类似 VGG 的卷积神经网络
import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import SGD
# 生成虚拟数据
x_train = np.random.random((100, 100, 100, 3))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)
x_test = np.random.random((20, 100, 100, 3))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(20, 1)), num_classes=10)
model = Sequential()
# 输入: 3 通道 100x100 像素图像 -> (100, 100, 3) 张量。
# 使用 32 个大小为 3x3 的卷积滤波器。
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(100, 100, 3)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)
model.fit(x_train, y_train, batch_size=32, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=32)
例子6:基于 LSTM 的序列分类
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers import Embedding
from keras.layers import LSTM
max_features = 1024
model = Sequential()
model.add(Embedding(max_features, output_dim=256))
model.add(LSTM(128))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=16, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=16)
例子7:基于 1D 卷积的序列分类
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers import Embedding
from keras.layers import Conv1D, GlobalAveragePooling1D, MaxPooling1D
seq_length = 64
model = Sequential()
model.add(Conv1D(64, 3, activation='relu', input_shape=(seq_length, 100)))
model.add(Conv1D(64, 3, activation='relu'))
model.add(MaxPooling1D(3))
model.add(Conv1D(128, 3, activation='relu'))
model.add(Conv1D(128, 3, activation='relu'))
model.add(GlobalAveragePooling1D())
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=16, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=16)
例子8:基于栈式 LSTM 的序列分类
from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np
data_dim = 16
timesteps = 8
num_classes = 10
# 期望输入数据尺寸: (batch_size, timesteps, data_dim)
model = Sequential()
model.add(LSTM(32, return_sequences=True,
input_shape=(timesteps, data_dim))) # 返回维度为 32 的向量序列
model.add(LSTM(32, return_sequences=True)) # 返回维度为 32 的向量序列
model.add(LSTM(32)) # 返回维度为 32 的单个向量
model.add(Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
# 生成虚拟训练数据
x_train = np.random.random((1000, timesteps, data_dim))
y_train = np.random.random((1000, num_classes))
# 生成虚拟验证数据
x_val = np.random.random((100, timesteps, data_dim))
y_val = np.random.random((100, num_classes))
model.fit(x_train, y_train,
batch_size=64, epochs=5,
validation_data=(x_val, y_val))
例子9:“stateful” 渲染的的栈式 LSTM 模型,有状态的循环神经网络
from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np
data_dim = 16
timesteps = 8
num_classes = 10
batch_size = 32
# 期望输入数据尺寸: (batch_size, timesteps, data_dim)
# 请注意,我们必须提供完整的 batch_input_shape,因为网络是有状态的。
# 第 k 批数据的第 i 个样本是第 k-1 批数据的第 i 个样本的后续。
model = Sequential()
model.add(LSTM(32, return_sequences=True, stateful=True,
batch_input_shape=(batch_size, timesteps, data_dim)))
model.add(LSTM(32, return_sequences=True, stateful=True))
model.add(LSTM(32, stateful=True))
model.add(Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
# 生成虚拟训练数据
x_train = np.random.random((batch_size * 10, timesteps, data_dim))
y_train = np.random.random((batch_size * 10, num_classes))
# 生成虚拟验证数据
x_val = np.random.random((batch_size * 3, timesteps, data_dim))
y_val = np.random.random((batch_size * 3, num_classes))
model.fit(x_train, y_train,
batch_size=batch_size, epochs=5, shuffle=False,
validation_data=(x_val, y_val))
keras.models.Model()
参考:
Keras函数式API
Keras 函数式 API 是定义复杂模型(如多输出模型、有向无环图,或具有共享层的模型)的方法。函数式模型是最广泛的一类模型,序贯模型(Sequential)只是它的一种特殊情况。
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'])
# 生成虚拟数据
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(2, size=(1000, 1))
# 开始训练
model.fit(data, labels)
结构上与TensorFlow的使用类似。
在多输入或多输出模型的情况下,你也可以使用列表:
model = Model(inputs=[a1, a2], outputs=[b1, b3, b3])
利用函数式 API,可以轻易地重用训练好的模型(包括模型结构和权重),可以将任何模型看作是一个层,然后通过传递一个张量来调用它。例如,重用上面训练好的的model:
x = Input(shape=(784,))
# 这是可行的,并且返回上面定义的 10-way softmax。
y = model(x)
这种方式能允许我们快速创建可以处理序列输入的模型。只需一行代码,你就将图像分类模型转换为视频分类模型。
from keras.layers import TimeDistributed
# 输入张量是 20 个时间步的序列,
# 每一个时间为一个 784 维的向量
input_sequences = Input(shape=(20, 784))
# 这部分将我们之前定义的模型应用于输入序列中的每个时间步。
# 之前定义的模型的输出是一个 10-way softmax,
# 因而下面的层的输出将是维度为 10 的 20 个向量的序列。
processed_sequences = TimeDistributed(model)(input_sequences)
使用Model构建模型的步骤:
第一步 定义输入层
- 必须定义一个输入层,来指示输入数据的形状。
- input layer 接受一个指示输入数据维度的元组作为输入。
- 当输入数据是一维时,例如多层感知器,必须显示的预留最后一维的空间,以便在训练网络时分割数据时使用的mini_batch大小的形状。因此,当输入是一维(2,)时,shape tuple总是用用逗号指示预留一个维度,例如:
from keras.layers import Input
x = Input(shape=(2,))
第二步 模型初始化
keras 提供一个Model类可以建立自己的模型了,而这个模型只用你指定什么是输入层和输出层就行了,中间的层模型会自动连接好。
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
x = Input(shape=(2,))
hidden = Dense(2)(x)
model = Model(inputs=x, outputs=hidden)
第三步 模型编译
model.compile(optimizer=keras.optimizers.rmsprop(lr=0.0001),
loss='mean_squared_error',
metrics=['mae', 'acc', 'mse'])
第四步 模型训练
# 开始训练
model.fit(data, labels,
batch_size=1000,
epochs=100,
callbacks=[EarlyStopping(monitor='val_loss', patience=10)],
validation_split=0.5,
shuffle=False
)
第五步 模型评估
y = model.predict(x_test)
scores = model.evaluate(x_test, y_test, verbose=1)
模型的方法和属性
model.summary()
打印出模型概述信息。 它是 utils.print_summary 的简捷调用。
model = Model(inputs=inputs, outputs=outputs)
model.summary()
keras.utils.plot_model
keras.utils.plot_model(model, to_file='multilayer_perceptron_graph.png')
可以将网络架构输出到一张图片上。
模型信息展示
- model.layers 是包含模型网络层的展平列表。
- model.inputs 是模型输入张量的列表。
- model.outputs 是模型输出张量的列表。
- model.get_config() 返回包含模型配置信息的字典。通过以下代码,就可以根据这些配置信息重新实例化模型:
config = model.get_config()
model = Model.from_config(config)
# 或者,对于 Sequential:
model = Sequential.from_config(config)
- model.to_json() 以 JSON 字符串的形式返回模型的表示。请注意,该表示不包括权重,仅包含结构。你可以通过以下方式从 JSON 字符串重新实例化同一模型(使用重新初始化的权重):
from keras.models import model_from_json
json_string = model.to_json()
model = model_from_json(json_string)
- model.to_yaml() 以 YAML 字符串的形式返回模型的表示。请注意,该表示不包括权重,只包含结构。你可以通过以下代码,从 YAML 字符串中重新实例化相同的模型(使用重新初始化的权重):
from keras.models import model_from_yaml
yaml_string = model.to_yaml()
model = model_from_yaml(yaml_string)
权重相关
- model.get_weights():返回模型中所有权重张量的列表,类型为 Numpy 数组。
- model.set_weights(weights) : 从 Numpy 数组中为模型设置权重。列表中的数组必须与 get_weights()返回的权重具有相同的尺寸。
- model.save_weights(filepath): 将模型权重存储为 HDF5 文件。
- model.load_weights(filepath, by_name=False): 从 HDF5 文件(由 save_weights 创建)中加载权重。默认情况下,模型的结构应该是不变的。 如果想将权重载入不同的模型(部分层相同), 设置 by_name=True 来载入那些名字相同的层的权重。
Model 类继承
这里是一个用 Model 类继承写的简单的多层感知器的例子:
import keras
class SimpleMLP(keras.Model):
def __init__(self, use_bn=False, use_dp=False, num_classes=10):
super(SimpleMLP, self).__init__(name='mlp')
self.use_bn = use_bn
self.use_dp = use_dp
self.num_classes = num_classes
self.dense1 = keras.layers.Dense(32, activation='relu')
self.dense2 = keras.layers.Dense(num_classes, activation='softmax')
if self.use_dp:
self.dp = keras.layers.Dropout(0.5)
if self.use_bn:
self.bn = keras.layers.BatchNormalization(axis=-1)
def call(self, inputs):
x = self.dense1(inputs)
if self.use_dp:
x = self.dp(x)
if self.use_bn:
x = self.bn(x)
return self.dense2(x)
model = SimpleMLP()
model.compile(...)
model.fit(...)