keras基础入门教程

后来你就会发现原来那些最需要,有一个去依靠的时候,往往到最后都是自己一个人挺过去的

Posted by yishuifengxiao on 2021-06-02

一 keras基础入门

Keras 是与 TensorFlow 一起使用的更高级别的作为后端的 API。添加层就像添加一行代码一样简单。在模型架构之后,使用一行代码,你可以编译和拟合模型。之后,它可以用于预测。变量声明、占位符甚至会话都由 API 管理。

分类问题与回归问题

  • 分类问题预测的是类别,模型的输出是概率分布

      - 三分类问题输出例子 :[0.7,0.2,0.1]
    
  • 回归问题预测的是一个值,模型的输出是一个实数值

为什么需要目标函数

  • ​ 参数是逐步调整的
  • ​ 目标函数可以帮助衡量模型的好坏

分类问题

​ 需要衡量目标类别与当前预测的差距

​ 三分类问题输出例子 :[0.7,0.2,0.1]

​ 三分类真实类别 2 —> one_hot —>[0,0,1]

one_hot 编码把握正整数变为向量表达式,生成一个长度不小于正整数的向量,只有正整数的位置处为1,其他地方为0

image-20210601135901685

image-20210601135939548


回归问题

  • 预测值与真实值的差距
  • 平方差损失
  • 绝对值损失

重要参考网站 池化层 Pooling Layers - Keras 中文文档 (keras-zh.readthedocs.io)

1.1 快速入门

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 安装 TensorFlow
import tensorflow as tf

print(" \n 使用的 tensorflow 的版本为 ", tf.__version__, " \n")

# 载入并准备好 MNIST 数据集。将样本从整数转换为浮点数:
mnist = tf.keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

# 将模型的各层堆叠起来,以搭建 tf.keras.Sequential 模型。为训练选择优化器和损失函数:


model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])

# 训练并验证模型:
model.fit(x_train, y_train, epochs=5)

model.evaluate(x_test, y_test, verbose=2)

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
 使用的 tensorflow 的版本为  2.5.0  

Epoch 1/5
1875/1875 [==============================] - 2s 687us/step - loss: 0.2946 - accuracy: 0.9138
Epoch 2/5
1875/1875 [==============================] - 1s 717us/step - loss: 0.1429 - accuracy: 0.9576
Epoch 3/5
1875/1875 [==============================] - 1s 656us/step - loss: 0.1071 - accuracy: 0.9672
Epoch 4/5
1875/1875 [==============================] - 1s 701us/step - loss: 0.0872 - accuracy: 0.9732
Epoch 5/5
1875/1875 [==============================] - 1s 688us/step - loss: 0.0748 - accuracy: 0.9768
313/313 - 0s - loss: 0.0771 - accuracy: 0.9769

1.2 关键API说明

其中关键API的说明如下

1.2.1 tf.keras.models.Sequential

Sequential()方法是一个容器,描述了神经网络的网络结构,在Sequential()的输入参数中描述从输入层到输出层的网络结构

用法为

1
model = tf.keras.models.Sequential([网络结构])  #描述各层网络

网络结构举例:

  • 拉直层:

      tf.keras.layers.Flatten() #拉直层可以变换张量的尺寸,把输入特征拉直为一维数组,是不含计算参数的层
    
  • 全连接层:

      tf.keras.layers.Dense(神经元个数,activation = "激活函数“,kernel_regularizer = "正则化方式)
    
      其中:
      activation 可选  relu 、softmax、 sigmoid、 tanh等
      kernel_regularizer 可选  tf.keras.regularizers.l1() 、tf.keras.regularizers.l2()
    
  • 卷积层:

    1
    2
    3
    4
    tf.keras.layers.Conv2D(filter = 卷积核个数,
    kernel_size = 卷积核尺寸,
    strides = 卷积步长,
    padding = ”valid“ or "same")
  • LSTM层

    1
    tf.keras.layers.LSTM()

    下面举例为建立一个最终输出维度为10的分类结果的全连接神经网络。使用.add()函数进行各个层的堆叠

1
2
3
4
5
6
# Adds a densely-connected layer with 64 units to the model:
model.add(keras.layers.Dense(64, activation='relu'))
# Add another:
model.add(keras.layers.Dense(64, activation='relu'))
# Add a softmax layer with 10 output units:
model.add(keras.layers.Dense(10, activation='softmax'))

可以使用很多 tf.keras.layers,这些layers有相同的构造函数参数:

img

其中,Dense是一个全连接层,它的激活函数默认为是linear线性函数

激活函数可以通过 单独的激活层 实现,也可以通过 构建层时传递activation实现,这就是说:

1
2
model.add(Dense(64))
model.add(Activation('tanh'))

等价于

1
model.add(Dense(64, activation='tanh'))

1.2.2 model.compile

model.compile用于配置训练模型。

构建好模型后,通过调用 compile 方法配置该模型的学习流程,它是keras自带的函数,函数位于keras/engine/training.py,是类Model(Network)的一个成员函数,函数原型。接口定义如下:

1
compile(optimizer, loss=None, metrics=None, loss_weights=None, sample_weight_mode=None, weighted_metrics=None, target_tensors=None)
  • 参数

    • optimizer: 字符串(优化器名)或者优化器实例。 详见 optimizers
    • loss: 字符串(目标函数名)或目标函数。 详见 losses。 如果模型具有多个输出,则可以通过传递损失函数的字典或列表,在每个输出上使用不同的损失。 模型将最小化的损失值将是所有单个损失的总和。
    • 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 参数指定它们。 它可以是单个张量(单输出模型),张量列表,或一个映射输出名称到目标张量的字典。
    • \kwargs: 当使用 Theano/CNTK 后端时,这些参数被传入 K.function。 当使用 TensorFlow 后端时,这些参数被传递到 tf.Session.run

    异常

    • ValueError: 如果 optimizer, loss, metricssample_weight_mode 这些参数不合法。

下面时一个使用示例

1
2
3
model.compile(optimizer=tf.train.AdamOptimizer(0.001),
loss='categorical_crossentropy',
metrics=['accuracy'])

tf.keras.Model.compile 采用三个重要参数:

optimizer:此对象会指定训练过程。从 tf.train 模块向其传递优化器实例,例如 AdamOptimizer、RMSPropOptimizer 或 GradientDescentOptimizer。

loss:要在优化期间最小化的函数。常见选择包括均方误差 (mse)、categorical_crossentropy 和 binary_crossentropy。损失函数由名称或通过从 tf.keras.losses 模块传递可调用对象来指定。

metrics:用于监控训练。它们是 tf.keras.metrics 模块中的字符串名称或可调用对象。

1.2.3 model.fit

model.fit的作用是以给定数量的轮次(数据集上的迭代)训练模型。

接口定义如下

1
2
3
fit( x, y, batch_size=32, epochs=10, verbose=1, callbacks=None,
validation_split=0.0, validation_data=None, shuffle=True,
class_weight=None, sample_weight=None, initial_epoch=0)

在一般情况下使用方法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
 model.fit( 训练集的输入特征,

                 训练集的标签,  

                 batch_size,  #每一个batch的大小

                 epochs,   #迭代次数

                 validation_data = (测试集的输入特征,测试集的标签),

                 validation_split = 从测试集中划分多少比例给训练集,

                 validation_freq = 测试的epoch间隔数)

参数

  • x: 训练数据的 Numpy 数组(如果模型只有一个输入), 或者是 Numpy 数组的列表(如果模型有多个输入)。 如果模型中的输入层被命名,你也可以传递一个字典,将输入层名称映射到 Numpy 数组。 如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,x 可以是 None(默认)。
  • y: 目标(标签)数据的 Numpy 数组(如果模型只有一个输出), 或者是 Numpy 数组的列表(如果模型有多个输出)。 如果模型中的输出层被命名,你也可以传递一个字典,将输出层名称映射到 Numpy 数组。 如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,y 可以是 None(默认)。
  • batch_size: 整数或 None。每次梯度更新的样本数。如果未指定,默认为 32。
  • epochs: 整数。训练模型迭代轮次。一个轮次是在整个 xy 上的一轮迭代。 请注意,与 initial_epoch 一起,epochs 被理解为 「最终轮次」。模型并不是训练了 epochs 轮,而是到第 epochs 轮停止训练。
  • verbose: 0, 1 或 2。日志显示模式。 0 = 安静模式, 1 = 进度条, 2 = 每轮一行。
  • callbacks: 一系列的 keras.callbacks.Callback 实例。一系列可以在训练时使用的回调函数。 详见 callbacks
  • validation_split: 0 和 1 之间的浮点数。用作验证集的训练数据的比例。 模型将分出一部分不会被训练的验证数据,并将在每一轮结束时评估这些验证数据的误差和任何其他模型指标。 验证数据是混洗之前 xy 数据的最后一部分样本中。
  • validation_data: 元组 (x_val,y_val) 或元组 (x_val,y_val,val_sample_weights), 用来评估损失,以及在每轮结束时的任何模型度量指标。 模型将不会在这个数据上进行训练。这个参数会覆盖 validation_split
  • shuffle: 布尔值(是否在每轮迭代之前混洗数据)或者 字符串 (batch)。 batch 是处理 HDF5 数据限制的特殊选项,它对一个 batch 内部的数据进行混洗。 当 steps_per_epochNone 时,这个参数无效。
  • 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 训练损失和评估值,以及验证集损失和评估值的记录(如果适用)。

    异常

  • RuntimeError: 如果模型从未编译。

  • ValueError: 在提供的输入数据与模型期望的不匹配的情况下。

1.2.4 model.evaluate

model.evaluate 用于评估您训练的模型。它的输出是准确度或损失,而不是对输入数据的预测

在测试模式下返回模型的误差值和评估标准值。

计算是分批进行的。

接口定义如下

1
evaluate(x=None, y=None, batch_size=None, verbose=1, sample_weight=None, steps=None)

输入数据和标签,输出损失值和选定的指标值(如精确度accuracy)

参数

  • x: 测试数据的 Numpy 数组(如果模型只有一个输入), 或者是 Numpy 数组的列表(如果模型有多个输入)。 如果模型中的输入层被命名,你也可以传递一个字典,将输入层名称映射到 Numpy 数组。 如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,x 可以是 None(默认)。
  • y: 目标(标签)数据的 Numpy 数组,或 Numpy 数组的列表(如果模型具有多个输出)。 如果模型中的输出层被命名,你也可以传递一个字典,将输出层名称映射到 Numpy 数组。 如果从本地框架张量馈送(例如 TensorFlow 数据张量)数据,y 可以是 None(默认)。
  • batch_size: 整数或 None。每次评估的样本数。如果未指定,默认为 32。
  • verbose: 0 或 1。日志显示模式。 0 = 安静模式,1 = 进度条。
  • sample_weight: 测试样本的可选 Numpy 权重数组,用于对损失函数进行加权。 您可以传递与输入样本长度相同的扁平(1D)Numpy 数组(权重和样本之间的 1:1 映射), 或者在时序数据的情况下,传递尺寸为 (samples, sequence_length) 的 2D 数组,以对每个样本的每个时间步施加不同的权重。 在这种情况下,你应该确保在 compile() 中指定 sample_weight_mode="temporal"
  • steps: 整数或 None。 声明评估结束之前的总步数(批次样本)。默认值 None

返回

标量测试误差(如果模型只有一个输出且没有评估标准) 或标量列表(如果模型具有多个输出 和/或 评估指标)。 属性 model.metrics_names 将提供标量输出的显示标签。

用法示例

1
2
3
4
# 评估模型,不输出预测结果
loss,accuracy = model.evaluate(X_test,Y_test)
print('\ntest loss',loss)
print('accuracy',accuracy)

另外,返回了多少个值,是不固定的,如果在complie的时候没有指定metrics的话,默认只有loss一个返回值。

可以使用model.metrics_names查看。

1.2.5 model.predict

model.predict为输入样本生成输出预测。

计算是分批进行的.

接口定义如下

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

参数

  • x: 输入数据,Numpy 数组 (或者 Numpy 数组的列表,如果模型有多个输出)。
  • batch_size: 整数。如未指定,默认为 32。
  • verbose: 日志显示模式,0 或 1。
  • steps: 声明预测结束之前的总步数(批次样本)。默认值 None

返回

预测的 Numpy 数组(或数组列表)。

异常

  • ValueError: 在提供的输入数据与模型期望的不匹配的情况下, 或者在有状态的模型接收到的样本不是 batch size 的倍数的情况下。

1.3 数据预处理

1.3.1 损失函数 Losses

1.3.1.1 损失函数的使用

损失函数(或称目标函数、优化评分函数)是编译模型时所需的两个参数之一:

1
2
3
4
model.compile(loss='mean_squared_error', optimizer='sgd')
from keras import losses

model.compile(loss=losses.mean_squared_error, optimizer='sgd')

你可以传递一个现有的损失函数名,或者一个 TensorFlow/Theano 符号函数。 该符号函数为每个数据点返回一个标量,有以下两个参数:

  • y_true: 真实标签。TensorFlow/Theano 张量。
  • y_pred: 预测值。TensorFlow/Theano 张量,其 shape 与 y_true 相同。

实际的优化目标是所有数据点的输出数组的平均值。

有关这些函数的几个例子,请查看 losses source


1.3.1.2 可用损失函数

mean_squared_error

1
mean_squared_error(y_true, y_pred)

mean_absolute_error

1
mean_absolute_error(y_true, y_pred)

mean_absolute_percentage_error

1
mean_absolute_percentage_error(y_true, y_pred)

mean_squared_logarithmic_error

1
mean_squared_logarithmic_error(y_true, y_pred)

squared_hinge

1
squared_hinge(y_true, y_pred)

hinge

1
hinge(y_true, y_pred)

categorical_hinge

1
categorical_hinge(y_true, y_pred)

logcosh

1
logcosh(y_true, y_pred)

预测误差的双曲余弦的对数。

对于小的 xlog(cosh(x)) 近似等于 (x ** 2) / 2。对于大的 x,近似于 abs(x) - log(2)。这表示 ‘logcosh’ 与均方误差大致相同,但是不会受到偶尔疯狂的错误预测的强烈影响。

参数

  • y_true: 目标真实值的张量。
  • y_pred: 目标预测值的张量。

返回

每个样本都有一个标量损失的张量。

categorical_crossentropy

1
categorical_crossentropy(y_true, y_pred)

sparse_categorical_crossentropy

1
sparse_categorical_crossentropy(y_true, y_pred)

binary_crossentropy

1
binary_crossentropy(y_true, y_pred)

kullback_leibler_divergence

1
kullback_leibler_divergence(y_true, y_pred)

poisson

1
poisson(y_true, y_pred)

cosine_proximity

1
cosine_proximity(y_true, y_pred)

注意: 当使用 categorical_crossentropy 损失时,你的目标值应该是分类格式 (即,如果你有 10 个类,每个样本的目标值应该是一个 10 维的向量,这个向量除了表示类别的那个索引为 1,其他均为 0)。 为了将 整数目标值 转换为 分类目标值,你可以使用 Keras 实用函数 to_categorical

1
2
3
from keras.utils.np_utils import to_categorical

categorical_labels = to_categorical(int_labels, num_classes=None)

1.3.2 评估函数

1.3.2.1 评价函数的用法

评价函数用于评估当前训练模型的性能。当模型编译后(compile),评价函数应该作为 metrics 的参数来输入。

1
2
3
4
5
6
7
8
model.compile(loss='mean_squared_error',
optimizer='sgd',
metrics=['mae', 'acc'])
from keras import metrics

model.compile(loss='mean_squared_error',
optimizer='sgd',
metrics=[metrics.mae, metrics.categorical_accuracy])

评价函数和 损失函数 相似,只不过评价函数的结果不会用于训练过程中。

我们可以传递已有的评价函数名称,或者传递一个自定义的 Theano/TensorFlow 函数来使用(查阅自定义评价函数)。

参数

  • y_true: 真实标签,Theano/Tensorflow 张量。
  • y_pred: 预测值。和 y_true 相同尺寸的 Theano/TensorFlow 张量。

返回值

返回一个表示全部数据点平均值的张量。


1.3.2.2 可使用的评价函数

binary_accuracy

1
binary_accuracy(y_true, y_pred)

categorical_accuracy

1
categorical_accuracy(y_true, y_pred)

sparse_categorical_accuracy

1
sparse_categorical_accuracy(y_true, y_pred)

top_k_categorical_accuracy

1
top_k_categorical_accuracy(y_true, y_pred, k=5)

sparse_top_k_categorical_accuracy

1
sparse_top_k_categorical_accuracy(y_true, y_pred, k=5)

1.3.2.3 自定义评价函数

自定义评价函数应该在编译的时候(compile)传递进去。该函数需要以 (y_true, y_pred) 作为输入参数,并返回一个张量作为输出结果。

1
2
3
4
5
6
7
8
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])

1.3.3 优化器

1.3.3.1 优化器的用法

优化器 (optimizer) 是编译 Keras 模型的所需的两个参数之一:

1
2
3
4
5
6
7
8
from keras import optimizers

model = Sequential()
model.add(Dense(64, kernel_initializer='uniform', input_shape=(10,)))
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(),像上述示例中一样, 或者你可以通过名称来调用优化器。在后一种情况下,将使用优化器的默认参数。

1
2
# 传入优化器名称: 默认参数将被采用
model.compile(loss='mean_squared_error', optimizer='sgd')

1.3.3.2 Keras 优化器的公共参数

参数 clipnormclipvalue 能在所有的优化器中使用,用于控制梯度裁剪(Gradient Clipping):

1
2
3
4
5
6
7
8
9
10
from keras import optimizers

# 所有参数梯度将被裁剪,让其l2范数最大为1:g * 1 / max(1, l2_norm)
sgd = optimizers.SGD(lr=0.01, clipnorm=1.)
from keras import optimizers

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

1.3.3.3 可用的优化器

SGD

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

随机梯度下降优化器。

包含扩展功能的支持: - 动量(momentum)优化, - 学习率衰减(每次参数更新后) - Nestrov 动量 (NAG) 优化

参数

  • lr: float >= 0. 学习率。
  • momentum: float >= 0. 参数,用于加速 SGD 在相关方向上前进,并抑制震荡。
  • decay: float >= 0. 每次参数更新后学习率衰减值。
  • nesterov: boolean. 是否使用 Nesterov 动量。

RMSprop

1
keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=None, decay=0.0)

RMSProp 优化器.

建议使用优化器的默认参数 (除了学习率 lr,它可以被自由调节)

这个优化器通常是训练循环神经网络RNN的不错选择。

参数

  • lr: float >= 0. 学习率。
  • rho: float >= 0. RMSProp梯度平方的移动均值的衰减率.
  • epsilon: float >= 0. 模糊因子. 若为 None, 默认为 K.epsilon()
  • decay: float >= 0. 每次参数更新后学习率衰减值。

Adagrad

1
keras.optimizers.Adagrad(lr=0.01, epsilon=None, decay=0.0)

Adagrad 优化器。

Adagrad 是一种具有特定参数学习率的优化器,它根据参数在训练期间的更新频率进行自适应调整。参数接收的更新越多,更新越小。

建议使用优化器的默认参数。

参数

  • lr: float >= 0. 学习率.
  • epsilon: float >= 0. 若为 None, 默认为 K.epsilon().
  • decay: float >= 0. 每次参数更新后学习率衰减值.

Adadelta

1
keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=None, decay=0.0)

Adadelta 优化器。

Adadelta 是 Adagrad 的一个具有更强鲁棒性的的扩展版本,它不是累积所有过去的梯度,而是根据渐变更新的移动窗口调整学习速率。 这样,即使进行了许多更新,Adadelta 仍在继续学习。 与 Adagrad 相比,在 Adadelta 的原始版本中,您无需设置初始学习率。 在此版本中,与大多数其他 Keras 优化器一样,可以设置初始学习速率和衰减因子。

建议使用优化器的默认参数。

参数

  • lr: float >= 0. 学习率,建议保留默认值。
  • rho: float >= 0. Adadelta梯度平方移动均值的衰减率。
  • epsilon: float >= 0. 模糊因子. 若为 None, 默认为 K.epsilon()
  • decay: float >= 0. 每次参数更新后学习率衰减值。

Adam

1
keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)

Adam 优化器。

默认参数遵循原论文中提供的值。

参数

  • lr: float >= 0. 学习率。
  • beta_1: float, 0 < beta < 1. 通常接近于 1。
  • beta_2: float, 0 < beta < 1. 通常接近于 1。
  • epsilon: float >= 0. 模糊因子. 若为 None, 默认为 K.epsilon()
  • decay: float >= 0. 每次参数更新后学习率衰减值。
  • amsgrad: boolean. 是否应用此算法的 AMSGrad 变种,来自论文 “On the Convergence of Adam and Beyond”。

Adamax

1
keras.optimizers.Adamax(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0)

Adamax 优化器,来自 Adam 论文的第七小节.

它是Adam算法基于无穷范数(infinity norm)的变种。 默认参数遵循论文中提供的值。

参数

  • lr: float >= 0. 学习率。
  • beta_1/beta_2: floats, 0 < beta < 1. 通常接近于 1。
  • epsilon: float >= 0. 模糊因子. 若为 None, 默认为 K.epsilon()
  • decay: float >= 0. 每次参数更新后学习率衰减值。

Nadam

1
keras.optimizers.Nadam(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=None, schedule_decay=0.004)

Nesterov 版本 Adam 优化器。

正像 Adam 本质上是 RMSProp 与动量 momentum 的结合, Nadam 是采用 Nesterov momentum 版本的 Adam 优化器。

默认参数遵循论文中提供的值。 建议使用优化器的默认参数。

参数

  • lr: float >= 0. 学习率。
  • beta_1/beta_2: floats, 0 < beta < 1. 通常接近于 1。
  • epsilon: float >= 0. 模糊因子. 若为 None, 默认为 K.epsilon()

1.3.4 激活函数

1.3.4.1 激活函数的用法

激活函数可以通过设置单独的激活层实现,也可以在构造层对象时通过传递 activation 参数实现:

1
2
3
4
from keras.layers import Activation, Dense

model.add(Dense(64))
model.add(Activation('tanh'))

等价于:

1
model.add(Dense(64, activation='tanh'))

你也可以通过传递一个逐元素运算的 Theano/TensorFlow/CNTK 函数来作为激活函数:

1
2
3
4
from keras import backend as K

model.add(Dense(64, activation=K.tanh))
model.add(Activation(K.tanh))

1.3.4.2 预定义激活函数

softmax

1
keras.activations.softmax(x, axis=-1)

Softmax 激活函数。

参数

  • x:张量。
  • axis:整数,代表softmax所作用的维度。

返回

softmax 变换后的张量。

异常

  • ValueError:如果 dim(x) == 1

elu

1
keras.activations.elu(x, alpha=1.0)

指数线性单元。

参数

  • x:张量。
  • alpha:一个标量,表示负数部分的斜率。

返回

线性指数激活:如果 x > 0,返回值为 x;如果 x < 0 返回值为 alpha * (exp(x)-1)


selu

1
keras.activations.selu(x)

可伸缩的指数线性单元(SELU)。

SELU 等同于:scale * elu(x, alpha),其中 alpha 和 scale 是预定义的常量。只要正确初始化权重(参见 lecun_normal 初始化方法)并且输入的数量「足够大」(参见参考文献获得更多信息),选择合适的 alpha 和 scale 的值,就可以在两个连续层之间保留输入的均值和方差。

参数

  • x: 一个用来用于计算激活函数的张量或变量。

返回

可伸缩的指数线性激活:scale * elu(x, alpha)

注意

  • 与「lecun_normal」初始化方法一起使用。
  • 与 dropout 的变种「AlphaDropout」一起使用。

softplus

1
keras.activations.softplus(x)

Softplus 激活函数。

参数

  • x: 张量。

返回

Softplus 激活:log(exp(x) + 1)


softsign

1
keras.activations.softsign(x)

Softsign 激活函数。

参数

  • x: 张量。

返回

Softsign 激活:x / (abs(x) + 1)


relu

1
keras.activations.relu(x, alpha=0.0, max_value=None, threshold=0.0)

整流线性单元。

使用默认值时,它返回逐元素的 max(x, 0)

否则,它遵循:

  • 如果 x >= max_valuef(x) = max_value
  • 如果 threshold <= x < max_valuef(x) = x
  • 否则:f(x) = alpha * (x - threshold)

参数

  • x: 张量。
  • alpha:负数部分的斜率。默认为 0。
  • max_value:输出的最大值。
  • threshold: 浮点数。Thresholded activation 的阈值值。

返回

一个张量。


tanh

1
keras.activations.tanh(x)

双曲正切激活函数。


sigmoid

1
sigmoid(x)

Sigmoid 激活函数。


hard_sigmoid

1
hard_sigmoid(x)

Hard sigmoid 激活函数。

计算速度比 sigmoid 激活函数更快。

参数

  • x: 张量。

返回

Hard sigmoid 激活:

  • 如果 x < -2.5,返回 0。
  • 如果 x > 2.5,返回 1。
  • 如果 -2.5 <= x <= 2.5,返回 0.2 * x + 0.5

exponential

1
keras.activations.exponential(x)

自然数指数激活函数。


linear

1
keras.activations.linear(x)

线性激活函数(即不做任何改变)


1.3.4.3 高级激活函数

对于 Theano/TensorFlow/CNTK 不能表达的复杂激活函数,如含有可学习参数的激活函数,可通过高级激活函数实现,可以在 keras.layers.advanced_activations 模块中找到。 这些高级激活函数包括 PReLU

1.3.5 回调函数

回调函数使用

回调函数是一个函数的合集,会在训练的阶段中所使用。你可以使用回调函数来查看训练模型的内在状态和统计。你可以传递一个列表的回调函数(作为 callbacks 关键字参数)到 SequentialModel 类型的 .fit() 方法。在训练时,相应的回调函数的方法就会被在各自的阶段被调用。


Callback

1
keras.callbacks.Callback()

用来组建新的回调函数的抽象基类。

属性

  • params: 字典。训练参数, (例如,verbosity, batch size, number of epochs…)。
  • model: keras.models.Model 的实例。 指代被训练模型。

被回调函数作为参数的 logs 字典,它会含有于当前批量或训练轮相关数据的键。

目前,Sequential 模型类的 .fit() 方法会在传入到回调函数的 logs 里面包含以下的数据:

  • on_epoch_end: 包括 accloss 的日志, 也可以选择性的包括 val_loss(如果在 fit 中启用验证),和 val_acc(如果启用验证和监测精确值)。
  • on_batch_begin: 包括 size 的日志,在当前批量内的样本数量。
  • on_batch_end: 包括 loss 的日志,也可以选择性的包括 acc(如果启用监测精确值)。

BaseLogger

1
keras.callbacks.BaseLogger(stateful_metrics=None)

会积累训练轮平均评估的回调函数。

这个回调函数被自动应用到每一个 Keras 模型上面。

参数

stateful_metrics: 可重复使用不应在一个 epoch 上平均的指标的字符串名称。 此列表中的度量标准将按原样记录在 on_epoch_end 中。 所有其他指标将在 on_epoch_end 中取平均值。


TerminateOnNaN

1
keras.callbacks.TerminateOnNaN()

当遇到 NaN 损失会停止训练的回调函数。


ProgbarLogger

1
keras.callbacks.ProgbarLogger(count_mode='samples', stateful_metrics=None)

会把评估以标准输出打印的回调函数。

参数

  • count_mode: “steps” 或者 “samples”。 进度条是否应该计数看见的样本或步骤(批量)。 stateful_metrics: 可重复使用不应在一个 epoch 上平均的指标的字符串名称。 此列表中的度量标准将按原样记录在 on_epoch_end 中。 所有其他指标将在 on_epoch_end 中取平均值。

异常

  • ValueError: 如果 count_mode

History

1
keras.callbacks.History()

把所有事件都记录到 History 对象的回调函数。

这个回调函数被自动启用到每一个 Keras 模型。History 对象会被模型的 fit 方法返回。


ModelCheckpoint

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

在每个训练期之后保存模型。

filepath 可以包括命名格式选项,可以由 epoch 的值和 logs 的键(由 on_epoch_end 参数传递)来填充。

例如:如果 filepathweights.{epoch:02d}-{val_loss:.2f}.hdf5, 那么模型被保存的的文件名就会有训练轮数和验证损失。

参数

  • filepath: 字符串,保存模型的路径。
  • monitor: 被监测的数据。
  • verbose: 详细信息模式,0 或者 1 。
  • save_best_only: 如果 save_best_only=True, 被监测数据的最佳模型就不会被覆盖。
  • mode: {auto, min, max} 的其中之一。 如果 save_best_only=True,那么是否覆盖保存文件的决定就取决于被监测数据的最大或者最小值。 对于 val_acc,模式就会是 max,而对于 val_loss,模式就需要是 min,等等。 在 auto 模式中,方向会自动从被监测的数据的名字中判断出来。
  • save_weights_only: 如果 True,那么只有模型的权重会被保存 (model.save_weights(filepath)), 否则的话,整个模型会被保存 (model.save(filepath))。
  • period: 每个检查点之间的间隔(训练轮数)。

EarlyStopping

1
keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=0, verbose=0, mode='auto', baseline=None, restore_best_weights=False)

当被监测的数量不再提升,则停止训练。

参数

  • monitor: 被监测的数据。
  • min_delta: 在被监测的数据中被认为是提升的最小变化, 例如,小于 min_delta 的绝对变化会被认为没有提升。
  • patience: 没有进步的训练轮数,在这之后训练就会被停止。
  • verbose: 详细信息模式。
  • mode: {auto, min, max} 其中之一。 在 min 模式中, 当被监测的数据停止下降,训练就会停止;在 max 模式中,当被监测的数据停止上升,训练就会停止;在 auto 模式中,方向会自动从被监测的数据的名字中判断出来。
  • baseline: 要监控的数量的基准值。 如果模型没有显示基准的改善,训练将停止。
  • restore_best_weights: 是否从具有监测数量的最佳值的时期恢复模型权重。 如果为 False,则使用在训练的最后一步获得的模型权重。

RemoteMonitor

1
keras.callbacks.RemoteMonitor(root='http://localhost:9000', path='/publish/epoch/end/', field='data', headers=None, send_as_json=False)

将事件数据流到服务器的回调函数。

需要 requests 库。 事件被默认发送到 root + '/publish/epoch/end/'。 采用 HTTP POST ,其中的 data 参数是以 JSON 编码的事件数据字典。 如果 send_as_json 设置为 True,请求的 content type 是 application/json。否则,将在表单中发送序列化的 JSON。

参数

  • root: 字符串;目标服务器的根地址。
  • path: 字符串;相对于 root 的路径,事件数据被送达的地址。
  • field: 字符串;JSON ,数据被保存的领域。
  • headers: 字典;可选自定义的 HTTP 的头字段。
  • send_as_json: 布尔值;请求是否应该以 application/json 格式发送。

LearningRateScheduler

1
keras.callbacks.LearningRateScheduler(schedule, verbose=0)

学习速率定时器。

参数

  • schedule: 一个函数,接受轮索引数作为输入(整数,从 0 开始迭代) 然后返回一个学习速率作为输出(浮点数)。
  • verbose: 整数。 0:安静,1:更新信息。

TensorBoard

1
keras.callbacks.TensorBoard(log_dir='./logs', histogram_freq=0, batch_size=32, write_graph=True, write_grads=False, write_images=False, embeddings_freq=0, embeddings_layer_names=None, embeddings_metadata=None, embeddings_data=None, update_freq='epoch')

Tensorboard 基本可视化。

TensorBoard 是由 Tensorflow 提供的一个可视化工具。

这个回调函数为 Tensorboard 编写一个日志, 这样你可以可视化测试和训练的标准评估的动态图像, 也可以可视化模型中不同层的激活值直方图。

如果你已经使用 pip 安装了 Tensorflow,你应该可以从命令行启动 Tensorflow:

1
tensorboard --logdir=/full_path_to_your_logs

参数

  • log_dir: 用来保存被 TensorBoard 分析的日志文件的文件名。
  • histogram_freq: 对于模型中各个层计算激活值和模型权重直方图的频率(训练轮数中)。 如果设置成 0 ,直方图不会被计算。对于直方图可视化的验证数据(或分离数据)一定要明确的指出。
  • write_graph: 是否在 TensorBoard 中可视化图像。 如果 write_graph 被设置为 True,日志文件会变得非常大。
  • write_grads: 是否在 TensorBoard 中可视化梯度值直方图。 histogram_freq 必须要大于 0 。
  • batch_size: 用以直方图计算的传入神经元网络输入批的大小。
  • write_images: 是否在 TensorBoard 中将模型权重以图片可视化。
  • embeddings_freq: 被选中的嵌入层会被保存的频率(在训练轮中)。
  • embeddings_layer_names: 一个列表,会被监测层的名字。 如果是 None 或空列表,那么所有的嵌入层都会被监测。
  • embeddings_metadata: 一个字典,对应层的名字到保存有这个嵌入层元数据文件的名字。 查看 详情 关于元数据的数据格式。 以防同样的元数据被用于所用的嵌入层,字符串可以被传入。
  • embeddings_data: 要嵌入在 embeddings_layer_names 指定的层的数据。 Numpy 数组(如果模型有单个输入)或 Numpy 数组列表(如果模型有多个输入)。 Learn ore about embeddings
  • update_freq: 'batch''epoch' 或 整数。当使用 'batch' 时,在每个 batch 之后将损失和评估值写入到 TensorBoard 中。同样的情况应用到 'epoch' 中。如果使用整数,例如 10000,这个回调会在每 10000 个样本之后将损失和评估值写入到 TensorBoard 中。注意,频繁地写入到 TensorBoard 会减缓你的训练。

ReduceLROnPlateau

1
keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=10, verbose=0, mode='auto', min_delta=0.0001, cooldown=0, min_lr=0)

当标准评估停止提升时,降低学习速率。

当学习停止时,模型总是会受益于降低 2-10 倍的学习速率。 这个回调函数监测一个数据并且当这个数据在一定「有耐心」的训练轮之后还没有进步, 那么学习速率就会被降低。

例子

1
2
3
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2,
patience=5, min_lr=0.001)
model.fit(X_train, Y_train, callbacks=[reduce_lr])

参数

  • monitor: 被监测的数据。
  • factor: 学习速率被降低的因数。新的学习速率 = 学习速率 * 因数
  • patience: 没有进步的训练轮数,在这之后训练速率会被降低。
  • verbose: 整数。0:安静,1:更新信息。
  • mode: {auto, min, max} 其中之一。如果是 min 模式,学习速率会被降低如果被监测的数据已经停止下降; 在 max 模式,学习塑料会被降低如果被监测的数据已经停止上升; 在 auto 模式,方向会被从被监测的数据中自动推断出来。
  • min_delta: 对于测量新的最优化的阀值,只关注巨大的改变。
  • cooldown: 在学习速率被降低之后,重新恢复正常操作之前等待的训练轮数量。
  • min_lr: 学习速率的下边界。

CSVLogger

1
keras.callbacks.CSVLogger(filename, separator=',', append=False)

把训练轮结果数据流到 csv 文件的回调函数。

支持所有可以被作为字符串表示的值,包括 1D 可迭代数据,例如,np.ndarray。

例子

1
2
csv_logger = CSVLogger('training.log')
model.fit(X_train, Y_train, callbacks=[csv_logger])

参数

  • filename: csv 文件的文件名,例如 ‘run/log.csv’。
  • separator: 用来隔离 csv 文件中元素的字符串。
  • append: True:如果文件存在则增加(可以被用于继续训练)。False:覆盖存在的文件。

LambdaCallback

1
keras.callbacks.LambdaCallback(on_epoch_begin=None, on_epoch_end=None, on_batch_begin=None, on_batch_end=None, on_train_begin=None, on_train_end=None)

在训练进行中创建简单,自定义的回调函数的回调函数。

这个回调函数和匿名函数在合适的时间被创建。 需要注意的是回调函数要求位置型参数,如下:

  • on_epoch_beginon_epoch_end 要求两个位置型的参数: epoch, logs
  • on_batch_beginon_batch_end 要求两个位置型的参数: batch, logs
  • on_train_beginon_train_end 要求一个位置型的参数: logs

参数

  • on_epoch_begin: 在每轮开始时被调用。
  • on_epoch_end: 在每轮结束时被调用。
  • on_batch_begin: 在每批开始时被调用。
  • on_batch_end: 在每批结束时被调用。
  • on_train_begin: 在模型训练开始时被调用。
  • on_train_end: 在模型训练结束时被调用。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 在每一个批开始时,打印出批数。
batch_print_callback = LambdaCallback(
on_batch_begin=lambda batch,logs: print(batch))

# 把训练轮损失数据流到 JSON 格式的文件。文件的内容
# 不是完美的 JSON 格式,但是时每一行都是 JSON 对象。
import json
json_log = open('loss_log.json', mode='wt', buffering=1)
json_logging_callback = LambdaCallback(
on_epoch_end=lambda epoch, logs: json_log.write(
json.dumps({'epoch': epoch, 'loss': logs['loss']}) + '\n'),
on_train_end=lambda logs: json_log.close()
)

# 在完成模型训练之后,结束一些进程。
processes = ...
cleanup_callback = LambdaCallback(
on_train_end=lambda logs: [
p.terminate() for p in processes if p.is_alive()])

model.fit(...,
callbacks=[batch_print_callback,
json_logging_callback,
cleanup_callback])

创建一个回调函数

你可以通过扩展 keras.callbacks.Callback 基类来创建一个自定义的回调函数。 通过类的属性 self.model,回调函数可以获得它所联系的模型。

下面是一个简单的例子,在训练时,保存一个列表的批量损失值:

1
2
3
4
5
6
class LossHistory(keras.callbacks.Callback):
def on_train_begin(self, logs={}):
self.losses = []

def on_batch_end(self, batch, logs={}):
self.losses.append(logs.get('loss'))

例: 记录损失历史

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class LossHistory(keras.callbacks.Callback):
def on_train_begin(self, logs={}):
self.losses = []

def on_batch_end(self, batch, logs={}):
self.losses.append(logs.get('loss'))

model = Sequential()
model.add(Dense(10, input_dim=784, kernel_initializer='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

history = LossHistory()
model.fit(x_train, y_train, batch_size=128, epochs=20, verbose=0, callbacks=[history])

print(history.losses)
# 输出
'''
[0.66047596406559383, 0.3547245744908703, ..., 0.25953155204159617, 0.25901699725311789]
'''

例: 模型检查点

1
2
3
4
5
6
7
8
9
10
11
12
from keras.callbacks import ModelCheckpoint

model = Sequential()
model.add(Dense(10, input_dim=784, kernel_initializer='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

'''
如果验证损失下降, 那么在每个训练轮之后保存模型。
'''
checkpointer = ModelCheckpoint(filepath='/tmp/weights.hdf5', verbose=1, save_best_only=True)
model.fit(x_train, y_train, batch_size=128, epochs=20, verbose=0, validation_data=(X_test, Y_test), callbacks=[c

1.3.6 初始化器

1.3.6.1 初始化器的用法

初始化定义了设置 Keras 各层权重随机初始值的方法。

用来将初始化器传入 Keras 层的参数名取决于具体的层。通常关键字为 kernel_initializerbias_initializer:

1
2
3
model.add(Dense(64,
kernel_initializer='random_uniform',
bias_initializer='zeros'))

1.3.6.2 可用的初始化器

下面这些是可用的内置初始化器,是 keras.initializers 模块的一部分:

Initializer

1
keras.initializers.Initializer()

初始化器基类:所有初始化器继承这个类。


Zeros

1
keras.initializers.Zeros()

将张量初始值设为 0 的初始化器。


Ones

1
keras.initializers.Ones()

将张量初始值设为 1 的初始化器。


Constant

1
keras.initializers.Constant(value=0)

将张量初始值设为一个常数的初始化器。

参数

  • value: 浮点数,生成的张量的值。

RandomNormal

1
keras.initializers.RandomNormal(mean=0.0, stddev=0.05, seed=None)

按照正态分布生成随机张量的初始化器。

参数

  • mean: 一个 Python 标量或者一个标量张量。要生成的随机值的平均数。
  • stddev: 一个 Python 标量或者一个标量张量。要生成的随机值的标准差。
  • seed: 一个 Python 整数。用于设置随机数种子。

RandomUniform

1
keras.initializers.RandomUniform(minval=-0.05, maxval=0.05, seed=None)

按照均匀分布生成随机张量的初始化器。

参数

  • minval: 一个 Python 标量或者一个标量张量。要生成的随机值的范围下限。
  • maxval: 一个 Python 标量或者一个标量张量。要生成的随机值的范围下限。默认为浮点类型的 1。
  • seed: 一个 Python 整数。用于设置随机数种子。

TruncatedNormal

1
keras.initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None)

按照截尾正态分布生成随机张量的初始化器。

生成的随机值与 RandomNormal 生成的类似,但是在距离平均值两个标准差之外的随机值将被丢弃并重新生成。这是用来生成神经网络权重和滤波器的推荐初始化器。

Arguments

  • mean: 一个 Python 标量或者一个标量张量。要生成的随机值的平均数。
  • stddev: 一个 Python 标量或者一个标量张量。要生成的随机值的标准差。
  • seed: 一个 Python 整数。用于设置随机数种子。

VarianceScaling

1
keras.initializers.VarianceScaling(scale=1.0, mode='fan_in', distribution='normal', seed=None)

初始化器能够根据权值的尺寸调整其规模。

使用 distribution="normal" 时,样本是从一个以 0 为中心的截断正态分布中抽取的,stddev = sqrt(scale / n),其中 n 是:

  • 权值张量中输入单元的数量,如果 mode = “fan_in”。
  • 输出单元的数量,如果 mode = “fan_out”。
  • 输入和输出单位数量的平均数,如果 mode = “fan_avg”。

使用 distribution="uniform" 时,样本是从 [-limit,limit] 内的均匀分布中抽取的,其中 limit = sqrt(3 * scale / n)

参数

  • scale: 缩放因子(正浮点数)。
  • mode: “fan_in”, “fan_out”, “fan_avg” 之一。
  • distribution: 使用的随机分布。”normal”, “uniform” 之一。
  • seed: 一个 Python 整数。作为随机发生器的种子。

异常

  • ValueError: 如果 “scale”, mode” 或 “distribution” 参数无效。

Orthogonal

1
keras.initializers.Orthogonal(gain=1.0, seed=None)

生成一个随机正交矩阵的初始化器。

参数

  • gain: 适用于正交矩阵的乘法因子。
  • seed: 一个 Python 整数。作为随机发生器的种子。

Identity

1
keras.initializers.Identity(gain=1.0)

生成单位矩阵的初始化器。

仅用于 2D 方阵。

参数

  • gain: 适用于单位矩阵的乘法因子。

lecun_uniform

1
keras.initializers.lecun_uniform(seed=None)

LeCun 均匀初始化器。

它从 [-limit,limit] 中的均匀分布中抽取样本, 其中 limitsqrt(3 / fan_in)fan_in 是权值张量中的输入单位的数量。

参数

  • seed: 一个 Python 整数。作为随机发生器的种子。

返回

一个初始化器。


glorot_normal

1
keras.initializers.glorot_normal(seed=None)

Glorot 正态分布初始化器,也称为 Xavier 正态分布初始化器。

它从以 0 为中心,标准差为 stddev = sqrt(2 / (fan_in + fan_out)) 的截断正态分布中抽取样本, 其中 fan_in 是权值张量中的输入单位的数量, fan_out 是权值张量中的输出单位的数量。

参数

  • seed: 一个 Python 整数。作为随机发生器的种子。

返回

一个初始化器。


glorot_uniform

1
keras.initializers.glorot_uniform(seed=None)

Glorot 均匀分布初始化器,也称为 Xavier 均匀分布初始化器。

它从 [-limit,limit] 中的均匀分布中抽取样本, 其中 limitsqrt(6 / (fan_in + fan_out))fan_in 是权值张量中的输入单位的数量, fan_out 是权值张量中的输出单位的数量。

参数

  • seed: 一个 Python 整数。作为随机发生器的种子。

返回

一个初始化器。


he_normal

1
keras.initializers.he_normal(seed=None)

He 正态分布初始化器。

它从以 0 为中心,标准差为 stddev = sqrt(2 / fan_in) 的截断正态分布中抽取样本, 其中 fan_in 是权值张量中的输入单位的数量,

参数

  • seed: 一个 Python 整数。作为随机发生器的种子。

返回

一个初始化器。


lecun_normal

1
keras.initializers.lecun_normal(seed=None)

LeCun 正态分布初始化器。

它从以 0 为中心,标准差为 stddev = sqrt(1 / fan_in) 的截断正态分布中抽取样本, 其中 fan_in 是权值张量中的输入单位的数量。

参数

  • seed: 一个 Python 整数。作为随机发生器的种子。

返回

一个初始化器。


he_uniform

1
keras.initializers.he_uniform(seed=None)

He 均匀方差缩放初始化器。

它从 [-limit,limit] 中的均匀分布中抽取样本, 其中 limitsqrt(6 / fan_in), 其中 fan_in 是权值张量中的输入单位的数量。

参数

  • seed: 一个 Python 整数。作为随机发生器的种子。

返回

一个初始化器。

参考文献

一个初始化器可以作为一个字符串传递(必须匹配上面的一个可用的初始化器),或者作为一个可调用函数传递:

1
2
3
4
5
6
from keras import initializers

model.add(Dense(64, kernel_initializer=initializers.random_normal(stddev=0.01)))

# 同样有效;将使用默认参数。
model.add(Dense(64, kernel_initializer='random_normal'))

1.3.6.3 使用自定义初始化器

如果传递一个自定义的可调用函数,那么它必须使用参数 shape(需要初始化的变量的尺寸)和 dtype(数据类型):

1
2
3
4
5
6
from keras import backend as K

def my_init(shape, dtype=None):
return K.random_normal(shape, dtype=dtype)

model.add(Dense(64, kernel_initializer=my_init))

1.4 Keras 网络层

1.4.1 关于 Keras 网络层

所有 Keras 网络层都有很多共同的函数:

  • layer.get_weights(): 以含有Numpy矩阵的列表形式返回层的权重。
  • layer.set_weights(weights): 从含有Numpy矩阵的列表中设置层的权重(与get_weights的输出形状相同)。
  • layer.get_config(): 返回包含层配置的字典。此图层可以通过以下方式重置:
1
2
3
layer = Dense(32)
config = layer.get_config()
reconstructed_layer = Dense.from_config(config)

或:

1
2
3
4
5
from keras import layers

config = layer.get_config()
layer = layers.deserialize({'class_name': layer.__class__.__name__,
'config': config})

如果一个层具有单个节点 (i.e. 如果它不是共享层), 你可以得到它的输入张量、输出张量、输入尺寸和输出尺寸:

  • layer.input
  • layer.output
  • layer.input_shape
  • layer.output_shape

如果层有多个节点 (参见: 层节点和共享层的概念), 您可以使用以下函数:

  • layer.get_input_at(node_index)
  • layer.get_output_at(node_index)
  • layer.get_input_shape_at(node_index)
  • layer.get_output_shape_at(node_index)

1.4.2 核心网络层Dense

1.4.2.1 Dense

1
keras.layers.Dense(units, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)

就是你常用的的全连接层。

Dense 实现以下操作: output = activation(dot(input, kernel) + bias) 其中 activation 是按逐个元素计算的激活函数,kernel 是由网络层创建的权值矩阵,以及 bias 是其创建的偏置向量 (只在 use_biasTrue 时才有用)。

  • 注意: 如果该层的输入的秩大于2,那么它首先被展平然后 再计算与 kernel 的点乘。

示例

1
2
3
4
5
6
7
8
# 作为 Sequential 模型的第一层
model = Sequential()
model.add(Dense(32, input_shape=(16,)))
# 现在模型就会以尺寸为 (*, 16) 的数组作为输入,
# 其输出数组的尺寸为 (*, 32)

# 在第一层之后,你就不再需要指定输入的尺寸了:
model.add(Dense(32))

参数

  • units: 正整数,输出空间维度。
  • activation: 激活函数 (详见 activations)。 若不指定,则不使用激活函数 (即,「线性」激活: a(x) = x)。
  • use_bias: 布尔值,该层是否使用偏置向量。
  • kernel_initializer: kernel 权值矩阵的初始化器 (详见 initializers)。
  • bias_initializer: 偏置向量的初始化器 (see initializers).
  • kernel_regularizer: 运用到 kernel 权值矩阵的正则化函数 (详见 regularizer)。
  • bias_regularizer: 运用到偏置向的的正则化函数 (详见 regularizer)。
  • activity_regularizer: 运用到层的输出的正则化函数 (它的 “activation”)。 (详见 regularizer)。
  • kernel_constraint: 运用到 kernel 权值矩阵的约束函数 (详见 constraints)。
  • bias_constraint: 运用到偏置向量的约束函数 (详见 constraints)。

输入尺寸

nD 张量,尺寸: (batch_size, ..., input_dim)。 最常见的情况是一个尺寸为 (batch_size, input_dim) 的 2D 输入。

输出尺寸

nD 张量,尺寸: (batch_size, ..., units)。 例如,对于尺寸为 (batch_size, input_dim) 的 2D 输入, 输出的尺寸为 (batch_size, units)


1.4.2.2 Activation

1
keras.layers.Activation(activation)

将激活函数应用于输出。

参数

  • activation: 要使用的激活函数的名称 (详见: activations), 或者选择一个 Theano 或 TensorFlow 操作。

输入尺寸

任意尺寸。 当使用此层作为模型中的第一层时, 使用参数 input_shape (整数元组,不包括样本数的轴)。

输出尺寸

与输入相同。


1.4.2.3 Dropout

1
keras.layers.Dropout(rate, noise_shape=None, seed=None)

将 Dropout 应用于输入。

Dropout 包括在训练中每次更新时, 将输入单元的按比率随机设置为 0, 这有助于防止过拟合。

参数

  • rate: 在 0 和 1 之间浮动。需要丢弃的输入比例。
  • noise_shape: 1D 整数张量, 表示将与输入相乘的二进制 dropout 掩层的形状。 例如,如果你的输入尺寸为 (batch_size, timesteps, features),然后 你希望 dropout 掩层在所有时间步都是一样的, 你可以使用 noise_shape=(batch_size, 1, features)
  • seed: 一个作为随机种子的 Python 整数。

1.4.2.4 Flatten

1
keras.layers.Flatten(data_format=None)

将输入展平。不影响批量大小。

参数

  • data_format:一个字符串,其值为 channels_last(默认值)或者 channels_first。它表明输入的维度的顺序。此参数的目的是当模型从一种数据格式切换到另一种数据格式时保留权重顺序。channels_last 对应着尺寸为 (batch, ..., channels) 的输入,而 channels_first 对应着尺寸为 (batch, channels, ...) 的输入。默认为 image_data_format 的值,你可以在 Keras 的配置文件 ~/.keras/keras.json 中找到它。如果你从未设置过它,那么它将是 channels_last

示例

1
2
3
4
5
6
7
model = Sequential()
model.add(Conv2D(64, (3, 3),
input_shape=(3, 32, 32), padding='same',))
# 现在:model.output_shape == (None, 64, 32, 32)

model.add(Flatten())
# 现在:model.output_shape == (None, 65536)

1.4.2.5 Input

1
keras.engine.input_layer.Input()

Input() 用于实例化 Keras 张量。

Keras 张量是底层后端(Theano, TensorFlow 或 CNTK) 的张量对象,我们增加了一些特性,使得能够通过了解模型的输入 和输出来构建 Keras 模型。

例如,如果 a, b 和 c 都是 Keras 张量, 那么以下操作是可行的: model = Model(input=[a, b], output=c)

添加的 Keras 属性是: - _keras_shape: 通过 Keras端的尺寸推理 进行传播的整数尺寸元组。 - _keras_history: 应用于张量的最后一层。 整个网络层计算图可以递归地从该层中检索。

参数

  • shape: 一个尺寸元组(整数),不包含批量大小。 例如,shape=(32,) 表明期望的输入是按批次的 32 维向量。
  • batch_shape: 一个尺寸元组(整数),包含批量大小。 例如,batch_shape=(10, 32) 表明期望的输入是 10 个 32 维向量。 batch_shape=(None, 32) 表明任意批次大小的 32 维向量。
  • name: 一个可选的层的名称的字符串。 在一个模型中应该是唯一的(不可以重用一个名字两次)。 如未提供,将自动生成。
  • dtype: 输入所期望的数据类型,字符串表示 (float32, float64, int32…)
  • sparse: 一个布尔值,指明需要创建的占位符是否是稀疏的。
  • tensor: 可选的可封装到 Input 层的现有张量。 如果设定了,那么这个层将不会创建占位符张量。

返回

一个张量。

示例

1
2
3
4
# 这是 Keras 中的一个逻辑回归
x = Input(shape=(32,))
y = Dense(16, activation='softmax')(x)
model = Model(x, y)

1.4.2.6 Reshape

1
keras.layers.Reshape(target_shape)

将输入重新调整为特定的尺寸。

参数

  • target_shape: 目标尺寸。整数元组。 不包含表示批量的轴。

输入尺寸

任意,尽管输入尺寸中的所有维度必须是固定的。 当使用此层作为模型中的第一层时, 使用参数 input_shape (整数元组,不包括样本数的轴)。

输出尺寸

1
(batch_size,) + target_shape

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
# 作为 Sequential 模型的第一层
model = Sequential()
model.add(Reshape((3, 4), input_shape=(12,)))
# 现在:model.output_shape == (None, 3, 4)
# 注意: `None` 是批表示的维度

# 作为 Sequential 模型的中间层
model.add(Reshape((6, 2)))
# 现在: model.output_shape == (None, 6, 2)

# 还支持使用 `-1` 表示维度的尺寸推断
model.add(Reshape((-1, 2, 2)))
# 现在: model.output_shape == (None, 3, 2, 2)

1.4.2.7 Permute

1
keras.layers.Permute(dims)

根据给定的模式置换输入的维度。

在某些场景下很有用,例如将 RNN 和 CNN 连接在一起。

示例

1
2
3
4
model = Sequential()
model.add(Permute((2, 1), input_shape=(10, 64)))
# 现在: model.output_shape == (None, 64, 10)
# 注意: `None` 是批表示的维度

参数

  • dims: 整数元组。置换模式,不包含样本维度。 索引从 1 开始。 例如, (2, 1) 置换输入的第一和第二个维度。

输入尺寸

任意。当使用此层作为模型中的第一层时, 使用参数 input_shape (整数元组,不包括样本数的轴)。

输出尺寸

与输入尺寸相同,但是维度根据指定的模式重新排列。


1.4.2.8 RepeatVector

1
keras.layers.RepeatVector(n)

将输入重复 n 次。

示例

1
2
3
4
5
6
7
model = Sequential()
model.add(Dense(32, input_dim=32))
# 现在: model.output_shape == (None, 32)
# 注意: `None` 是批表示的维度

model.add(RepeatVector(3))
# 现在: model.output_shape == (None, 3, 32)

参数

  • n: 整数,重复次数。

输入尺寸

2D 张量,尺寸为 (num_samples, features)

输出尺寸

3D 张量,尺寸为 (num_samples, n, features)


1.4.2.9 Lambda

1
keras.layers.Lambda(function, output_shape=None, mask=None, arguments=None)

将任意表达式封装为 Layer 对象。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 添加一个 x -> x^2 层
model.add(Lambda(lambda x: x ** 2))
# 添加一个网络层,返回输入的正数部分
# 与负数部分的反面的连接

def antirectifier(x):
x -= K.mean(x, axis=1, keepdims=True)
x = K.l2_normalize(x, axis=1)
pos = K.relu(x)
neg = K.relu(-x)
return K.concatenate([pos, neg], axis=1)

def antirectifier_output_shape(input_shape):
shape = list(input_shape)
assert len(shape) == 2 # only valid for 2D tensors
shape[-1] *= 2
return tuple(shape)

model.add(Lambda(antirectifier,
output_shape=antirectifier_output_shape))

参数

  • function: 需要封装的函数。 将输入张量作为第一个参数。
  • output_shape: 预期的函数输出尺寸。 只在使用 Theano 时有意义。 可以是元组或者函数。 如果是元组,它只指定第一个维度; 样本维度假设与输入相同: output_shape = (input_shape[0], ) + output_shape 或者,输入是 None 且样本维度也是 Noneoutput_shape = (None, ) + output_shape 如果是函数,它指定整个尺寸为输入尺寸的一个函数: output_shape = f(input_shape)
  • arguments: 可选的需要传递给函数的关键字参数。

输入尺寸

任意。当使用此层作为模型中的第一层时, 使用参数 input_shape (整数元组,不包括样本数的轴)。

输出尺寸

output_shape 参数指定 (或者在使用 TensorFlow 时,自动推理得到)。


1.4.2.10 ActivityRegularization

1
keras.layers.ActivityRegularization(l1=0.0, l2=0.0)

网络层,对基于代价函数的输入活动应用一个更新。

参数

  • l1: L1 正则化因子 (正数浮点型)。
  • l2: L2 正则化因子 (正数浮点型)。

输入尺寸

任意。当使用此层作为模型中的第一层时, 使用参数 input_shape (整数元组,不包括样本数的轴)。

输出尺寸

与输入相同。


1.4.2.11 Masking

1
keras.layers.Masking(mask_value=0.0)

使用覆盖值覆盖序列,以跳过时间步。

对于输入张量的每一个时间步(张量的第一个维度), 如果所有时间步中输入张量的值与 mask_value 相等, 那么这个时间步将在所有下游层被覆盖 (跳过) (只要它们支持覆盖)。

如果任何下游层不支持覆盖但仍然收到此类输入覆盖信息,会引发异常。

示例

考虑将要喂入一个 LSTM 层的 Numpy 矩阵 x, 尺寸为 (samples, timesteps, features)。 你想要覆盖时间步 #3 和 #5,因为你缺乏这几个 时间步的数据。你可以:

  • 设置 x[:, 3, :] = 0. 以及 x[:, 5, :] = 0.
  • 在 LSTM 层之前,插入一个 mask_value=0Masking 层:
1
2
3
model = Sequential()
model.add(Masking(mask_value=0., input_shape=(timesteps, features)))
model.add(LSTM(32))

1.4.2.12 SpatialDropout1D

1
keras.layers.SpatialDropout1D(rate)

Dropout 的 Spatial 1D 版本

此版本的功能与 Dropout 相同,但它会丢弃整个 1D 的特征图而不是丢弃单个元素。如果特征图中相邻的帧是强相关的(通常是靠前的卷积层中的情况),那么常规的 dropout 将无法使激活正则化,且导致有效的学习速率降低。在这种情况下,SpatialDropout1D 将有助于提高特征图之间的独立性,应该使用它来代替 Dropout。

参数

  • rate: 0 到 1 之间的浮点数。需要丢弃的输入比例。

输入尺寸

3D 张量,尺寸为:(samples, timesteps, channels)

输出尺寸

与输入相同。


1.4.2.13 SpatialDropout2D

1
keras.layers.SpatialDropout2D(rate, data_format=None)

Dropout 的 Spatial 2D 版本

此版本的功能与 Dropout 相同,但它会丢弃整个 2D 的特征图而不是丢弃单个元素。如果特征图中相邻的像素是强相关的(通常是靠前的卷积层中的情况),那么常规的 dropout 将无法使激活正则化,且导致有效的学习速率降低。在这种情况下,SpatialDropout2D 将有助于提高特征图之间的独立性,应该使用它来代替 dropout。

参数

  • rate: 0 到 1 之间的浮点数。需要丢弃的输入比例。
  • data_formatchannels_first 或者 channels_last。在 channels_first 模式中,通道维度(即深度)位于索引 1,在 channels_last 模式中,通道维度位于索引 3。默认为 image_data_format 的值,你可以在 Keras 的配置文件 ~/.keras/keras.json 中找到它。如果你从未设置过它,那么它将是 channels_last

输入尺寸

4D 张量,如果 data_format=channels_first,尺寸为 (samples, channels, rows, cols),如果 data_format=channels_last,尺寸为 (samples, rows, cols, channels)

输出尺寸

与输入相同。


1.4.2.14 SpatialDropout3D

1
keras.layers.SpatialDropout3D(rate, data_format=None)

Dropout 的 Spatial 3D 版本

此版本的功能与 Dropout 相同,但它会丢弃整个 3D 的特征图而不是丢弃单个元素。如果特征图中相邻的体素是强相关的(通常是靠前的卷积层中的情况),那么常规的 dropout 将无法使激活正则化,且导致有效的学习速率降低。在这种情况下,SpatialDropout3D 将有助于提高特征图之间的独立性,应该使用它来代替 dropout。

参数

  • rate: 0 到 1 之间的浮点数。需要丢弃的输入比例。
  • data_formatchannels_first 或者 channels_last。在 channels_first 模式中,通道维度(即深度)位于索引 1,在 channels_last 模式中,通道维度位于索引 4。默认为 image_data_format 的值,你可以在 Keras 的配置文件 ~/.keras/keras.json 中找到它。如果你从未设置过它,那么它将是 channels_last

输入尺寸

5D 张量,如果 data_format=channels_first,尺寸为 (samples, channels, dim1, dim2, dim3),如果 data_format=channels_last,尺寸为 (samples, dim1, dim2, dim3, channels)

输出尺寸

与输入相同。

1.4.3 卷积层 Convolutional Layers

1.4.3.1 Conv1D

1
keras.layers.Conv1D(filters, kernel_size, strides=1, padding='valid', data_format='channels_last', dilation_rate=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)

1D 卷积层 (例如时序卷积)。

该层创建了一个卷积核,该卷积核以 单个空间(或时间)维上的层输入进行卷积, 以生成输出张量。 如果 use_bias 为 True, 则会创建一个偏置向量并将其添加到输出中。 最后,如果 activation 不是 None,它也会应用于输出。

当使用该层作为模型第一层时,需要提供 input_shape 参数(整数元组或 None,不包含 batch 轴), 例如,input_shape=(10, 128)data_format="channels_last" 时表示 10 个 128 维的向量组成的向量序列, (None, 128) 表示每步 128 维的向量组成的变长序列。

参数

  • filters: 整数,输出空间的维度 (即卷积中滤波器的输出数量)。
  • kernel_size: 一个整数,或者单个整数表示的元组或列表, 指明 1D 卷积窗口的长度。
  • strides: 一个整数,或者单个整数表示的元组或列表, 指明卷积的步长。 指定任何 stride 值 != 1 与指定 dilation_rate 值 != 1 两者不兼容。
  • padding: "valid", "causal""same" 之一 (大小写敏感) "valid" 表示「不填充」。 "same" 表示填充输入以使输出具有与原始输入相同的长度。 "causal" 表示因果(膨胀)卷积, 例如,output[t] 不依赖于 input[t+1:], 在模型不应违反时间顺序的时间数据建模时非常有用。 详见 WaveNet: A Generative Model for Raw Audio, section 2.1
  • data_format: 字符串, "channels_last" (默认) 或 "channels_first" 之一。输入的各个维度顺序。 "channels_last" 对应输入尺寸为 (batch, steps, channels) (Keras 中时序数据的默认格式) 而 "channels_first" 对应输入尺寸为 (batch, channels, steps)
  • dilation_rate: 一个整数,或者单个整数表示的元组或列表,指定用于膨胀卷积的膨胀率。 当前,指定任何 dilation_rate 值 != 1 与指定 stride 值 != 1 两者不兼容。
  • activation: 要使用的激活函数 (详见 activations)。 如未指定,则不使用激活函数 (即线性激活: a(x) = x)。
  • use_bias: 布尔值,该层是否使用偏置向量。
  • kernel_initializer: kernel 权值矩阵的初始化器 (详见 initializers)。
  • bias_initializer: 偏置向量的初始化器 (详见 initializers)。
  • kernel_regularizer: 运用到 kernel 权值矩阵的正则化函数 (详见 regularizer)。
  • bias_regularizer: 运用到偏置向量的正则化函数 (详见 regularizer)。
  • activity_regularizer: 运用到层输出(它的激活值)的正则化函数 (详见 regularizer)。
  • kernel_constraint: 运用到 kernel 权值矩阵的约束函数 (详见 constraints)。
  • bias_constraint: 运用到偏置向量的约束函数 (详见 constraints)。

输入尺寸

3D 张量 ,尺寸为 (batch_size, steps, input_dim)

输出尺寸

3D 张量,尺寸为 (batch_size, new_steps, filters)。 由于填充或窗口按步长滑动,steps 值可能已更改。


1.4.3.2 Conv2D

1
keras.layers.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)

2D 卷积层 (例如对图像的空间卷积)。

该层创建了一个卷积核, 该卷积核对层输入进行卷积, 以生成输出张量。 如果 use_bias 为 True, 则会创建一个偏置向量并将其添加到输出中。 最后,如果 activation 不是 None,它也会应用于输出。

当使用该层作为模型第一层时,需要提供 input_shape 参数 (整数元组,不包含 batch 轴),例如, input_shape=(128, 128, 3) 表示 128x128 RGB 图像, 在 data_format="channels_last" 时。

参数

  • filters: 整数,输出空间的维度 (即卷积中滤波器的输出数量)。
  • kernel_size: 一个整数,或者 2 个整数表示的元组或列表, 指明 2D 卷积窗口的宽度和高度。 可以是一个整数,为所有空间维度指定相同的值。
  • strides: 一个整数,或者 2 个整数表示的元组或列表, 指明卷积沿宽度和高度方向的步长。 可以是一个整数,为所有空间维度指定相同的值。 指定任何 stride 值 != 1 与指定 dilation_rate 值 != 1 两者不兼容。
  • padding: "valid""same" (大小写敏感)。
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一,表示输入中维度的顺序。 channels_last 对应输入尺寸为 (batch, height, width, channels)channels_first 对应输入尺寸为 (batch, channels, height, width)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用 channels_last
  • dilation_rate: 一个整数或 2 个整数的元组或列表, 指定膨胀卷积的膨胀率。 可以是一个整数,为所有空间维度指定相同的值。 当前,指定任何 dilation_rate 值 != 1 与 指定 stride 值 != 1 两者不兼容。
  • activation: 要使用的激活函数 (详见 activations)。 如果你不指定,则不使用激活函数 (即线性激活: a(x) = x)。
  • use_bias: 布尔值,该层是否使用偏置向量。
  • kernel_initializer: kernel 权值矩阵的初始化器 (详见 initializers)。
  • bias_initializer: 偏置向量的初始化器 (详见 initializers)。
  • kernel_regularizer: 运用到 kernel 权值矩阵的正则化函数 (详见 regularizer)。
  • bias_regularizer: 运用到偏置向量的正则化函数 (详见 regularizer)。
  • activity_regularizer: 运用到层输出(它的激活值)的正则化函数 (详见 regularizer)。
  • kernel_constraint: 运用到 kernel 权值矩阵的约束函数 (详见 constraints)。
  • bias_constraint: 运用到偏置向量的约束函数 (详见 constraints)。

输入尺寸

  • 如果 data_format=’channels_first’, 输入 4D 张量,尺寸为 (samples, channels, rows, cols)
  • 如果 data_format=’channels_last’, 输入 4D 张量,尺寸为 (samples, rows, cols, channels)

输出尺寸

  • 如果 data_format=’channels_first’, 输出 4D 张量,尺寸为 (samples, filters, new_rows, new_cols)
  • 如果 data_format=’channels_last’, 输出 4D 张量,尺寸为 (samples, new_rows, new_cols, filters)

由于填充的原因,rowscols 值可能已更改。


1.4.3.3 SeparableConv1D

1
keras.layers.SeparableConv1D(filters, kernel_size, strides=1, padding='valid', data_format='channels_last', dilation_rate=1, depth_multiplier=1, activation=None, use_bias=True, depthwise_initializer='glorot_uniform', pointwise_initializer='glorot_uniform', bias_initializer='zeros', depthwise_regularizer=None, pointwise_regularizer=None, bias_regularizer=None, activity_regularizer=None, depthwise_constraint=None, pointwise_constraint=None, bias_constraint=None)

深度方向的可分离 1D 卷积。

可分离的卷积的操作包括,首先执行深度方向的空间卷积 (分别作用于每个输入通道),紧接一个将所得输出通道 混合在一起的逐点卷积。depth_multiplier 参数控 制深度步骤中每个输入通道生成多少个输出通道。

直观地说,可分离的卷积可以理解为一种将卷积核分解成 两个较小的卷积核的方法,或者作为 Inception 块的 一个极端版本。

参数

  • filters: 整数,输出空间的维度 (即卷积中滤波器的输出数量)。
  • kernel_size: 一个整数,或者单个整数表示的元组或列表, 指明 1D 卷积窗口的长度。
  • strides: 一个整数,或者单个整数表示的元组或列表, 指明卷积的步长。 指定任何 stride 值 != 1 与指定 dilation_rate 值 != 1 两者不兼容。
  • padding: "valid""same" (大小写敏感)。
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一,表示输入中维度的顺序。 channels_last 对应输入尺寸为 (batch, height, width, channels)channels_first 对应输入尺寸为 (batch, channels, height, width)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用「channels_last」。
  • dilation_rate: 一个整数,或者单个整数表示的元组或列表, 为使用扩张(空洞)卷积指明扩张率。 目前,指定任何 dilation_rate 值 != 1 与指定任何 stride 值 != 1 两者不兼容。
  • depth_multiplier: 每个输入通道的深度方向卷积输出通道的数量。 深度方向卷积输出通道的总数将等于 filterss_in * depth_multiplier
  • activation: 要使用的激活函数 (详见 activations)。 如果你不指定,则不使用激活函数 (即线性激活: a(x) = x)。
  • use_bias: 布尔值,该层是否使用偏置向量。
  • depthwise_initializer: 运用到深度方向的核矩阵的初始化器 (详见 initializers)。
  • pointwise_initializer: 运用到逐点核矩阵的初始化器 (详见 initializers)。
  • bias_initializer: 偏置向量的初始化器 (详见 initializers)。
  • depthwise_regularizer: 运用到深度方向的核矩阵的正则化函数 (详见 regularizer)。
  • pointwise_regularizer: 运用到逐点核矩阵的正则化函数 (详见 regularizer)。
  • bias_regularizer: 运用到偏置向量的正则化函数 (详见 regularizer)。
  • activity_regularizer: 运用到层输出(它的激活值)的正则化函数 (详见 regularizer)。
  • depthwise_constraint: 运用到深度方向的核矩阵的约束函数 (详见 constraints)。
  • pointwise_constraint: 运用到逐点核矩阵的约束函数 (详见 constraints)。
  • bias_constraint: 运用到偏置向量的约束函数 (详见 constraints)。

输入尺寸

  • 如果 data_format=’channels_first’, 输入 3D 张量,尺寸为 (batch, channels, steps)
  • 如果 data_format=’channels_last’, 输入 3D 张量,尺寸为 (batch, steps, channels)

输出尺寸

  • 如果 data_format=’channels_first’, 输出 3D 张量,尺寸为 (batch, filters, new_steps)
  • 如果 data_format=’channels_last’, 输出 3D 张量,尺寸为 (batch, new_steps, filters)

由于填充的原因,new_steps 值可能已更改。


1.4.3.4 SeparableConv2D

1
keras.layers.SeparableConv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), depth_multiplier=1, activation=None, use_bias=True, depthwise_initializer='glorot_uniform', pointwise_initializer='glorot_uniform', bias_initializer='zeros', depthwise_regularizer=None, pointwise_regularizer=None, bias_regularizer=None, activity_regularizer=None, depthwise_constraint=None, pointwise_constraint=None, bias_constraint=None)

深度方向的可分离 2D 卷积。

可分离的卷积的操作首先执行深度方向的空间卷积 (分别作用于每个输入通道),紧接一个将所得输出通道 混合在一起的逐点卷积。depth_multiplier 参数控 制深度步骤中每个输入通道生成多少个输出通道。

直观地说,可分离的卷积可以理解为一种将卷积核分解成 两个较小的卷积核的方法,或者作为 Inception 块的 一个极端版本。

参数

  • filters: 整数,输出空间的维度 (即卷积中滤波器的输出数量)。
  • kernel_size: 一个整数,或者 2 个整数表示的元组或列表, 指明 2D 卷积窗口的高度和宽度。 可以是一个整数,为所有空间维度指定相同的值。
  • strides: 一个整数,或者 2 个整数表示的元组或列表, 指明卷积沿高度和宽度方向的步长。 可以是一个整数,为所有空间维度指定相同的值。 指定任何 stride 值 != 1 与指定 dilation_rate 值 != 1 两者不兼容。
  • padding: "valid""same" (大小写敏感)。
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一,表示输入中维度的顺序。 channels_last 对应输入尺寸为 (batch, height, width, channels)channels_first 对应输入尺寸为 (batch, channels, height, width)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用「channels_last」。
  • dilation_rate: 一个整数,或者 2 个整数表示的元组或列表, 为使用扩张(空洞)卷积指明扩张率。 目前,指定任何 dilation_rate 值 != 1 与指定任何 stride 值 != 1 两者不兼容。
  • depth_multiplier: 每个输入通道的深度方向卷积输出通道的数量。 深度方向卷积输出通道的总数将等于 filterss_in * depth_multiplier
  • activation: 要使用的激活函数 (详见 activations)。 如果你不指定,则不使用激活函数 (即线性激活: a(x) = x)。
  • use_bias: 布尔值,该层是否使用偏置向量。
  • depthwise_initializer: 运用到深度方向的核矩阵的初始化器 详见 initializers)。
  • pointwise_initializer: 运用到逐点核矩阵的初始化器 (详见 initializers)。
  • bias_initializer: 偏置向量的初始化器 (详见 initializers)。
  • depthwise_regularizer: 运用到深度方向的核矩阵的正则化函数 (详见 regularizer)。
  • pointwise_regularizer: 运用到逐点核矩阵的正则化函数 (详见 regularizer)。
  • bias_regularizer: 运用到偏置向量的正则化函数 (详见 regularizer)。
  • activity_regularizer: 运用到层输出(它的激活值)的正则化函数 (详见 regularizer)。
  • depthwise_constraint: 运用到深度方向的核矩阵的约束函数 (详见 constraints)。
  • pointwise_constraint: 运用到逐点核矩阵的约束函数 (详见 constraints)。
  • bias_constraint: 运用到偏置向量的约束函数 (详见 constraints)。

输入尺寸

  • 如果 data_format=’channels_first’, 输入 4D 张量,尺寸为 (batch, channels, rows, cols)
  • 如果 data_format=’channels_last’, 输入 4D 张量,尺寸为 (batch, rows, cols, channels)

输出尺寸

  • 如果 data_format=’channels_first’, 输出 4D 张量,尺寸为 (batch, filters, new_rows, new_cols)
  • 如果 data_format=’channels_last’, 输出 4D 张量,尺寸为 (batch, new_rows, new_cols, filters)

由于填充的原因,rowscols 值可能已更改。


1.4.3.5 DepthwiseConv2D

1
keras.layers.DepthwiseConv2D(kernel_size, strides=(1, 1), padding='valid', depth_multiplier=1, data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, depthwise_initializer='glorot_uniform', bias_initializer='zeros', depthwise_regularizer=None, bias_regularizer=None, activity_regularizer=None, depthwise_constraint=None, bias_constraint=None)

深度 2D 卷积。

深度卷积仅执行深度空间卷积中的第一步(其分别作用于每个输入通道)。 depth_multiplier 参数控制深度步骤中每个输入通道生成多少个输出通道。

参数

  • kernel_size: 一个整数,或者 2 个整数表示的元组或列表, 指明 2D 卷积窗口的高度和宽度。 可以是一个整数,为所有空间维度指定相同的值。
  • strides: 一个整数,或者 2 个整数表示的元组或列表, 指明卷积沿高度和宽度方向的步长。 可以是一个整数,为所有空间维度指定相同的值。 指定任何 stride 值 != 1 与指定 dilation_rate 值 != 1 两者不兼容。
  • padding: "valid""same" (大小写敏感)。
  • depth_multiplier: 每个输入通道的深度方向卷积输出通道的数量。 深度方向卷积输出通道的总数将等于 filterss_in * depth_multiplier
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一,表示输入中维度的顺序。 channels_last 对应输入尺寸为 (batch, height, width, channels)channels_first 对应输入尺寸为 (batch, channels, height, width)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用「channels_last」。
  • dilation_rate: 一个整数,或者 2 个整数表示的元组或列表, 为使用扩张(空洞)卷积指明扩张率。 目前,指定任何 dilation_rate 值 != 1 与指定任何 stride 值 != 1 两者不兼容。
  • activation: 要使用的激活函数 (详见 activations)。 如果你不指定,则不使用激活函数 (即线性激活: a(x) = x)。
  • use_bias: 布尔值,该层是否使用偏置向量。
  • depthwise_initializer: 运用到深度方向的核矩阵的初始化器 详见 initializers)。
  • bias_initializer: 偏置向量的初始化器 (详见 initializers)。
  • depthwise_regularizer: 运用到深度方向的核矩阵的正则化函数 (详见 regularizer)。
  • bias_regularizer: 运用到偏置向量的正则化函数 (详见 regularizer)。
  • activity_regularizer: 运用到层输出(它的激活值)的正则化函数 (详见 regularizer)。
  • depthwise_constraint: 运用到深度方向的核矩阵的约束函数 (详见 constraints)。
  • bias_constraint: 运用到偏置向量的约束函数 (详见 constraints)。

输入尺寸

  • 如果 data_format=’channels_first’, 输入 4D 张量,尺寸为 (batch, channels, rows, cols)
  • 如果 data_format=’channels_last’, 输入 4D 张量,尺寸为 (batch, rows, cols, channels)

输出尺寸

  • 如果 data_format=’channels_first’, 输出 4D 张量,尺寸为 (batch, channels * depth_multiplier, new_rows, new_cols)
  • 如果 data_format=’channels_last’, 输出 4D 张量,尺寸为 (batch, new_rows, new_cols, channels * depth_multiplier)

由于填充的原因,rowscols 值可能已更改。


1.4.3.6 Conv2DTranspose

1
keras.layers.Conv2DTranspose(filters, kernel_size, strides=(1, 1), padding='valid', output_padding=None, data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)

转置卷积层 (有时被成为反卷积)。

对转置卷积的需求一般来自希望使用 与正常卷积相反方向的变换, 即,将具有卷积输出尺寸的东西 转换为具有卷积输入尺寸的东西, 同时保持与所述卷积相容的连通性模式。

当使用该层作为模型第一层时,需要提供 input_shape 参数 (整数元组,不包含 batch 轴),例如, input_shape=(128, 128, 3) 表示 128x128 RGB 图像, 在 data_format="channels_last" 时。

参数

  • filters: 整数,输出空间的维度 (即卷积中滤波器的输出数量)。
  • kernel_size: 一个整数,或者 2 个整数表示的元组或列表, 指明 2D 卷积窗口的高度和宽度。 可以是一个整数,为所有空间维度指定相同的值。
  • strides: 一个整数,或者 2 个整数表示的元组或列表, 指明卷积沿高度和宽度方向的步长。 可以是一个整数,为所有空间维度指定相同的值。 指定任何 stride 值 != 1 与指定 dilation_rate 值 != 1 两者不兼容。
  • padding: "valid""same" (大小写敏感)。
  • output_padding: 一个整数,或者 2 个整数表示的元组或列表, 指定沿输出张量的高度和宽度的填充量。 可以是单个整数,以指定所有空间维度的相同值。 沿给定维度的输出填充量必须低于沿同一维度的步长。 如果设置为 None (默认), 输出尺寸将自动推理出来。
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一,表示输入中维度的顺序。 channels_last 对应输入尺寸为 (batch, height, width, channels)channels_first 对应输入尺寸为 (batch, channels, height, width)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用 “channels_last”。
  • dilation_rate: 一个整数或 2 个整数的元组或列表, 指定膨胀卷积的膨胀率。 可以是一个整数,为所有空间维度指定相同的值。 当前,指定任何 dilation_rate 值 != 1 与 指定 stride 值 != 1 两者不兼容。
  • activation: 要使用的激活函数 (详见 activations)。 如果你不指定,则不使用激活函数 (即线性激活: a(x) = x)。
  • use_bias: 布尔值,该层是否使用偏置向量。
  • kernel_initializer: kernel 权值矩阵的初始化器 (详见 initializers)。
  • bias_initializer: 偏置向量的初始化器 (详见 initializers)。
  • kernel_regularizer: 运用到 kernel 权值矩阵的正则化函数 (详见 regularizer)。
  • bias_regularizer: 运用到偏置向量的正则化函数 (详见 regularizer)。
  • activity_regularizer: 运用到层输出(它的激活值)的正则化函数 (详见 regularizer)。
  • kernel_constraint: 运用到 kernel 权值矩阵的约束函数 (详见 constraints)。
  • bias_constraint: 运用到偏置向量的约束函数 (详见 constraints)。

输入尺寸

  • 如果 data_format=’channels_first’, 输入 4D 张量,尺寸为 (batch, channels, rows, cols)
  • 如果 data_format=’channels_last’, 输入 4D 张量,尺寸为 (batch, rows, cols, channels)

输出尺寸

  • 如果 data_format=’channels_first’, 输出 4D 张量,尺寸为 (batch, filters, new_rows, new_cols)
  • 如果 data_format=’channels_last’, 输出 4D 张量,尺寸为 (batch, new_rows, new_cols, filters)

由于填充的原因,rowscols 值可能已更改。

如果指定了 output_padding:

1
2
3
4
new_rows = ((rows - 1) * strides[0] + kernel_size[0]
- 2 * padding[0] + output_padding[0])
new_cols = ((cols - 1) * strides[1] + kernel_size[1]
- 2 * padding[1] + output_padding[1])

1.4.3.7 Conv3D

1
keras.layers.Conv3D(filters, kernel_size, strides=(1, 1, 1), padding='valid', data_format=None, dilation_rate=(1, 1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)

3D 卷积层 (例如立体空间卷积)。

该层创建了一个卷积核, 该卷积核对层输入进行卷积, 以生成输出张量。 如果 use_bias 为 True, 则会创建一个偏置向量并将其添加到输出中。 最后,如果 activation 不是 None,它也会应用于输出。

当使用该层作为模型第一层时,需要提供 input_shape 参数 (整数元组,不包含 batch 轴),例如, input_shape=(128, 128, 128, 1) 表示 128x128x128 的单通道立体, 在 data_format="channels_last" 时。

参数

  • filters: 整数,输出空间的维度 (即卷积中滤波器的输出数量)。
  • kernel_size: 一个整数,或者 3 个整数表示的元组或列表, 指明 3D 卷积窗口的深度、高度和宽度。 可以是一个整数,为所有空间维度指定相同的值。
  • strides: 一个整数,或者 3 个整数表示的元组或列表, 指明卷积沿每一个空间维度的步长。 可以是一个整数,为所有空间维度指定相同的步长值。 指定任何 stride 值 != 1 与指定 dilation_rate 值 != 1 两者不兼容。
  • padding: "valid""same" (大小写敏感)。
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一, 表示输入中维度的顺序。channels_last 对应输入尺寸为 (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)channels_first 对应输入尺寸为 (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用 “channels_last”。
  • dilation_rate: 一个整数或 3 个整数的元组或列表, 指定膨胀卷积的膨胀率。 可以是一个整数,为所有空间维度指定相同的值。 当前,指定任何 dilation_rate 值 != 1 与 指定 stride 值 != 1 两者不兼容。
  • activation: 要使用的激活函数 (详见 activations)。 如果你不指定,则不使用激活函数 (即线性激活: a(x) = x)。
  • use_bias: 布尔值,该层是否使用偏置向量。
  • kernel_initializer: kernel 权值矩阵的初始化器 (详见 initializers)。
  • bias_initializer: 偏置向量的初始化器 (详见 initializers)。
  • kernel_regularizer: 运用到 kernel 权值矩阵的正则化函数 (详见 regularizer)。
  • bias_regularizer: 运用到偏置向量的正则化函数 (详见 regularizer)。
  • activity_regularizer: 运用到层输出(它的激活值)的正则化函数 (详见 regularizer)。
  • kernel_constraint: 运用到 kernel 权值矩阵的约束函数 (详见 constraints)。
  • bias_constraint: 运用到偏置向量的约束函数 (详见 constraints)。

输入尺寸

  • 如果 data_format=’channels_first’, 输入 5D 张量,尺寸为 (samples, channels, conv_dim1, conv_dim2, conv_dim3)
  • 如果 data_format=’channels_last’, 输入 5D 张量,尺寸为 (samples, conv_dim1, conv_dim2, conv_dim3, channels)

输出尺寸

  • 如果 data_format=’channels_first’, 输出 5D 张量,尺寸为 (samples, filters, new_conv_dim1, new_conv_dim2, new_conv_dim3)
  • 如果 data_format=’channels_last’, 输出 5D 张量,尺寸为 (samples, new_conv_dim1, new_conv_dim2, new_conv_dim3, filters)

由于填充的原因,new_conv_dim1, new_conv_dim2new_conv_dim3 值可能已更改。


1.4.3.8 Conv3DTranspose

1
keras.layers.Conv3DTranspose(filters, kernel_size, strides=(1, 1, 1), padding='valid', output_padding=None, data_format=None, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)

转置卷积层 (有时被成为反卷积)。

对转置卷积的需求一般来自希望使用 与正常卷积相反方向的变换, 即,将具有卷积输出尺寸的东西 转换为具有卷积输入尺寸的东西, 同时保持与所述卷积相容的连通性模式。

当使用该层作为模型第一层时,需要提供 input_shape 参数 (整数元组,不包含样本表示的轴),例如, input_shape=(128, 128, 128, 3) 表示尺寸 128x128x128 的 3 通道立体, 在 data_format="channels_last" 时。

参数

  • filters: 整数,输出空间的维度 (即卷积中滤波器的输出数量)。
  • kernel_size: 一个整数,或者 3 个整数表示的元组或列表, 指明 3D 卷积窗口的深度、高度和宽度。 可以是一个整数,为所有空间维度指定相同的值。
  • strides: 一个整数,或者 3 个整数表示的元组或列表, 指明沿深度、高度和宽度方向的步长。 可以是一个整数,为所有空间维度指定相同的值。 指定任何 stride 值 != 1 与指定 dilation_rate 值 != 1 两者不兼容。
  • padding: "valid""same" (大小写敏感)。
  • output_padding: 一个整数,或者 3 个整数表示的元组或列表, 指定沿输出张量的高度和宽度的填充量。 可以是单个整数,以指定所有空间维度的相同值。 沿给定维度的输出填充量必须低于沿同一维度的步长。 如果设置为 None (默认), 输出尺寸将自动推理出来。
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一,表示输入中维度的顺序。 channels_last 对应输入尺寸为 (batch, depth, height, width, channels)channels_first 对应输入尺寸为 (batch, channels, depth, height, width)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用「channels_last」。
  • dilation_rate: 一个整数或 3 个整数的元组或列表, 指定膨胀卷积的膨胀率。 可以是一个整数,为所有空间维度指定相同的值。 当前,指定任何 dilation_rate 值 != 1 与 指定 stride 值 != 1 两者不兼容。
  • activation: 要使用的激活函数 (详见 activations)。 如果你不指定,则不使用激活函数 (即线性激活: a(x) = x)。
  • use_bias: 布尔值,该层是否使用偏置向量。
  • kernel_initializer: kernel 权值矩阵的初始化器 (详见 initializers)。
  • bias_initializer: 偏置向量的初始化器 (详见 initializers)。
  • kernel_regularizer: 运用到 kernel 权值矩阵的正则化函数 (详见 regularizer)。
  • bias_regularizer: 运用到偏置向量的正则化函数 (详见 regularizer)。
  • activity_regularizer: 运用到层输出(它的激活值)的正则化函数 (详见 regularizer)。
  • kernel_constraint: 运用到 kernel 权值矩阵的约束函数 (详见 constraints)。
  • bias_constraint: 运用到偏置向量的约束函数 (详见 constraints)。

输入尺寸

如果 data_format=’channels_first’, 输入 5D 张量,尺寸为 (batch, channels, depth, rows, cols), 如果 data_format=’channels_last’, 输入 5D 张量,尺寸为 (batch, depth, rows, cols, channels)

Output shape

如果 data_format=’channels_first’, 输出 5D 张量,尺寸为 (batch, filters, new_depth, new_rows, new_cols), 如果 data_format=’channels_last’, 输出 5D 张量,尺寸为 (batch, new_depth, new_rows, new_cols, filters)

depthrowscols 可能因为填充而改变。 如果指定了 output_padding

1
2
3
4
5
6
new_depth = ((depth - 1) * strides[0] + kernel_size[0]
- 2 * padding[0] + output_padding[0])
new_rows = ((rows - 1) * strides[1] + kernel_size[1]
- 2 * padding[1] + output_padding[1])
new_cols = ((cols - 1) * strides[2] + kernel_size[2]
- 2 * padding[2] + output_padding[2])

1.4.3.9 Cropping1D

1
keras.layers.Cropping1D(cropping=(1, 1))

1D 输入的裁剪层(例如时间序列)。

它沿着时间维度(第 1 个轴)裁剪。

参数

  • cropping: 整数或整数元组(长度为 2)。 在裁剪维度(第 1 个轴)的开始和结束位置 应该裁剪多少个单位。 如果只提供了一个整数,那么这两个位置将使用 相同的值。

输入尺寸

3D 张量,尺寸为 (batch, axis_to_crop, features)

输出尺寸

3D 张量,尺寸为 (batch, cropped_axis, features)


1.4.3.10 Cropping2D

1
keras.layers.Cropping2D(cropping=((0, 0), (0, 0)), data_format=None)

2D 输入的裁剪层(例如图像)。

它沿着空间维度裁剪,即宽度和高度。

参数

  • cropping

    : 整数,或 2 个整数的元组,或 2 个整数的 2 个元组。

    • 如果为整数: 将对宽度和高度应用相同的对称裁剪。
    • 如果为 2 个整数的元组: 解释为对高度和宽度的两个不同的对称裁剪值: (symmetric_height_crop, symmetric_width_crop)
    • 如果为 2 个整数的 2 个元组: 解释为 ((top_crop, bottom_crop), (left_crop, right_crop))
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一, 表示输入中维度的顺序。channels_last 对应输入尺寸为 (batch, height, width, channels)channels_first 对应输入尺寸为 (batch, channels, height, width)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用 “channels_last”。

输出尺寸

  • 如果 data_format=’channels_last’, 输出 4D 张量,尺寸为 (batch, rows, cols, channels)
  • 如果 data_format=’channels_first’, 输出 4D 张量,尺寸为 (batch, channels, rows, cols)

由于填充的原因,rowscols 值可能已更改。

输入尺寸

  • 如果 data_format"channels_last", 输入 4D 张量,尺寸为 (batch, cropped_rows, cropped_cols, channels)
  • 如果 data_format"channels_first", 输入 4D 张量,尺寸为 (batch, channels, cropped_rows, cropped_cols)

输出尺寸

  • 如果 data_format"channels_last", 输出 4D 张量,尺寸为 (batch, cropped_rows, cropped_cols, channels)
  • 如果 data_format"channels_first", 输出 4D 张量,尺寸为 (batch, channels, cropped_rows, cropped_cols)

示例

1
2
3
4
5
6
7
8
# 裁剪输入的 2D 图像或特征图
model = Sequential()
model.add(Cropping2D(cropping=((2, 2), (4, 4)),
input_shape=(28, 28, 3)))
# 现在 model.output_shape == (None, 24, 20, 3)
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Cropping2D(cropping=((2, 2), (2, 2))))
# 现在 model.output_shape == (None, 20, 16. 64)

1.4.3.11 Cropping3D

1
keras.layers.Cropping3D(cropping=((1, 1), (1, 1), (1, 1)), data_format=None)

3D 数据的裁剪层(例如空间或时空)。

参数

  • cropping

    : 整数,或 3 个整数的元组,或 2 个整数的 3 个元组。

    • 如果为整数: 将对深度、高度和宽度应用相同的对称裁剪。
    • 如果为 3 个整数的元组: 解释为对深度、高度和高度的 3 个不同的对称裁剪值: (symmetric_dim1_crop, symmetric_dim2_crop, symmetric_dim3_crop)
    • 如果为 2 个整数的 3 个元组: 解释为 ((left_dim1_crop, right_dim1_crop), (left_dim2_crop, right_dim2_crop), (left_dim3_crop, right_dim3_crop))
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一, 表示输入中维度的顺序。channels_last 对应输入尺寸为 (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)channels_first 对应输入尺寸为 (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用 “channels_last”。

输入尺寸

5D 张量,尺寸为:

  • 如果 data_format"channels_last": (batch, first_cropped_axis, second_cropped_axis, third_cropped_axis, depth)
  • 如果 data_format"channels_first": (batch, depth, first_cropped_axis, second_cropped_axis, third_cropped_axis)

输出尺寸

5D 张量,尺寸为:

  • 如果 data_format"channels_last": (batch, first_cropped_axis, second_cropped_axis, third_cropped_axis, depth)
  • 如果 data_format"channels_first": (batch, depth, first_cropped_axis, second_cropped_axis, third_cropped_axis)

1.4.3.12 UpSampling1D

1
keras.layers.UpSampling1D(size=2)

1D 输入的上采样层。

沿着时间轴重复每个时间步 size 次。

参数

  • size: 整数。上采样因子。

输入尺寸

3D 张量,尺寸为 (batch, steps, features)

输出尺寸

3D 张量,尺寸为 (batch, upsampled_steps, features)


1.4.3.13 UpSampling2D

1
keras.layers.UpSampling2D(size=(2, 2), data_format=None, interpolation='nearest')

2D 输入的上采样层。

沿着数据的行和列分别重复 size[0]size[1] 次。

参数

  • size: 整数,或 2 个整数的元组。 行和列的上采样因子。
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一, 表示输入中维度的顺序。channels_last 对应输入尺寸为 (batch, height, width, channels)channels_first 对应输入尺寸为 (batch, channels, height, width)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用 “channels_last”。
  • interpolation: 字符串,nearestbilinear 之一。 注意 CNTK 暂不支持 bilinear upscaling, 以及对于 Theano,只可以使用 size=(2, 2)

输入尺寸

  • 如果 data_format"channels_last", 输入 4D 张量,尺寸为 (batch, rows, cols, channels)
  • 如果 data_format"channels_first", 输入 4D 张量,尺寸为 (batch, channels, rows, cols)

输出尺寸

  • 如果 data_format"channels_last", 输出 4D 张量,尺寸为 (batch, upsampled_rows, upsampled_cols, channels)
  • 如果 data_format"channels_first", 输出 4D 张量,尺寸为 (batch, channels, upsampled_rows, upsampled_cols)

1.4.3.14 UpSampling3D

1
keras.layers.UpSampling3D(size=(2, 2, 2), data_format=None)

3D 输入的上采样层。

沿着数据的第 1、2、3 维度分别重复 size[0]size[1]size[2] 次。

参数

  • size: 整数,或 3 个整数的元组。 dim1, dim2 和 dim3 的上采样因子。
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一, 表示输入中维度的顺序。channels_last 对应输入尺寸为 (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)channels_first 对应输入尺寸为 (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用 “channels_last”。

输入尺寸

  • 如果 data_format"channels_last", 输入 5D 张量,尺寸为 (batch, dim1, dim2, dim3, channels)
  • 如果 data_format"channels_first", 输入 5D 张量,尺寸为 (batch, channels, dim1, dim2, dim3)

输出尺寸

  • 如果 data_format"channels_last", 输出 5D 张量,尺寸为 (batch, upsampled_dim1, upsampled_dim2, upsampled_dim3, channels)
  • 如果 data_format"channels_first", 输出 5D 张量,尺寸为 (batch, channels, upsampled_dim1, upsampled_dim2, upsampled_dim3)

1.4.3.15 ZeroPadding1D

1
keras.layers.ZeroPadding1D(padding=1)

1D 输入的零填充层(例如,时间序列)。

参数

  • padding

    : 整数,或长度为 2 的整数元组,或字典。

    • 如果为整数: 在填充维度(第一个轴)的开始和结束处添加多少个零。
    • 如果是长度为 2 的整数元组: 在填充维度的开始和结尾处添加多少个零 ((left_pad, right_pad))。

输入尺寸

3D 张量,尺寸为 (batch, axis_to_pad, features)

输出尺寸

3D 张量,尺寸为 (batch, padded_axis, features)


1.4.3.16 ZeroPadding2D

1
keras.layers.ZeroPadding2D(padding=(1, 1), data_format=None)

2D 输入的零填充层(例如图像)。

该图层可以在图像张量的顶部、底部、左侧和右侧添加零表示的行和列。

参数

  • padding

    : 整数,或 2 个整数的元组,或 2 个整数的 2 个元组。

    • 如果为整数:将对宽度和高度运用相同的对称填充。
    • 如果为 2 个整数的元组:解释为高度和高度的 2 个不同的对称裁剪值: (symmetric_height_pad, symmetric_width_pad)
    • 如果为 2 个整数的 2 个元组: 解释为 ((top_pad, bottom_pad), (left_pad, right_pad))
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一, 表示输入中维度的顺序。channels_last 对应输入尺寸为 (batch, height, width, channels)channels_first 对应输入尺寸为 (batch, channels, height, width)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用 “channels_last”。

输入尺寸

  • 如果 data_format"channels_last", 输入 4D 张量,尺寸为 (batch, rows, cols, channels)
  • 如果 data_format"channels_first", 输入 4D 张量,尺寸为 (batch, channels, rows, cols)

输出尺寸

  • 如果 data_format"channels_last", 输出 4D 张量,尺寸为 (batch, padded_rows, padded_cols, channels)
  • 如果 data_format"channels_first", 输出 4D 张量,尺寸为 (batch, channels, padded_rows, padded_cols)

1.4.3.17 ZeroPadding3D

1
keras.layers.ZeroPadding3D(padding=(1, 1, 1), data_format=None)

3D 数据的零填充层(空间或时空)。

参数

  • padding

    : 整数,或 3 个整数的元组,或 2 个整数的 3 个元组。

    • 如果为整数:将对深度、高度和宽度运用相同的对称填充。
    • 如果为 3 个整数的元组: 解释为深度、高度和宽度的三个不同的对称填充值: (symmetric_dim1_pad, symmetric_dim2_pad, symmetric_dim3_pad).
    • 如果为 2 个整数的 3 个元组:解释为 ((left_dim1_pad, right_dim1_pad), (left_dim2_pad, right_dim2_pad), (left_dim3_pad, right_dim3_pad))
  • data_format: 字符串, channels_last (默认) 或 channels_first 之一, 表示输入中维度的顺序。channels_last 对应输入尺寸为 (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)channels_first 对应输入尺寸为 (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)。 它默认为从 Keras 配置文件 ~/.keras/keras.json 中 找到的 image_data_format 值。 如果你从未设置它,将使用 “channels_last”。

输入尺寸

5D 张量,尺寸为:

  • 如果 data_format"channels_last": (batch, first_axis_to_pad, second_axis_to_pad, third_axis_to_pad, depth)
  • 如果 data_format"channels_first": (batch, depth, first_axis_to_pad, second_axis_to_pad, third_axis_to_pad)

输出尺寸

5D 张量,尺寸为:

  • 如果 data_format"channels_last": (batch, first_padded_axis, second_padded_axis, third_axis_to_pad, depth)
  • 如果 data_format"channels_first": (batch, depth, first_padded_axis, second_padded_axis, third_axis_to_pad)

1.4.4 池化层 Pooling Layers

1.4.4.1 MaxPooling1D

1
keras.layers.MaxPooling1D(pool_size=2, strides=None, padding='valid', data_format='channels_last')

对于时序数据的最大池化。

参数

  • pool_size: 整数,最大池化的窗口大小。
  • strides: 整数,或者是 None。作为缩小比例的因数。
    例如,2 会使得输入张量缩小一半。
    如果是 None,那么默认值是 pool_size
  • padding: "valid" 或者 "same" (区分大小写)。
  • data_format: 字符串,channels_last (默认)或 channels_first 之一。
    表示输入各维度的顺序。
    channels_last 对应输入尺寸为 (batch, steps, features)
    channels_first 对应输入尺寸为 (batch, features, steps)

输入尺寸

  • 如果 data_format='channels_last'
    输入为 3D 张量,尺寸为:
    (batch_size, steps, features)
  • 如果data_format='channels_first'
    输入为 3D 张量,尺寸为:
    (batch_size, features, steps)

输出尺寸

  • 如果 data_format='channels_last'
    输出为 3D 张量,尺寸为:
    (batch_size, downsampled_steps, features)
  • 如果 data_format='channels_first'
    输出为 3D 张量,尺寸为:
    (batch_size, features, downsampled_steps)

1.4.4.2 MaxPooling2D

1
keras.layers.MaxPooling2D(pool_size=(2, 2), strides=None, padding='valid', data_format=None)

对于空间数据的最大池化。

参数

  • pool_size: 整数,或者 2 个整数表示的元组,
    沿(垂直,水平)方向缩小比例的因数。
    (2,2)会把输入张量的两个维度都缩小一半。
    如果只使用一个整数,那么两个维度都会使用同样的窗口长度。
  • strides: 整数,2 个整数表示的元组,或者是 None
    表示步长值。
    如果是 None,那么默认值是 pool_size
  • padding: "valid" 或者 "same" (区分大小写)。
  • data_format: 字符串,channels_last (默认)或 channels_first 之一。
    表示输入各维度的顺序。
    channels_last 代表尺寸是 (batch, height, width, channels) 的输入张量,
    channels_first 代表尺寸是 (batch, channels, height, width) 的输入张量。
    默认值根据 Keras 配置文件 ~/.keras/keras.json 中的 image_data_format 值来设置。
    如果还没有设置过,那么默认值就是 “channels_last”。

输入尺寸

  • 如果 data_format='channels_last':
    尺寸是 (batch_size, rows, cols, channels) 的 4D 张量
  • 如果 data_format='channels_first':
    尺寸是 (batch_size, channels, rows, cols) 的 4D 张量

输出尺寸

  • 如果 data_format='channels_last':
    尺寸是 (batch_size, pooled_rows, pooled_cols, channels) 的 4D 张量
  • 如果 data_format='channels_first':
    尺寸是 (batch_size, channels, pooled_rows, pooled_cols) 的 4D 张量

1.4.4.3 MaxPooling3D

1
keras.layers.MaxPooling3D(pool_size=(2, 2, 2), strides=None, padding='valid', data_format=None)

对于 3D(空间,或时空间)数据的最大池化。

参数

  • pool_size: 3 个整数表示的元组,缩小(dim1,dim2,dim3)比例的因数。
    (2, 2, 2) 会把 3D 输入张量的每个维度缩小一半。
  • strides: 3 个整数表示的元组,或者是 None。步长值。
  • padding: "valid" 或者 "same"(区分大小写)。
  • data_format: 字符串,channels_last (默认)或 channels_first 之一。
    表示输入各维度的顺序。
    channels_last 代表尺寸是 (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels) 的输入张量,
    channels_first 代表尺寸是 (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3) 的输入张量。
    默认值根据 Keras 配置文件 ~/.keras/keras.json 中的 image_data_format 值来设置。
    如果还没有设置过,那么默认值就是 “channels_last”。

输入尺寸

  • 如果 data_format='channels_last':
    尺寸是 (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) 的 5D 张量
  • 如果 data_format='channels_first':
    尺寸是 (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3) 的 5D 张量

输出尺寸

  • 如果 data_format='channels_last':
    尺寸是 (batch_size, pooled_dim1, pooled_dim2, pooled_dim3, channels) 的 5D 张量
  • 如果 data_format='channels_first':
    尺寸是 (batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3) 的 5D 张量

1.4.4.4 AveragePooling1D

1
keras.layers.AveragePooling1D(pool_size=2, strides=None, padding='valid', data_format='channels_last')

对于时序数据的平均池化。

参数

  • pool_size: 整数,平均池化的窗口大小。
  • strides: 整数,或者是 None。作为缩小比例的因数。
    例如,2 会使得输入张量缩小一半。
    如果是 None,那么默认值是 pool_size
  • padding: "valid" 或者 "same" (区分大小写)。
  • data_format: 字符串,channels_last (默认)或 channels_first 之一。
    表示输入各维度的顺序。
    channels_last 对应输入尺寸为 (batch, steps, features)
    channels_first 对应输入尺寸为 (batch, features, steps)

输入尺寸

  • 如果 data_format='channels_last'
    输入为 3D 张量,尺寸为:
    (batch_size, steps, features)
  • 如果data_format='channels_first'
    输入为 3D 张量,尺寸为:
    (batch_size, features, steps)

输出尺寸

  • 如果 data_format='channels_last'
    输出为 3D 张量,尺寸为:
    (batch_size, downsampled_steps, features)
  • 如果 data_format='channels_first'
    输出为 3D 张量,尺寸为:
    (batch_size, features, downsampled_steps)

1.4.4.5 AveragePooling2D

1
keras.layers.AveragePooling2D(pool_size=(2, 2), strides=None, padding='valid', data_format=None)

对于空间数据的平均池化。

参数

  • pool_size: 整数,或者 2 个整数表示的元组,
    沿(垂直,水平)方向缩小比例的因数。
    (2,2)会把输入张量的两个维度都缩小一半。
    如果只使用一个整数,那么两个维度都会使用同样的窗口长度。
  • strides: 整数,2 个整数表示的元组,或者是 None
    表示步长值。
    如果是 None,那么默认值是 pool_size
  • padding: "valid" 或者 "same" (区分大小写)。
  • data_format: 字符串,channels_last (默认)或 channels_first 之一。
    表示输入各维度的顺序。
    channels_last 代表尺寸是 (batch, height, width, channels) 的输入张量,
    channels_first 代表尺寸是 (batch, channels, height, width) 的输入张量。
    默认值根据 Keras 配置文件 ~/.keras/keras.json 中的 image_data_format 值来设置。
    如果还没有设置过,那么默认值就是 “channels_last”。

输入尺寸

  • 如果 data_format='channels_last':
    尺寸是 (batch_size, rows, cols, channels) 的 4D 张量
  • 如果 data_format='channels_first':
    尺寸是 (batch_size, channels, rows, cols) 的 4D 张量

输出尺寸

  • 如果 data_format='channels_last':
    尺寸是 (batch_size, pooled_rows, pooled_cols, channels) 的 4D 张量
  • 如果 data_format='channels_first':
    尺寸是 (batch_size, channels, pooled_rows, pooled_cols) 的 4D 张量

1.4.4.6 AveragePooling3D

1
keras.layers.AveragePooling3D(pool_size=(2, 2, 2), strides=None, padding='valid', data_format=None)

对于 3D (空间,或者时空间)数据的平均池化。

参数

  • pool_size: 3 个整数表示的元组,缩小(dim1,dim2,dim3)比例的因数。
    (2, 2, 2) 会把 3D 输入张量的每个维度缩小一半。
  • strides: 3 个整数表示的元组,或者是 None。步长值。
  • padding: "valid" 或者 "same"(区分大小写)。
  • data_format: 字符串,channels_last (默认)或 channels_first 之一。
    表示输入各维度的顺序。
    channels_last 代表尺寸是 (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels) 的输入张量,
    channels_first 代表尺寸是 (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3) 的输入张量。
    默认值根据 Keras 配置文件 ~/.keras/keras.json 中的 image_data_format 值来设置。
    如果还没有设置过,那么默认值就是 “channels_last”。

输入尺寸

  • 如果 data_format='channels_last':
    尺寸是 (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) 的 5D 张量
  • 如果 data_format='channels_first':
    尺寸是 (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3) 的 5D 张量

输出尺寸

  • 如果 data_format='channels_last':
    尺寸是 (batch_size, pooled_dim1, pooled_dim2, pooled_dim3, channels) 的 5D 张量
  • 如果 data_format='channels_first':
    尺寸是 (batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3) 的 5D 张量

1.4.4.7 GlobalMaxPooling1D

1
keras.layers.GlobalMaxPooling1D(data_format='channels_last')

对于时序数据的全局最大池化。

参数

  • data_format: 字符串,channels_last (默认)或 channels_first 之一。
    表示输入各维度的顺序。
    channels_last 对应输入尺寸为 (batch, steps, features)
    channels_first 对应输入尺寸为 (batch, features, steps)

输入尺寸

尺寸是 (batch_size, steps, features) 的 3D 张量。

输出尺寸

尺寸是 (batch_size, features) 的 2D 张量。


1.4.4.8 GlobalAveragePooling1D

1
keras.layers.GlobalAveragePooling1D()

对于时序数据的全局平均池化。

输入尺寸

  • 如果 data_format='channels_last'
    输入为 3D 张量,尺寸为:
    (batch_size, steps, features)
  • 如果data_format='channels_first'
    输入为 3D 张量,尺寸为:
    (batch_size, features, steps)

输出尺寸

尺寸是 (batch_size, features) 的 2D 张量。


1.4.4.9 GlobalMaxPooling2D

1
keras.layers.GlobalMaxPooling2D(data_format=None)

对于空域数据的全局最大池化。

参数

  • data_format: 字符串,channels_last (默认)或 channels_first 之一。
    表示输入各维度的顺序。
    channels_last 代表尺寸是 (batch, height, width, channels) 的输入张量,
    channels_first 代表尺寸是 (batch, channels, height, width) 的输入张量。
    默认值根据 Keras 配置文件 ~/.keras/keras.json 中的 image_data_format 值来设置。
    如果还没有设置过,那么默认值就是 “channels_last”。

输入尺寸

  • 如果 data_format='channels_last':
    尺寸是 (batch_size, rows, cols, channels) 的 4D 张量
  • 如果 data_format='channels_first':
    尺寸是 (batch_size, channels, rows, cols) 的 4D 张量

输出尺寸

尺寸是 (batch_size, channels) 的 2D 张量


1.4.4.10 GlobalAveragePooling2D

1
keras.layers.GlobalAveragePooling2D(data_format=None)

对于空域数据的全局平均池化。

参数

  • data_format: 一个字符串,channels_last (默认值)或者 channels_first
    输入张量中的维度顺序。
    channels_last 代表尺寸是 (batch, height, width, channels) 的输入张量,而 channels_first 代表尺寸是 (batch, channels, height, width) 的输入张量。
    默认值根据 Keras 配置文件 ~/.keras/keras.json 中的 image_data_format 值来设置。
    如果还没有设置过,那么默认值就是 “channels_last”。

输入尺寸

  • 如果 data_format='channels_last':
    尺寸是 (batch_size, rows, cols, channels) 的 4D 张量
  • 如果 data_format='channels_first':
    尺寸是 (batch_size, channels, rows, cols) 的 4D 张量

输出尺寸

尺寸是 (batch_size, channels) 的 2D 张量


1.4.4.11 GlobalMaxPooling3D

1
keras.layers.GlobalMaxPooling3D(data_format=None)

对于 3D 数据的全局最大池化。

参数

  • data_format: 字符串,channels_last (默认)或 channels_first 之一。
    表示输入各维度的顺序。
    channels_last 代表尺寸是 (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels) 的输入张量,
    channels_first 代表尺寸是 (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3) 的输入张量。
    默认值根据 Keras 配置文件 ~/.keras/keras.json 中的 image_data_format 值来设置。
    如果还没有设置过,那么默认值就是 “channels_last”。

输入尺寸

  • 如果 data_format='channels_last':
    尺寸是 (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) 的 5D 张量
  • 如果 data_format='channels_first':
    尺寸是 (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3) 的 5D 张量

输出尺寸

尺寸是 (batch_size, channels) 的 2D 张量


1.4.4.12 GlobalAveragePooling3D

1
keras.layers.GlobalAveragePooling3D(data_format=None)

对于 3D 数据的全局平均池化。

参数

  • data_format: 字符串,channels_last (默认)或 channels_first 之一。
    表示输入各维度的顺序。
    channels_last 代表尺寸是 (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels) 的输入张量,
    channels_first 代表尺寸是 (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3) 的输入张量。
    默认值根据 Keras 配置文件 ~/.keras/keras.json 中的 image_data_format 值来设置。
    如果还没有设置过,那么默认值就是 “channels_last”。

输入尺寸

  • 如果 data_format='channels_last':
    尺寸是 (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) 的 5D 张量
  • 如果 data_format='channels_first':
    尺寸是 (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3) 的 5D 张量

输出尺寸

尺寸是 (batch_size, channels) 的 2D 张量

二 使用keras进行基本图像分类

2.1 准备数据

本指南使用 Fashion MNIST 数据集,该数据集包含 10 个类别的 70,000 个灰度图像。这些图像以低分辨率(28x28 像素)展示了单件衣物

在本指南中,我们使用 60,000 个图像来训练网络,使用 10,000 个图像来评估网络学习对图像分类的准确率。您可以直接从 TensorFlow 访问 Fashion MNIST。请运行以下代码,直接从 TensorFlow 中导入和加载 Fashion MNIST 数据:

1
2
3
fashion_mnist = keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

加载数据集会返回四个 NumPy 数组:

  • train_imagestrain_labels 数组是训练集,即模型用于学习的数据。
  • 测试集test_imagestest_labels 数组会被用来对模型进行测试。

图像是 28x28 的 NumPy 数组,像素值介于 0 到 255 之间。标签是整数数组,介于 0 到 9 之间。这些标签对应于图像所代表的服装

标签
0 T恤/上衣
1 裤子
2 套头衫
3 连衣裙
4 外套
5 凉鞋
6 衬衫
7 运动鞋
8
9 短靴

2.2 构建模型

构建神经网络需要先配置模型的层,然后再编译模型。

2.2.1 设置层

神经网络的基本组成部分是。层会从向其馈送的数据中提取表示形式。希望这些表示形式有助于解决手头上的问题。

大多数深度学习都包括将简单的层链接在一起。大多数层(如 tf.keras.layers.Dense)都具有在训练期间才会学习的参数。

1
2
3
4
5
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dense(10)
])

该网络的第一层 tf.keras.layers.Flatten 将图像格式从二维数组(28 x 28 像素)转换成一维数组(28 x 28 = 784 像素)。将该层视为图像中未堆叠的像素行并将其排列起来。该层没有要学习的参数,它只会重新格式化数据。

展平像素后,网络会包括两个 tf.keras.layers.Dense 层的序列。它们是密集连接或全连接神经层。第一个 Dense 层有 128 个节点(或神经元)。第二个(也是最后一个)层会返回一个长度为 10 的 logits 数组。每个节点都包含一个得分,用来表示当前图像属于 10 个类中的哪一类。

2.2.2 编译模型

在准备对模型进行训练之前,还需要再对其进行一些设置。以下内容是在模型的编译步骤中添加的:

  • 损失函数 - 用于测量模型在训练期间的准确率。您会希望最小化此函数,以便将模型“引导”到正确的方向上。
  • 优化器 - 决定模型如何根据其看到的数据和自身的损失函数进行更新。
  • 指标 - 用于监控训练和测试步骤。以下示例使用了准确率,即被正确分类的图像的比率。
1
2
3
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])

2.3 训练模型

训练神经网络模型需要执行以下步骤:

  1. 将训练数据馈送给模型。在本例中,训练数据位于 train_imagestrain_labels 数组中。
  2. 模型学习将图像和标签关联起来。
  3. 要求模型对测试集(在本例中为 test_images 数组)进行预测。
  4. 验证预测是否与 test_labels 数组中的标签相匹配。

2.3.1 向模型馈送数据

要开始训练,请调用 model.fit 方法,这样命名是因为该方法会将模型与训练数据进行“拟合”:

1
model.fit(train_images, train_labels, epochs=10)

2.3.2 评估准确率

接下来,比较模型在测试数据集上的表现:

1
2
3
test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)

print('\nTest accuracy:', test_acc)

结果表明,模型在测试数据集上的准确率略低于训练数据集。训练准确率和测试准确率之间的差距代表过拟合。过拟合是指机器学习模型在新的、以前未曾见过的输入上的表现不如在训练数据上的表现。过拟合的模型会“记住”训练数据集中的噪声和细节,从而对模型在新数据上的表现产生负面影响。

2.3.3 进行预测

在模型经过训练后,您可以使用它对一些图像进行预测。模型具有线性输出,即 logits。您可以附加一个 softmax 层,将 logits 转换成更容易理解的概率。

1
2
3
4
probability_model = tf.keras.Sequential([model, 
tf.keras.layers.Softmax()])

predictions = probability_model.predict(test_images)

在上例中,模型预测了测试集中每个图像的标签。我们来看看第一个预测结果

1
predictions[0]

得到的结果为

1
2
3
array([6.9982241e-07, 5.5403369e-08, 1.8353174e-07, 1.4761626e-07,
2.4380807e-07, 1.9273469e-04, 1.8122660e-06, 6.5027133e-02,
1.7891599e-06, 9.3477517e-01], dtype=float32)

预测结果是一个包含 10 个数字的数组。它们代表模型对 10 种不同服装中每种服装的“置信度”。您可以看到哪个标签的置信度值最大:

1
np.argmax(predictions[0])

输出结果为

1
9

2.4 使用训练好的模型

最后,使用训练好的模型对单个图像进行预测。

1
2
3
4
# Grab an image from the test dataset.
img = test_images[1]

print(img.shape)

输出结果为

1
(28, 28)

tf.keras 模型经过了优化,可同时对一个或一组样本进行预测。因此,即便您只使用一个图像,您也需要将其添加到列表中:

1
2
3
4
5
# Add the image to a batch where it's the only member.
img = (np.expand_dims(img,0))

print(img.shape)
(1, 28, 28)

现在预测这个图像的正确标签:

1
2
3
4
5
predictions_single = probability_model.predict(img)

print(predictions_single)
[[1.0675135e-05 2.4023437e-12 9.9772269e-01 1.3299730e-09 1.2968916e-03
8.7469149e-14 9.6970733e-04 5.4669354e-19 2.4514609e-11 1.8405429e-12]]

keras.Model.predict 会返回一组列表,每个列表对应一批数据中的每个图像。在批次中获取对我们(唯一)图像的预测:

1
2
np.argmax(predictions_single[0])
2

该模型会按照预期预测标签。

2.5 完整示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import tensorflow as tf
import numpy as np

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def exec(images, labels):
"""
训练模型
:param images:
:param labels:
:return:
"""

model = keras.Sequential([
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dense(10)
])
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
model.fit(images, labels, epochs=10)
return model


def prepare():
"""
准备数据
:return:
"""
fashion_mnist = keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

return (train_images, train_labels), (test_images, test_labels)


if __name__ == "__main__":
# 准备数据
(train_images, train_labels), (test_images, test_labels) = prepare()

# 获取模型
model = exec(train_images, train_labels)

# 评估准确率
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print(f'\n 该模型的损失率为 {test_loss} ,准确率为 {test_acc} \n')

# 进行预测
probability_model = tf.keras.Sequential([model,
tf.keras.layers.Softmax()])
predictions = probability_model.predict(test_images)

print(f"\n 预测的结果为 {predictions}\n ")

result = predictions[0]
print(f"\n 第一个预测的结果为 {result}\n ")

max_val = np.argmax(result)
print(f"\n 标签的置信度值最大 {max_val}\n ")

运行结果为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 
当前的tensorflow版本为 2.5.0

Epoch 1/10
1875/1875 [==============================] - 2s 661us/step - loss: 2.9311 - accuracy: 0.6793
Epoch 2/10
1875/1875 [==============================] - 1s 657us/step - loss: 0.6888 - accuracy: 0.7287
Epoch 3/10
1875/1875 [==============================] - 1s 651us/step - loss: 0.6284 - accuracy: 0.7645
Epoch 4/10
1875/1875 [==============================] - 1s 654us/step - loss: 0.5846 - accuracy: 0.7850
Epoch 5/10
1875/1875 [==============================] - 1s 655us/step - loss: 0.5361 - accuracy: 0.8123
Epoch 6/10
1875/1875 [==============================] - 1s 651us/step - loss: 0.5247 - accuracy: 0.8182
Epoch 7/10
1875/1875 [==============================] - 1s 655us/step - loss: 0.5133 - accuracy: 0.8238
Epoch 8/10
1875/1875 [==============================] - 1s 660us/step - loss: 0.5029 - accuracy: 0.8275
Epoch 9/10
1875/1875 [==============================] - 1s 654us/step - loss: 0.4989 - accuracy: 0.8300
Epoch 10/10
1875/1875 [==============================] - 1s 660us/step - loss: 0.4996 - accuracy: 0.8308
313/313 - 0s - loss: 0.5729 - accuracy: 0.8159

该模型的损失率为 0.5729408860206604 ,准确率为 0.8159000277519226

预测的结果为 [[2.6714636e-11 2.1633006e-12 0.0000000e+00 ... 1.5879445e-01
3.2504733e-08 7.0632845e-01]
[5.3072190e-03 1.3794645e-04 6.1355513e-01 ... 0.0000000e+00
9.9997334e-05 1.2250206e-18]
[2.3415004e-15 1.0000000e+00 7.5255159e-22 ... 0.0000000e+00
4.5934239e-19 0.0000000e+00]
...
[8.7049462e-05 1.3646974e-16 3.3726320e-08 ... 7.3532672e-23
9.9553645e-01 2.8880037e-18]
[3.0991928e-11 1.0000000e+00 5.3241626e-17 ... 0.0000000e+00
1.2041029e-13 0.0000000e+00]
[1.0217112e-26 5.1743408e-36 0.0000000e+00 ... 1.7620994e-03
8.2260941e-04 2.0202377e-03]]

第一个预测的结果为 [2.6714636e-11 2.1633006e-12 0.0000000e+00 9.8106201e-10 3.3878266e-30
1.3487716e-01 2.7203369e-15 1.5879445e-01 3.2504733e-08 7.0632845e-01]

标签的置信度值最大 9

三 使用keras进行文本分类

使用评论文本将影评分为积极(positive)消极(nagetive)两类。这是一个二元(binary)或者二分类问题,一种重要且应用广泛的机器学习问题。

3.1 下载 IMDB 数据集

IMDB 数据集已经打包在 Tensorflow 中。该数据集已经经过预处理,评论(单词序列)已经被转换为整数序列,其中每个整数表示字典中的特定单词。

以下代码将下载 IMDB 数据集到您的机器上(如果您已经下载过将从缓存中复制):

1
2
3
imdb = keras.datasets.imdb

(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)

参数 num_words=10000 保留了训练数据中最常出现的 10,000 个单词。为了保持数据规模的可管理性,低频词将被丢弃。

3.2 准备数据

影评——即整数数组必须在输入神经网络之前转换为张量。这种转换可以通过以下两种方式来完成:

  • 将数组转换为表示单词出现与否的由 0 和 1 组成的向量,类似于 one-hot 编码。例如,序列[3, 5]将转换为一个 10,000 维的向量,该向量除了索引为 3 和 5 的位置是 1 以外,其他都为 0。然后,将其作为网络的首层——一个可以处理浮点型向量数据的稠密层。不过,这种方法需要大量的内存,需要一个大小为 num_words * num_reviews 的矩阵。
  • 或者,我们可以填充数组来保证输入数据具有相同的长度,然后创建一个大小为 max_length * num_reviews 的整型张量。我们可以使用能够处理此形状数据的嵌入层作为网络中的第一层。

在本示例中,我们将使用第二种方法。

由于电影评论长度必须相同,我们将使用 pad_sequences 函数来使长度标准化

1
2
3
4
5
6
7
8
9
train_data = keras.preprocessing.sequence.pad_sequences(train_data,
value=word_index["<PAD>"],
padding='post',
maxlen=256)

test_data = keras.preprocessing.sequence.pad_sequences(test_data,
value=word_index["<PAD>"],
padding='post',
maxlen=256)

现在看下样本的长度:

1
len(train_data[0]), len(train_data[1])

输出结果为

1
(256, 256)

并检查一下首条评论(当前已经填充):

1
print(train_data[0])

输出结果为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[   1   14   22   16   43  530  973 1622 1385   65  458 4468   66 3941
4 173 36 256 5 25 100 43 838 112 50 670 2 9
35 480 284 5 150 4 172 112 167 2 336 385 39 4
172 4536 1111 17 546 38 13 447 4 192 50 16 6 147
2025 19 14 22 4 1920 4613 469 4 22 71 87 12 16
43 530 38 76 15 13 1247 4 22 17 515 17 12 16
626 18 2 5 62 386 12 8 316 8 106 5 4 2223
5244 16 480 66 3785 33 4 130 12 16 38 619 5 25
124 51 36 135 48 25 1415 33 6 22 12 215 28 77
52 5 14 407 16 82 2 8 4 107 117 5952 15 256
4 2 7 3766 5 723 36 71 43 530 476 26 400 317
46 7 4 2 1029 13 104 88 4 381 15 297 98 32
2071 56 26 141 6 194 7486 18 4 226 22 21 134 476
26 480 5 144 30 5535 18 51 36 28 224 92 25 104
4 226 65 16 38 1334 88 12 16 283 5 16 4472 113
103 32 15 16 5345 19 178 32 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0]

3.3 构建模型

神经网络由堆叠的层来构建,这需要从两个主要方面来进行体系结构决策:

  • 模型里有多少层?
  • 每个层里有多少隐层单元(hidden units)

在此样本中,输入数据包含一个单词索引的数组。要预测的标签为 0 或 1。让我们来为该问题构建一个模型:

1
2
3
4
5
6
7
8
9
10
# 输入形状是用于电影评论的词汇数目(10,000 词)
vocab_size = 10000

model = keras.Sequential()
model.add(keras.layers.Embedding(vocab_size, 16))
model.add(keras.layers.GlobalAveragePooling1D())
model.add(keras.layers.Dense(16, activation='relu'))
model.add(keras.layers.Dense(1, activation='sigmoid'))

model.summary()

输出结果为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding (Embedding) (None, None, 16) 160000
_________________________________________________________________
global_average_pooling1d (Gl (None, 16) 0
_________________________________________________________________
dense (Dense) (None, 16) 272
_________________________________________________________________
dense_1 (Dense) (None, 1) 17
=================================================================
Total params: 160,289
Trainable params: 160,289
Non-trainable params: 0
_________________________________________________________________

层按顺序堆叠以构建分类器:

  1. 第一层是嵌入(Embedding)层。该层采用整数编码的词汇表,并查找每个词索引的嵌入向量(embedding vector)。这些向量是通过模型训练学习到的。向量向输出数组增加了一个维度。得到的维度为:(batch, sequence, embedding)
  2. 接下来,GlobalAveragePooling1D 将通过对序列维度求平均值来为每个样本返回一个定长输出向量。这允许模型以尽可能最简单的方式处理变长输入。
  3. 该定长输出向量通过一个有 16 个隐层单元的全连接(Dense)层传输。
  4. 最后一层与单个输出结点密集连接。使用 Sigmoid 激活函数,其函数值为介于 0 与 1 之间的浮点数,表示概率或置信度。

3.3.1 隐层单元

上述模型在输入输出之间有两个中间层或“隐藏层”。输出(单元,结点或神经元)的数量即为层表示空间的维度。换句话说,是学习内部表示时网络所允许的自由度。

如果模型具有更多的隐层单元(更高维度的表示空间)和/或更多层,则可以学习到更复杂的表示。但是,这会使网络的计算成本更高,并且可能导致学习到不需要的模式——一些能够在训练数据上而不是测试数据上改善性能的模式。这被称为过拟合(overfitting)

3.3.2 损失函数与优化器

一个模型需要损失函数和优化器来进行训练。由于这是一个二分类问题且模型输出概率值(一个使用 sigmoid 激活函数的单一单元层),我们将使用 binary_crossentropy 损失函数。

这不是损失函数的唯一选择,例如,您可以选择 mean_squared_error 。但是,一般来说 binary_crossentropy 更适合处理概率——它能够度量概率分布之间的“距离”,或者在我们的示例中,指的是度量 ground-truth 分布与预测值之间的“距离”。

稍后,当我们研究回归问题(例如,预测房价)时,我们将介绍如何使用另一种叫做均方误差的损失函数。

现在,配置模型来使用优化器和损失函数:

1
2
3
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])

3.4 创建一个验证集

在训练时,我们想要检查模型在未见过的数据上的准确率(accuracy)。通过从原始训练数据中分离 10,000 个样本来创建一个验证集。(为什么现在不使用测试集?我们的目标是只使用训练数据来开发和调整模型,然后只使用一次测试数据来评估准确率(accuracy))。

1
2
3
4
5
x_val = train_data[:10000]
partial_x_train = train_data[10000:]

y_val = train_labels[:10000]
partial_y_train = train_labels[10000:]

3.5 训练模型

以 512 个样本的 mini-batch 大小迭代 40 个 epoch 来训练模型。这是指对 x_trainy_train 张量中所有样本的的 40 次迭代。在训练过程中,监测来自验证集的 10,000 个样本上的损失值(loss)和准确率(accuracy):

1
2
3
4
5
6
history = model.fit(partial_x_train,
partial_y_train,
epochs=40,
batch_size=512,
validation_data=(x_val, y_val),
verbose=1)

3.6 评估模型

我们来看一下模型的性能如何。将返回两个值。损失值(loss)(一个表示误差的数字,值越低越好)与准确率(accuracy)。

1
2
3
results = model.evaluate(test_data,  test_labels, verbose=2)

print(results)

输出结果为

1
2
782/782 - 1s - loss: 0.3298 - accuracy: 0.8729
[0.32977813482284546, 0.8728799819946289]

这种十分朴素的方法得到了约 87% 的准确率(accuracy)

3.7 随时间变化的图表

model.fit() 返回一个 History 对象,该对象包含一个字典,其中包含训练阶段所发生的一切事件:

1
2
history_dict = history.history
history_dict.keys()

输出结果为

1
dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])

有四个条目:在训练和验证期间,每个条目对应一个监控指标。我们可以使用这些条目来绘制训练与验证过程的损失值(loss)和准确率(accuracy),以便进行比较。

3.8 完整示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import tensorflow as tf
import numpy as np

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def prepare():
"""
准备数据
:return:
"""
imdb = keras.datasets.imdb

# 一个映射单词到整数索引的词典
word_index = imdb.get_word_index()

# 保留第一个索引
word_index = {k: (v + 3) for k, v in word_index.items()}
word_index["<PAD>"] = 0
word_index["<START>"] = 1
word_index["<UNK>"] = 2 # unknown
word_index["<UNUSED>"] = 3

(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)

train_data = keras.preprocessing.sequence.pad_sequences(train_data,
value=word_index["<PAD>"],
padding='post',
maxlen=256)

test_data = keras.preprocessing.sequence.pad_sequences(test_data,
value=word_index["<PAD>"],
padding='post',
maxlen=256)

return (train_data, train_labels), (test_data, test_labels)


def exec(x_train, y_train, x_val, y_val):
"""
训练模型
:param x_train: 训练集X轴数据
:param y_train: 训练集Y轴数据
:param x_val: 验证集X轴数据
:param y_val: 验证集Y轴数据
:return: 模型 ,history
"""

# 输入形状是用于电影评论的词汇数目(10,000 词)
vocab_size = 10000

model = keras.Sequential()

# 第一层是`嵌入(Embedding)`层。该层采用整数编码的词汇表,
# 并查找每个词索引的嵌入向量(embedding vector)。
# 这些向量是通过模型训练学习到的。向量向输出数组增加了一个维度。
# 得到的维度为:`(batch, sequence, embedding)`。
model.add(keras.layers.Embedding(vocab_size, 16))

# `GlobalAveragePooling1D` 将通过对序列维度求平均值来为每个样本返回一个定长输出向量。
# 这允许模型以尽可能最简单的方式处理变长输入
model.add(keras.layers.GlobalAveragePooling1D())

# 该定长输出向量通过一个有 16 个隐层单元的全连接(`Dense`)层传输
model.add(keras.layers.Dense(16, activation='relu'))

# 最后一层与单个输出结点密集连接。使用 `Sigmoid` 激活函数,其函数值为介于 0 与 1 之间的浮点数,表示概率或置信度
model.add(keras.layers.Dense(1, activation='sigmoid'))

# summary = model.summary()

# 配置模型来使用优化器和损失函数
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])

# 训练模型
history = model.fit(x_train,
y_train,
epochs=40,
batch_size=512,
validation_data=(x_val, y_val),
verbose=1)

return model, history


if __name__ == "__main__":
# 准备数据
(train_data, train_labels), (test_data, test_labels) = prepare()

# 创建一个验证集
x_val = train_data[:10000]
x_train = train_data[10000:]

y_val = train_labels[:10000]
y_train = train_labels[10000:]

# 获取模型
model, history = exec(x_train, y_train, x_val, y_val)

# History对象包含一个字典,其中包含训练阶段所发生的一切事件
history_dict = history.history
keys = history_dict.keys()
print(f'\n history 包含的数据属性为 {keys} \n')

# 评估模型
results = model.evaluate(test_data, test_labels, verbose=2)
print(f'\n 该模型的准确率为 {results} \n')

运行结果为

1
2
3
4
5
6
 当前的tensorflow版本为  2.5.0  

history 包含的数据属性为 dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
782/782 - 0s - loss: 0.3354 - accuracy: 0.8720

该模型的准确率为 [0.33535251021385193, 0.8719599843025208]

进一步将该模型用图表表示出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def draw_picture(history_dict):
# 支持中文
mpl.rcParams["font.sans-serif"] = ["simHei"]
mpl.rcParams["axes.unicode_minus"] = False
acc = history_dict['accuracy']
val_acc = history_dict['val_accuracy']
loss = history_dict['loss']
val_loss = history_dict['val_loss']
epochs = range(1, len(acc) + 1)
# “bo”代表 "蓝点"
plt.plot(epochs, loss, 'bo', label='Training loss')
# b代表“蓝色实线”
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.plot(epochs, acc, c='green', label='Training acc')
plt.plot(epochs, val_acc, c='red', label='Validation acc')
plt.title('准确率(accuracy)和损失值(loss)随时间变化趋势图')
plt.xlabel('Epochs')
plt.ylabel('准确率(accuracy)和损失值(loss)')
plt.legend()
plt.show()

可以看到如下所示的图表

image-20210602100626443

四 使用keras进行回归

回归 (regression) 问题中,我们的目的是预测出如价格或概率这样连续值的输出。相对于分类(classification) 问题,分类(classification) 的目的是从一系列的分类出选择出一个分类 (如,给出一张包含苹果或橘子的图片,识别出图片中是哪种水果)。

本示例使用经典的 Auto MPG 数据集,构建了一个用来预测70年代末到80年代初汽车燃油效率的模型。为了做到这一点,我们将为该模型提供许多那个时期的汽车描述。这个描述包含:气缸数,排量,马力以及重量。

在处理回归问题的技术中:

  • 均方误差(MSE)是用于回归问题的常见损失函数(分类问题中使用不同的损失函数)。
  • 类似的,用于回归的评估指标与分类不同。 常见的回归指标是平均绝对误差(MAE)。
  • 当数字输入数据特征的值存在不同范围时,每个特征应独立缩放到相同范围。
  • 如果训练数据不多,一种方法是选择隐藏层较少的小网络,以避免过度拟合。
  • 早期停止是一种防止过度拟合的有效技术。

4.1 数据准备

4.1.1 获取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
# 下载数据
dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")


# 使用 pandas 导入数据集
column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight',
'Acceleration', 'Model Year', 'Origin']
raw_dataset = pd.read_csv(dataset_path, names=column_names,
na_values = "?", comment='\t',
sep=" ", skipinitialspace=True)

dataset = raw_dataset.copy()
dataset.tail()

得到的数据的大概样式如下

image-20210602101817797

4.1.2 数据清洗

在上述得到的数据中,包括一些未知值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import tensorflow as tf
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def prepare():
# 下载数据
dataset_path = keras.utils.get_file("auto-mpg.data",
"http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")

# 使用 pandas 导入数据集
column_names = ['MPG', 'Cylinders', 'Displacement', 'Horsepower', 'Weight',
'Acceleration', 'Model Year', 'Origin']
raw_dataset = pd.read_csv(dataset_path, names=column_names,
na_values="?", comment='\t',
sep=" ", skipinitialspace=True)

dataset = raw_dataset.copy()
dataset.tail()
return dataset


if __name__ == "__main__":
dataset = prepare()

sum_data = dataset.isna().sum()

print(sum_data)

运行结果如下

1
2
3
4
5
6
7
8
9
10
11
 当前的tensorflow版本为  2.5.0  

MPG 0
Cylinders 0
Displacement 0
Horsepower 6
Weight 0
Acceleration 0
Model Year 0
Origin 0
dtype: int64

为了保证这个初始示例的简单性,删除这些行。

1
dataset = dataset.dropna()

"Origin" 列实际上代表分类,而不仅仅是一个数字。所以把它转换为独热码 (one-hot):

1
2
3
4
5
origin = dataset.pop('Origin')
dataset['USA'] = (origin == 1)*1.0
dataset['Europe'] = (origin == 2)*1.0
dataset['Japan'] = (origin == 3)*1.0
dataset.tail()

优化代码为以下格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import tensorflow as tf
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def prepare():
# 下载数据
dataset_path = keras.utils.get_file("auto-mpg.data",
"http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")

# 使用 pandas 导入数据集
column_names = ['MPG', 'Cylinders', 'Displacement', 'Horsepower', 'Weight',
'Acceleration', 'Model Year', 'Origin']
raw_dataset = pd.read_csv(dataset_path, names=column_names,
na_values="?", comment='\t',
sep=" ", skipinitialspace=True)

dataset = raw_dataset.copy()

# 为了保证这个初始示例的简单性,删除这些行。
dataset = dataset.dropna()

# "Origin" 列实际上代表分类,而不仅仅是一个数字。所以把它转换为独热码 (one-hot):
origin = dataset.pop('Origin')
dataset['USA'] = (origin == 1) * 1.0
dataset['Europe'] = (origin == 2) * 1.0
dataset['Japan'] = (origin == 3) * 1.0
dataset.tail()
return dataset


if __name__ == "__main__":
dataset = prepare()

sum_data = dataset.isna().sum()

print(sum_data)

运行结果为

1
2
3
4
5
6
7
8
9
10
11
12
13
 当前的tensorflow版本为  2.5.0  

MPG 0
Cylinders 0
Displacement 0
Horsepower 0
Weight 0
Acceleration 0
Model Year 0
USA 0
Europe 0
Japan 0
dtype: int64

4.1.3 拆分数据集

现在需要将数据集拆分为一个训练数据集和一个测试数据集。

我们最后将使用测试数据集对模型进行评估。

1
2
train_dataset = dataset.sample(frac=0.8,random_state=0)
test_dataset = dataset.drop(train_dataset.index)

4.1.4 数据检查

快速查看训练集中几对列的联合分布

查看总体的数据统计:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import tensorflow as tf
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt

import seaborn as sns

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def prepare():
# 下载数据
dataset_path = keras.utils.get_file("auto-mpg.data",
"http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")

# 使用 pandas 导入数据集
column_names = ['MPG', 'Cylinders', 'Displacement', 'Horsepower', 'Weight',
'Acceleration', 'Model Year', 'Origin']
raw_dataset = pd.read_csv(dataset_path, names=column_names,
na_values="?", comment='\t',
sep=" ", skipinitialspace=True)

dataset = raw_dataset.copy()

# 为了保证这个初始示例的简单性,删除这些行。
dataset = dataset.dropna()

# "Origin" 列实际上代表分类,而不仅仅是一个数字。所以把它转换为独热码 (one-hot):
origin = dataset.pop('Origin')
dataset['USA'] = (origin == 1) * 1.0
dataset['Europe'] = (origin == 2) * 1.0
dataset['Japan'] = (origin == 3) * 1.0
dataset.tail()
return dataset


def data_split(dataset):
train_dataset = dataset.sample(frac=0.8, random_state=0)
test_dataset = dataset.drop(train_dataset.index)
return train_dataset, test_dataset


if __name__ == "__main__":
dataset = prepare()

sum_data = dataset.isna().sum()

# print(sum_data)

train_dataset, test_dataset = data_split(dataset)

# 数据检查
# 查看总体的数据统计:
train_stats = train_dataset.describe()
train_stats.pop("MPG")
train_stats = train_stats.transpose()
print(train_stats)

运行结果为

1
2
3
4
5
6
7
8
9
10
11
12
13
 当前的tensorflow版本为  2.5.0  

count mean std ... 50% 75% max
Cylinders 314.0 5.477707 1.699788 ... 4.0 8.00 8.0
Displacement 314.0 195.318471 104.331589 ... 151.0 265.75 455.0
Horsepower 314.0 104.869427 38.096214 ... 94.5 128.00 225.0
Weight 314.0 2990.251592 843.898596 ... 2822.5 3608.00 5140.0
Acceleration 314.0 15.559236 2.789230 ... 15.5 17.20 24.8
Model Year 314.0 75.898089 3.675642 ... 76.0 79.00 82.0
USA 314.0 0.624204 0.485101 ... 1.0 1.00 1.0
Europe 314.0 0.178344 0.383413 ... 0.0 0.00 1.0
Japan 314.0 0.197452 0.398712 ... 0.0 0.00 1.0
[9 rows x 8 columns]

4.1.5 从标签中分离特征

将特征值从目标值或者”标签”中分离。 这个标签是你使用训练模型进行预测的值。

1
2
3
4
5
train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')

print(f" \n train_labels =\n {train_labels} \n")
print(f" \n test_labels = \n{test_labels} \n")

运行结果为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 train_labels =
146 28.0
282 22.3
69 12.0
378 38.0
331 33.8
...
281 19.8
229 16.0
150 26.0
145 32.0
182 28.0
Name: MPG, Length: 314, dtype: float64

test_labels =
9 15.0
25 10.0
28 9.0
31 25.0
33 19.0
...
369 34.0
375 36.0
382 34.0
384 32.0
396 28.0
Name: MPG, Length: 78, dtype: float64

4.1.6 数据规范化

再次审视下上面的 train_stats 部分,并注意每个特征的范围有什么不同。

使用不同的尺度和范围对特征归一化是好的实践。尽管模型可能 在没有特征归一化的情况下收敛,它会使得模型训练更加复杂,并会造成生成的模型依赖输入所使用的单位选择。

注意:尽管我们仅仅从训练集中有意生成这些统计数据,但是这些统计信息也会用于归一化的测试数据集。我们需要这样做,将测试数据集放入到与已经训练过的模型相同的分布中。

1
2
3
4
5
def norm(x):
return (x - train_stats['mean']) / train_stats['std']

normed_train_data = norm(train_dataset)
normed_test_data = norm(test_dataset)

我们将会使用这个已经归一化的数据来训练模型。

警告: 用于归一化输入的数据统计(均值和标准差)需要反馈给模型从而应用于任何其他数据,以及我们之前所获得独热码。这些数据包含测试数据集以及生产环境中所使用的实时数据。

4.2 模型设计

4.2.1 构建模型

让我们来构建我们自己的模型。这里,我们将会使用一个“顺序”模型,其中包含两个紧密相连的隐藏层,以及返回单个、连续值得输出层。模型的构建步骤包含于一个名叫 ‘build_model’ 的函数中,稍后我们将会创建第二个模型。 两个密集连接的隐藏层。

1
2
3
4
5
6
7
8
9
10
11
12
13
def exec():
model = keras.Sequential([
keras.layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]),
keras.layers.Dense(64, activation='relu'),
keras.layers.Dense(1)
])

optimizer = tf.keras.optimizers.RMSprop(0.001)

model.compile(loss='mse',
optimizer=optimizer,
metrics=['mae', 'mse'])
return model

4.2.2 检查模型

使用 .summary 方法来打印该模型的简单描述。

1
model.summary()

输出信息如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 64) 640
_________________________________________________________________
dense_1 (Dense) (None, 64) 4160
_________________________________________________________________
dense_2 (Dense) (None, 1) 65
=================================================================
Total params: 4,865
Trainable params: 4,865
Non-trainable params: 0
_________________________________________________________________
None

4.2.3 训练模型

对模型进行1000个周期的训练,并在 history 对象中记录训练和验证的准确性。

1
2
3
4
5
6
7
8
9
10
11
12
# 通过为每个完成的时期打印一个点来显示训练进度
class PrintDot(keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs):
if epoch % 100 == 0: print('')
print('.', end='')

EPOCHS = 1000

history = model.fit(
normed_train_data, train_labels,
epochs=EPOCHS, validation_split = 0.2, verbose=0,
callbacks=[PrintDot()])

使用 history 对象中存储的统计信息可视化模型的训练进度。

1
2
3
4
hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch
tail = hist.tail()
print(f" \n tail = \n {tail} \n ")

运行结果如下

1
2
3
4
5
6
7
 tail = 
loss mae mse val_loss val_mae val_mse epoch
995 2.577699 1.052732 2.577699 9.195265 2.216188 9.195265 995
996 2.559914 1.080695 2.559914 8.477479 2.150404 8.477479 996
997 2.507329 1.002967 2.507329 8.963373 2.236578 8.963373 997
998 2.732234 1.059285 2.732234 8.776144 2.166286 8.776144 998
999 2.442101 0.997287 2.442101 8.820552 2.217157 8.820552 999

4.2.4 输出训练信息

主要函数如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def plot_history(history):
hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch

plt.figure()
plt.xlabel('Epoch')
plt.ylabel('Mean Abs Error [MPG]')
plt.plot(hist['epoch'], hist['mae'],
label='Train Error')
plt.plot(hist['epoch'], hist['val_mae'],
label='Val Error')

plt.ylim([0, 20])

# 添加网格
plt.grid(True, linestyle='--', alpha=0.5)

plt.legend()
plt.show()

运行得到的结果如下

image-20210602114516600

该图表显示在约100个 epochs 之后误差非但没有改进,反而出现恶化。 让我们更新 model.fit 调用,当验证值没有提高上是自动停止训练。 我们将使用一个 EarlyStopping callback 来测试每个 epoch 的训练条件。如果经过一定数量的 epochs 后没有改进,则自动停止训练。

1
2
3
4
5
# patience 值用来检查改进 epochs 的数量
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)

history = model.fit(normed_train_data, train_labels, epochs=EPOCHS,
validation_split = 0.2, verbose=0, callbacks=[early_stop, PrintDot()])

优化之后的运行结果如下

image-20210602114732709

如图所示,验证集中的平均的误差通常在 +/- 2 MPG左右。

让我们看看通过使用 测试集 来泛化模型的效果如何,我们在训练模型时没有使用测试集。这告诉我们,当我们在现实世界中使用这个模型时,我们可以期望它预测得有多好。

1
2
loss, mae, mse = model.evaluate(normed_test_data, test_labels, verbose=2)
print(f" loss ={loss} , mae ={mae} , mse ={mse}")

运行结果为

1
loss =5.641756534576416 , mae =1.857352375984192 , mse =5.641756534576416

4.2.4 进行预测

1
2
3
4
5
6
7
8
9
10
test_predictions = model.predict(normed_test_data).flatten()

plt.scatter(test_labels, test_predictions)
plt.xlabel('True Values [MPG]')
plt.ylabel('Predictions [MPG]')
plt.axis('equal')
plt.axis('square')
plt.xlim([0,plt.xlim()[1]])
plt.ylim([0,plt.ylim()[1]])
_ = plt.plot([-100, 100], [-100, 100])

4.3 完整示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import tensorflow as tf
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def prepare():
# 下载数据
dataset_path = keras.utils.get_file("auto-mpg.data",
"http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")

# 使用 pandas 导入数据集
column_names = ['MPG', 'Cylinders', 'Displacement', 'Horsepower', 'Weight',
'Acceleration', 'Model Year', 'Origin']
raw_dataset = pd.read_csv(dataset_path, names=column_names,
na_values="?", comment='\t',
sep=" ", skipinitialspace=True)

dataset = raw_dataset.copy()

# 为了保证这个初始示例的简单性,删除这些行。
dataset = dataset.dropna()

# "Origin" 列实际上代表分类,而不仅仅是一个数字。所以把它转换为独热码 (one-hot):
origin = dataset.pop('Origin')
dataset['USA'] = (origin == 1) * 1.0
dataset['Europe'] = (origin == 2) * 1.0
dataset['Japan'] = (origin == 3) * 1.0
dataset.tail()
return dataset


def data_split(dataset):
train_dataset = dataset.sample(frac=0.8, random_state=0)
test_dataset = dataset.drop(train_dataset.index)
return train_dataset, test_dataset


def normal_data(train_dataset, test_dataset):
train_stats = train_dataset.describe()
# train_stats.pop("MPG")
train_stats = train_stats.transpose()

def norm(x):
return (x - train_stats['mean']) / train_stats['std']

normed_train_data = norm(train_dataset)
normed_test_data = norm(test_dataset)
return normed_train_data, normed_test_data


def exec():
model = keras.Sequential([
keras.layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]),
keras.layers.Dense(64, activation='relu'),
keras.layers.Dense(1)
])

optimizer = tf.keras.optimizers.RMSprop(0.001)

model.compile(loss='mse',
optimizer=optimizer,
metrics=['mae', 'mse'])

EPOCHS = 1000

# patience 值用来检查改进 epochs 的数量
# 我们将使用一个 EarlyStopping callback 来测试每个 epoch 的训练条件。如果经过一定数量的 epochs 后没有改进,则自动停止训练
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)

history = model.fit(normed_train_data, train_labels, epochs=EPOCHS,
validation_split=0.2, verbose=0, callbacks=[early_stop, PrintDot()])

return model, history


# 通过为每个完成的时期打印一个点来显示训练进度
class PrintDot(keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs):
if epoch % 100 == 0: print('')
print('.', end='')


def plot_history(history):
hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch

plt.figure()
plt.xlabel('Epoch')
plt.ylabel('Mean Abs Error [MPG]')
plt.plot(hist['epoch'], hist['mae'],
label='Train Error')
plt.plot(hist['epoch'], hist['val_mae'],
label='Val Error')

plt.ylim([0, 20])

# 添加网格
plt.grid(True, linestyle='--', alpha=0.5)

plt.legend()
plt.show()


if __name__ == "__main__":
# 准备数据
dataset = prepare()

# sum_data = dataset.isna().sum()
# print(sum_data)

# 拆分训练数据集和测试数据集
train_dataset, test_dataset = data_split(dataset)

# 从标签中分离特征
train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')

print(f" \n train_labels =\n {train_labels} \n")
print(f" \n test_labels = \n{test_labels} \n")

# 数据规范化
normed_train_data, normed_test_data = normal_data(train_dataset, test_dataset)

# 获取模型
model, history = exec()

# print(model.summary())

# hist = pd.DataFrame(history.history)
# hist['epoch'] = history.epoch
# tail = hist.tail()
# print(f" \n tail = \n {tail} \n ")

# plot_history(history)

# loss, mae, mse = model.evaluate(normed_test_data, test_labels, verbose=2)
# print(f" loss ={loss} , mae ={mae} , mse ={mse}")

test_predictions = model.predict(normed_test_data).flatten()

plt.scatter(test_labels, test_predictions)
plt.xlabel('True Values [MPG]')
plt.ylabel('Predictions [MPG]')
plt.axis('equal')
plt.axis('square')
plt.xlim([0, plt.xlim()[1]])
plt.ylim([0, plt.ylim()[1]])
_ = plt.plot([-100, 100], [-100, 100])

# 添加网格
plt.grid(True, linestyle='--', alpha=0.5)

plt.legend()
plt.show()

运行结果为

image-20210602131908866

五 保存和恢复模型

模型可以在训练期间和训练完成后进行保存。这意味着模型可以从任意中断中恢复,并避免耗费比较长的时间在训练上。保存也意味着您可以共享您的模型,而其他人可以通过您的模型来重新创建工作。在发布研究模型和技术时,大多数机器学习从业者分享:

  • 用于创建模型的代码
  • 模型训练的权重 (weight) 和参数 (parameters) 。

共享数据有助于其他人了解模型的工作原理,并使用新数据自行尝试。

5.1 配置

安装并导入

安装并导入Tensorflow和依赖项:

1
pip install -q pyyaml h5py  # 以 HDF5 格式保存模型所必须

5.2 获取示例数据集

要演示如何保存和加载权重,您将使用 MNIST 数据集. 要加快运行速度,请使用前1000个示例:

1
2
3
4
5
6
7
8
9
10
def prepare():
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()

train_labels = train_labels[:1000]
test_labels = test_labels[:1000]

train_images = train_images[:1000].reshape(-1, 28 * 28) / 255.0
test_images = test_images[:1000].reshape(-1, 28 * 28) / 255.0

return train_labels, test_labels, train_images, test_images

5.3 定义模型

首先构建一个简单的序列(sequential)模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import tensorflow as tf
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras



def exec():
model = tf.keras.models.Sequential([
keras.layers.Dense(512, activation='relu', input_shape=(784,)),
keras.layers.Dropout(0.2),
keras.layers.Dense(10)
])

model.compile(optimizer='adam',
loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])

return model


if __name__ == "__main__":
# 准备数据
# dataset = prepare()

# 获取模型
model = exec()

# 显示模型的结构
summary_info = model.summary()

print(f"\n 模型的结构为 {summary_info} \n")

运行结果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 512) 401920
_________________________________________________________________
dropout (Dropout) (None, 512) 0
_________________________________________________________________
dense_1 (Dense) (None, 10) 5130
=================================================================
Total params: 407,050
Trainable params: 407,050
Non-trainable params: 0
_________________________________________________________________
模型的结构为 None

5.4 保存模型(checkpoints 形式)

在训练期间保存模型(以 checkpoints 形式保存)

您可以使用训练好的模型而无需从头开始重新训练,或在您打断的地方开始训练,以防止训练过程没有保存。 tf.keras.callbacks.ModelCheckpoint 允许在训练的过程中结束时回调保存的模型。

5.4.1 Checkpoint 回调用法

创建一个只在训练期间保存权重的 tf.keras.callbacks.ModelCheckpoint 回调:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
checkpoint_path = "chk/demo.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

# 创建一个保存模型权重的回调
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path,
save_weights_only=True,
verbose=1)

# 使用新的回调训练模型
model.fit(train_images,
train_labels,
epochs=10,
validation_data=(test_images,test_labels),
callbacks=[cp_callback]) # 通过回调训练

# 这可能会生成与保存优化程序状态相关的警告。
# 这些警告(以及整个笔记本中的类似警告)
# 是防止过时使用,可以忽略。

完整的代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import os

import tensorflow as tf
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def prepare():
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()

train_labels = train_labels[:1000]
test_labels = test_labels[:1000]

train_images = train_images[:1000].reshape(-1, 28 * 28) / 255.0
test_images = test_images[:1000].reshape(-1, 28 * 28) / 255.0

return train_labels, test_labels, train_images, test_images


def exec(train_images, train_labels, test_images, test_labels):
model = tf.keras.models.Sequential([
keras.layers.Dense(512, activation='relu', input_shape=(784,)),
keras.layers.Dropout(0.2),
keras.layers.Dense(10)
])

model.compile(optimizer='adam',
loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])

checkpoint_path = "chk/demo.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

# 创建一个保存模型权重的回调
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path,
save_weights_only=True,
verbose=1)
# 使用新的回调训练模型
model.fit(train_images,
train_labels,
epochs=10,
validation_data=(test_images, test_labels),
callbacks=[cp_callback]) # 通过回调训练

# 这可能会生成与保存优化程序状态相关的警告。
# 这些警告(以及整个笔记本中的类似警告)
# 是防止过时使用,可以忽略。

return model


if __name__ == "__main__":
# 准备数据
train_labels, test_labels, train_images, test_images = prepare()

# 获取模型
model = exec(train_images, train_labels, test_images, test_labels)

# 显示模型的结构
summary_info = model.summary()

print(f"\n 模型的结构为 {summary_info} \n")

这将创建一个 TensorFlow checkpoint 文件集合,这些文件在每个 epoch 结束时更新,运行成功后,在项目chk目录下会生成以下文件

image-20210602134330172

创建一个新的未经训练的模型。仅恢复模型的权重时,必须具有与原始模型具有相同网络结构的模型。由于模型具有相同的结构,您可以共享权重,尽管它是模型的不同实例。 现在重建一个新的未经训练的模型,并在测试集上进行评估。未经训练的模型将在机会水平(chance levels)上执行(准确度约为10%):

1
2
3
4
5
6
# 获取模型
model = exec(train_images, train_labels, test_images, test_labels)

# 评估模型
loss, acc = model.evaluate(test_images, test_labels, verbose=2)
print("Untrained model, accuracy: {:5.2f}%".format(100*acc))

运行结果为

1
2
32/32 - 0s - loss: 2.3734 - accuracy: 0.0990
Untrained model, accuracy: 9.90%

5.4.2 checkpoint 回调选项

回调提供了几个选项,为 checkpoint 提供唯一名称并调整 checkpoint 频率。

训练一个新模型,每五个 epochs 保存一次唯一命名的 checkpoint :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 在文件名中包含 epoch (使用 `str.format`)
checkpoint_path = "training_2/cp-{epoch:04d}.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

# 创建一个回调,每 5 个 epochs 保存模型的权重
cp_callback = tf.keras.callbacks.ModelCheckpoint(
filepath=checkpoint_path,
verbose=1,
save_weights_only=True,
period=5)

# 创建一个新的模型实例
model = create_model()

# 使用 `checkpoint_path` 格式保存权重
model.save_weights(checkpoint_path.format(epoch=0))

# 使用新的回调训练模型
model.fit(train_images,
train_labels,
epochs=50,
callbacks=[cp_callback],
validation_data=(test_images,test_labels),
verbose=0)

注意: 默认的 tensorflow 格式仅保存最近的5个 checkpoint 。

如果要进行测试,请重置模型并加载最新的 checkpoint :

1
2
3
4
5
6
7
8
9
# 创建一个新的模型实例
model = create_model()

# 加载以前保存的权重
model.load_weights(latest)

# 重新评估模型
loss, acc = model.evaluate(test_images, test_labels, verbose=2)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))

5.4.3 文件内容

上述代码将权重存储到 checkpoint—— 格式化文件的集合中,这些文件仅包含二进制格式的训练权重。 Checkpoints 包含:

  • 一个或多个包含模型权重的分片。
  • 索引文件,指示哪些权重存储在哪个分片中。

如果你只在一台机器上训练一个模型,你将有一个带有后缀的碎片: .data-00000-of-00001

5.5 加载模型(checkpoints 形式)

然后从 checkpoint 加载权重并重新评估:

1
2
3
4
5
6
# 加载权重
model.load_weights(checkpoint_path)

# 重新评估模型
loss,acc = model.evaluate(test_images, test_labels, verbose=2)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))

完整的代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import tensorflow as tf
import os

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def prepare():
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()

train_labels = train_labels[:1000]
test_labels = test_labels[:1000]

train_images = train_images[:1000].reshape(-1, 28 * 28) / 255.0
test_images = test_images[:1000].reshape(-1, 28 * 28) / 255.0

return train_labels, test_labels, train_images, test_images


# 定义一个简单的序列模型
def exec():
model = tf.keras.models.Sequential([
keras.layers.Dense(512, activation='relu', input_shape=(784,)),
keras.layers.Dropout(0.2),
keras.layers.Dense(10)
])

model.compile(optimizer='adam',
loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])

return model


if __name__ == "__main__":
model = exec()

# 准备数据
train_labels, test_labels, train_images, test_images = prepare()

checkpoint_path = "chk/demo.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

# 加载权重
model.load_weights(checkpoint_path)

# 重新评估模型
loss, acc = model.evaluate(test_images, test_labels, verbose=2)
print(f"\n加载模型后损失率为 {loss} ,准确率为 {acc}")

运行结果为

1
2
3
32/32 - 0s - loss: 0.3934 - accuracy: 0.8760

加载模型后损失率为 0.393374502658844 ,准确率为 0.8759999871253967

5.6 手动保存权重

您将了解如何将权重加载到模型中。使用 Model.save_weights 方法手动保存它们同样简单。默认情况下, tf.kerassave_weights 特别使用 TensorFlow checkpoints 格式 .ckpt 扩展名和 ( 保存在 HDF5 扩展名为 .h5 保存并序列化模型 ):

1
2
3
4
5
6
7
8
9
10
11
12
# 保存权重
model.save_weights('./checkpoints/my_checkpoint')

# 创建模型实例
model = create_model()

# 恢复权重
model.load_weights('./checkpoints/my_checkpoint')

# 评估模型
loss,acc = model.evaluate(test_images, test_labels, verbose=2)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))

5.7 保存整个模型

调用 model.save 将保存模型的结构,权重和训练配置保存在单个文件/文件夹中。这可以让您导出模型,以便在不访问原始 Python 代码的情况下使用它。因为优化器状态(optimizer-state)已经恢复,您可以从中断的位置恢复训练。

整个模型可以以两种不同的文件格式(SavedModelHDF5)进行保存。需要注意的是 TensorFlow 的 SavedModel 格式是 TF2.x. 中的默认文件格式。但是,模型仍可以以 HDF5 格式保存。下面介绍了以两种文件格式保存整个模型的更多详细信息。

保存完整模型会非常有用——您可以在 TensorFlow.js(Saved Model, HDF5)加载它们,然后在 web 浏览器中训练和运行它们,或者使用 TensorFlow Lite 将它们转换为在移动设备上运行(Saved Model, HDF5

自定义对象(例如,子类化模型或层)在保存和加载时需要特别注意。请参阅下面的*保存自定义对象部分

5.7.1 SavedModel 格式

5.7.1.1 保存模型

SavedModel 格式是序列化模型的另一种方法。以这种格式保存的模型,可以使用 tf.keras.models.load_model 还原,并且模型与 TensorFlow Serving 兼容。SavedModel 指南详细介绍了如何提供/检查 SavedModel。以下部分说明了保存和还原模型的步骤。

1
2
3
4
5
6
# 创建并训练一个新的模型实例。
model = create_model()
model.fit(train_images, train_labels, epochs=5)

# 将整个模型另存为 SavedModel。
model.save('saved_model/my_model')

完整代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import os

import tensorflow as tf
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def prepare():
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()

train_labels = train_labels[:1000]
test_labels = test_labels[:1000]

train_images = train_images[:1000].reshape(-1, 28 * 28) / 255.0
test_images = test_images[:1000].reshape(-1, 28 * 28) / 255.0

return train_labels, test_labels, train_images, test_images


# 定义一个简单的序列模型
def exec():
model = tf.keras.models.Sequential([
keras.layers.Dense(512, activation='relu', input_shape=(784,)),
keras.layers.Dropout(0.2),
keras.layers.Dense(10)
])

model.compile(optimizer='adam',
loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])

return model


if __name__ == "__main__":
# 准备数据
train_labels, test_labels, train_images, test_images = prepare()
# 获取模型
model = exec()

# 训练模型
model.fit(train_images, train_labels, epochs=5)

# 保存模型
model.save('saved_model/my_model')

运行成功后,会在项目路劲下生成以下文件

image-20210602140554659

SavedModel 格式是一个包含 protobuf 二进制文件和 Tensorflow 检查点(checkpoint)的目录。检查保存的模型目录:

5.7.1.2 加载模型

从保存的模型重新加载新的 Keras 模型:

1
2
3
4
new_model = tf.keras.models.load_model('saved_model/my_model')

# 检查其架构
new_model.summary()

还原的模型使用与原始模型相同的参数进行编译。 尝试使用加载的模型运行评估和预测:

1
2
# 评估还原的模型
loss, acc = new_model.evaluate(test_images, test_labels, verbose=2)

完整的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import os

import tensorflow as tf

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def prepare():
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()

train_labels = train_labels[:1000]
test_labels = test_labels[:1000]

train_images = train_images[:1000].reshape(-1, 28 * 28) / 255.0
test_images = test_images[:1000].reshape(-1, 28 * 28) / 255.0

return train_labels, test_labels, train_images, test_images


if __name__ == "__main__":
# 准备数据
train_labels, test_labels, train_images, test_images = prepare()
# 获取模型
new_model = tf.keras.models.load_model('saved_model/my_model')

# 评估还原的模型
loss, acc = new_model.evaluate(test_images, test_labels, verbose=2)

print(f" 加载模型后运行的结果为 损失率 = {loss} ,准确率 ={acc}")

运行结果为

1
2
3
4
当前的tensorflow版本为  2.5.0  

32/32 - 0s - loss: 0.4202 - accuracy: 0.8590
加载模型后运行的结果为 损失率 = 0.4201943576335907 ,准确率 =0.859000027179718

5.7.2 HDF5 格式

Keras使用 HDF5 标准提供了一种基本的保存格式。

1
2
3
4
5
6
7
# 创建并训练一个新的模型实例
model = create_model()
model.fit(train_images, train_labels, epochs=5)

# 将整个模型保存为 HDF5 文件。
# '.h5' 扩展名指示应将模型保存到 HDF5。
model.save('my_model.h5')

现在,从该文件重新创建模型:

1
2
3
4
5
# 重新创建完全相同的模型,包括其权重和优化程序
new_model = tf.keras.models.load_model('my_model.h5')

# 显示网络结构
new_model.summary()

检查其准确率(accuracy):

1
2
3
4
loss, acc = new_model.evaluate(test_images,  test_labels, verbose=2)
print('Restored model, accuracy: {:5.2f}%'.format(100*acc))
32/32 - 0s - loss: 0.4639 - accuracy: 0.0840
Restored model, accuracy: 8.40%

Keras 通过检查网络结构来保存模型。这项技术可以保存一切:

  • 权重值
  • 模型的架构
  • 模型的训练配置(您传递给编译的内容)
  • 优化器及其状态(如果有的话)(这使您可以在中断的地方重新开始训练)

Keras 无法保存 v1.x 优化器(来自 tf.compat.v1.train),因为它们与检查点不兼容。对于 v1.x 优化器,您需要在加载-失去优化器的状态后,重新编译模型。

5.8.3 保存自定义对象

如果使用的是 SavedModel 格式,则可以跳过此部分。HDF5 和 SavedModel 之间的主要区别在于,HDF5 使用对象配置保存模型结构,而 SavedModel 保存执行图。因此,SavedModel 能够保存自定义对象,例如子类化模型和自定义层,而无需原始代码。

要将自定义对象保存到 HDF5,必须执行以下操作:

  1. 在对象中定义一个get_config方法,以及可选的 from_config类方法。

    • get_config(self) 返回重新创建对象所需的参数的 JSON 可序列化字典。
  • from_config(cls, config) 使用从 get_config 返回的 config 来创建一个新对象。默认情况下,此函数将使用 config 作为初始化 kwargs(return cls(**config))。
  1. 加载模型时,将对象传递给 custom_objects 参数。参数必须是将字符串类名称映射到 Python 类的字典。例如,tf.keras.models.load_model(path, custom_objects={'CustomLayer': CustomLayer})

六 卷积神经网络

6.1 准备数据

CIFAR10 数据集包含 10 类,共 60000 张彩色图片,每类图片有 6000 张。此数据集中 50000 个样例被作为训练集,剩余 10000 个样例作为测试集。类之间相互独立,不存在重叠的部分

1
2
3
4
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()

# 将像素的值标准化至0到1的区间内。
train_images, test_images = train_images / 255.0, test_images / 255.0

6.2 构造卷积神经网络模型

下方展示的 6 行代码声明了了一个常见卷积神经网络,由几个 Conv2DMaxPooling2D 层组成。

CNN 的输入是张量 (Tensor) 形式的 (image_height, image_width, color_channels),包含了图像高度、宽度及颜色信息。不需要输入 batch size。如果您不熟悉图像处理,颜色信息建议您使用 RGB 色彩模式,此模式下,color_channels(R,G,B) 分别对应 RGB 的三个颜色通道(color channel)。在此示例中,我们的 CNN 输入,CIFAR 数据集中的图片,形状是 (32, 32, 3)。您可以在声明第一层时将形状赋值给参数 input_shape

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
model = models.Sequential()

# 卷积层,参见1.4.3.2
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))

# 池化层 参见1.4.4.1
model.add(layers.MaxPooling2D((2, 2)))

# 卷积层,参见1.4.3.2
model.add(layers.Conv2D(64, (3, 3), activation='relu'))

# 池化层 参见1.4.4.1
model.add(layers.MaxPooling2D((2, 2)))

# 卷积层,参见1.4.3.2
model.add(layers.Conv2D(64, (3, 3), activation='relu'))

完整代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import tensorflow as tf

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def exec():
model = keras.models.Sequential()

# 卷积层,参见1.4.3.2
model.add(keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))

# 池化层 参见1.4.4.1
model.add(keras.layers.MaxPooling2D((2, 2)))

# 卷积层,参见1.4.3.2
model.add(keras.layers.Conv2D(64, (3, 3), activation='relu'))

# 池化层 参见1.4.4.1
model.add(keras.layers.MaxPooling2D((2, 2)))

# 卷积层,参见1.4.3.2
model.add(keras.layers.Conv2D(64, (3, 3), activation='relu'))

return model


if __name__ == "__main__":
model = exec()
model.summary()

运行结果为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 30, 30, 32) 896
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 15, 15, 32) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 13, 13, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 6, 6, 64) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 4, 4, 64) 36928
=================================================================
Total params: 56,320
Trainable params: 56,320
Non-trainable params: 0
_________________________________________________________________

在上面的结构中,您可以看到每个 Conv2D 和 MaxPooling2D 层的输出都是一个三维的张量 (Tensor),其形状描述了 (height, width, channels)。越深的层中,宽度和高度都会收缩。每个 Conv2D 层输出的通道数量 (channels) 取决于声明层时的第一个参数(如:上面代码中的 32 或 64)。这样,由于宽度和高度的收缩,您便可以(从运算的角度)增加每个 Conv2D 层输出的通道数量 (channels)。

6.3 增加 Dense 层

Dense 层等同于全连接 (Full Connected) 层。
在模型的最后,您将把卷积后的输出张量(本例中形状为 (4, 4, 64))传给一个或多个 Dense 层来完成分类。Dense 层的输入为向量(一维),但前面层的输出是3维的张量 (Tensor)。因此您需要将三维张量展开 (flatten) 到1维,之后再传入一个或多个 Dense 层。CIFAR 数据集有 10 个类,因此您最终的 Dense 层需要 10 个输出及一个 softmax 激活函数。

1
2
3
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))

完整代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import tensorflow as tf

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def exec():
model = keras.models.Sequential()

# 卷积层,参见1.4.3.2
model.add(keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))

# 池化层 参见1.4.4.1
model.add(keras.layers.MaxPooling2D((2, 2)))

# 卷积层,参见1.4.3.2
model.add(keras.layers.Conv2D(64, (3, 3), activation='relu'))

# 池化层 参见1.4.4.1
model.add(keras.layers.MaxPooling2D((2, 2)))

# 卷积层,参见1.4.3.2
model.add(keras.layers.Conv2D(64, (3, 3), activation='relu'))

# 在模型的最后,您将把卷积后的输出张量(本例中形状为 (4, 4, 64))
# 传给一个或多个 Dense 层来完成分类。Dense 层的输入为向量(一维)
# ,但前面层的输出是3维的张量 (Tensor)。
# 因此您需要将三维张量展开 (flatten) 到1维,
# 之后再传入一个或多个 Dense 层。CIFAR 数据集有 10 个类,
# 因此您最终的 Dense 层需要 10 个输出及一个 softmax 激活函数
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(64, activation='relu'))
model.add(keras.layers.Dense(10))

return model


if __name__ == "__main__":
model = exec()
model.summary()

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 30, 30, 32) 896
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 15, 15, 32) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 13, 13, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 6, 6, 64) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 4, 4, 64) 36928
_________________________________________________________________
flatten (Flatten) (None, 1024) 0
_________________________________________________________________
dense (Dense) (None, 64) 65600
_________________________________________________________________
dense_1 (Dense) (None, 10) 650
=================================================================
Total params: 122,570
Trainable params: 122,570
Non-trainable params: 0
_________________________________________________________________

可以看出,在被传入两个 Dense 层之前,形状为 (4, 4, 64) 的输出被展平成了形状为 (1024) 的向量。

6.4 编译并训练模型

1
2
3
4
5
6
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])

history = model.fit(train_images, train_labels, epochs=10,
validation_data=(test_images, test_labels))

6.5 评估模型

1
2
3
4
5
6
7
8
9
plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label = 'val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.ylim([0.5, 1])
plt.legend(loc='lower right')
plt.show()

test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)

6.6 完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import tensorflow as tf
import matplotlib as mpl
import matplotlib.pyplot as plt

print("\n 当前的tensorflow版本为 ", tf.__version__, " \n")

keras = tf.keras


def prepare():
(train_images, train_labels), (test_images, test_labels) = keras.datasets.cifar10.load_data()

# 将像素的值标准化至0到1的区间内。
train_images, test_images = train_images / 255.0, test_images / 255.0
return train_images, test_images, train_labels, test_labels


def exec():
model = keras.models.Sequential()

# 卷积层,参见1.4.3.2
model.add(keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)))

# 池化层 参见1.4.4.1
model.add(keras.layers.MaxPooling2D((2, 2)))

# 卷积层,参见1.4.3.2
model.add(keras.layers.Conv2D(64, (3, 3), activation='relu'))

# 池化层 参见1.4.4.1
model.add(keras.layers.MaxPooling2D((2, 2)))

# 卷积层,参见1.4.3.2
model.add(keras.layers.Conv2D(64, (3, 3), activation='relu'))

# 在模型的最后,您将把卷积后的输出张量(本例中形状为 (4, 4, 64))
# 传给一个或多个 Dense 层来完成分类。Dense 层的输入为向量(一维)
# ,但前面层的输出是3维的张量 (Tensor)。
# 因此您需要将三维张量展开 (flatten) 到1维,
# 之后再传入一个或多个 Dense 层。CIFAR 数据集有 10 个类,
# 因此您最终的 Dense 层需要 10 个输出及一个 softmax 激活函数
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(64, activation='relu'))
model.add(keras.layers.Dense(10))

model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
return model


def draw(history):
plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label='val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.ylim([0.5, 1])
plt.legend(loc='lower right')
# 添加网格显示
plt.grid(True, linestyle='--', alpha=0.5)
plt.show()


if __name__ == "__main__":
# 获取模型
model = exec()

# 获取数据
train_images, test_images, train_labels, test_labels = prepare()

history = model.fit(train_images, train_labels, epochs=10,
validation_data=(test_images, test_labels))

# 测试
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print(f"测试出来的 损失值为 {test_loss} ,准确值为 {test_acc}")

# 画图
draw(history)

得到的结果为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 当前的tensorflow版本为  2.5.0  

Epoch 1/10
1563/1563 [==============================] - 23s 14ms/step - loss: 1.5279 - accuracy: 0.4427 - val_loss: 1.2543 - val_accuracy: 0.5501
Epoch 2/10
1563/1563 [==============================] - 22s 14ms/step - loss: 1.1673 - accuracy: 0.5866 - val_loss: 1.1190 - val_accuracy: 0.6091
Epoch 3/10
1563/1563 [==============================] - 22s 14ms/step - loss: 1.0213 - accuracy: 0.6431 - val_loss: 1.0253 - val_accuracy: 0.6353
Epoch 4/10
1563/1563 [==============================] - 22s 14ms/step - loss: 0.9172 - accuracy: 0.6783 - val_loss: 0.9695 - val_accuracy: 0.6632
Epoch 5/10
1563/1563 [==============================] - 22s 14ms/step - loss: 0.8434 - accuracy: 0.7060 - val_loss: 0.9179 - val_accuracy: 0.6788
Epoch 6/10
1563/1563 [==============================] - 21s 14ms/step - loss: 0.7872 - accuracy: 0.7239 - val_loss: 0.9463 - val_accuracy: 0.6734
Epoch 7/10
1563/1563 [==============================] - 22s 14ms/step - loss: 0.7286 - accuracy: 0.7447 - val_loss: 0.9512 - val_accuracy: 0.6702
Epoch 8/10
1563/1563 [==============================] - 22s 14ms/step - loss: 0.6828 - accuracy: 0.7596 - val_loss: 0.8734 - val_accuracy: 0.7040
Epoch 9/10
1563/1563 [==============================] - 22s 14ms/step - loss: 0.6421 - accuracy: 0.7749 - val_loss: 0.8988 - val_accuracy: 0.6996
Epoch 10/10
1563/1563 [==============================] - 22s 14ms/step - loss: 0.6028 - accuracy: 0.7880 - val_loss: 0.8431 - val_accuracy: 0.7208
313/313 - 1s - loss: 0.8431 - accuracy: 0.7208
测试出来的 损失值为 0.8431219458580017 ,准确值为 0.72079998254776

image-20210602152053184