TensorFlow Keras 官方教程

TensorFlow版本:1.10.0 > Guide >
教程地址:https://tensorflow.google.cn/guide/keras

Keras 简介

Keras是一个用于构建和训练深度学习模型的高级API。 它用于快速原型设计,高级研究和生产,具有三个主要优点:

  • 用户友好
    Keras具有针对常见用例优化的简单,一致的界面。 它为用户错误提供清晰且可操作的反馈。
  • 模块化和可组合
    Keras模型是通过将可配置的构建块连接在一起而制定的,几乎没有限制。
  • 易于扩展
    编写自定义构建块以表达研究的新想法。 创建新图层,损失函数并开发最先进的模型。

1. 导入 tf.keras

tf.kerasKeras API 在TensorFlow 里的实现。这是一个高级API,用于构建和训练模型,同时兼容 TensorFlow 的绝大部分功能,比如,eager executiontf.data模块及 Estimatorstf.keras使得 TensorFlow 更容易使用,且保持 TF 的灵活性和性能。
首先需要在您的代码开始时导入tf.keras:

import tensorflow as tf
from tensorflow import keras

tf.keras可以运行任何与Keras兼容的代码,但请记住:

  • 最新TensorFlow版本中的tf.keras版本可能与PyPI的最新keras版本不同。 检查tf.keras.version。
  • 保存模型的权重时,tf.keras默认为 checkpoint 格式。 通过save_format ='h5'使用HDF5。

2. 构建一个简单的模型

2.1 Sequential model

在Keras中,您可以组装图层来构建模型。 模型(通常)是图层图。 最常见的模型类型是一堆层:tf.keras.Sequential 模型。
构建一个简单的全连接网络(即多层感知器):

model = keras.Sequential()
# 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'))

2.2 Configure the layers

在 tf.keras.layers 中有很多层,下面是一些通用的构造函数的参数:

  • activation:设置层的激活函数。 此参数由内置函数的名称或可调用对象指定。 默认情况下,不应用任何激活。
  • kernel_initializerbias_initializer:设置层创建时,权重和偏差的初始化方法。指定方法:名称 或 可调用对象。默认为"Glorot uniform" initializer。
  • kernel_regularizerbias_regularizer:设置层的权重、偏差的正则化方法。比如:L1 或 L2 正则。默认为空。
    以下实例化tf.keras。 layers.Dense图层使用构造函数参数:
# Create a sigmoid layer:
layers.Dense(64, activation='sigmoid')
# Or:
layers.Dense(64, activation=tf.sigmoid)

# A linear layer with L1 regularization of factor 0.01 applied to the kernel matrix:
layers.Dense(64, kernel_regularizer=keras.regularizers.l1(0.01))
# A linear layer with L2 regularization of factor 0.01 applied to the bias vector:
layers.Dense(64, bias_regularizer=keras.regularizers.l2(0.01))

# A linear layer with a kernel initialized to a random orthogonal matrix:
layers.Dense(64, kernel_initializer='orthogonal')
# A linear layer with a bias vector initialized to 2.0s:
layers.Dense(64, bias_initializer=keras.initializers.constant(2.0))

3. Train and evaluate

3.1 Set up training

构建模型后,通过调用compile方法配置其训练过程:

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

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

  • optimizer:训练过程的优化方法。此参数通过 tf.train 模块的优化方法的实例来指定,比如:AdamOptimizerRMSPropOptimizerGradientDescentOptimizer
  • loss:训练过程中使用的损失函数(通过最小化损失函数来训练模型)。 常见的选择包括:均方误差(mse),categorical_crossentropy和binary_crossentropy。 损失函数由名称或通过从tf.keras.losses模块传递可调用对象来指定。
  • metrics:训练过程中,监测的指标(Used to monitor training)。
    指定方法:名称 或 可调用对象 from the tf.keras.metrics 模块。
    以下显示了配置培训模型的几个示例:
# Configure a model for mean-squared error regression.
model.compile(optimizer=tf.train.AdamOptimizer(0.01),
              loss='mse',       # mean squared error
              metrics=['mae'])  # mean absolute error

# Configure a model for categorical classification.
model.compile(optimizer=tf.train.RMSPropOptimizer(0.01),
              loss=keras.losses.categorical_crossentropy,
              metrics=[keras.metrics.categorical_accuracy])

3.2 Input NumPy data

对于小的数据集,可以直接使用 NumPy 格式的数据进行训练、评估模型。模型使用 fit 方法训练数据:

import numpy as np

data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

model.fit(data, labels, epochs=10, batch_size=32)

tf.keras.Model.fit 有三个重要的参数:

  • epochs:训练多少轮。(小批量)
  • batch_size:当传递NumPy数据时,模型将数据分成较小的批次,并在训练期间迭代这些批次。 此整数指定每个批次的大小。 请注意,如果样本总数不能被批量大小整除,则最后一批可能会更小。
  • validation_data:在对模型进行原型设计时,您希望轻松监控其在某些验证数据上的性能。 传递这个参数 - 输入和标签的元组 - 允许模型在每个epoch的末尾以传递数据的推理模式显示损失和度量。
    这是使用validation_data的示例:
import numpy as np

data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

val_data = np.random.random((100, 32))
val_labels = np.random.random((100, 10))

model.fit(data, labels, epochs=10, batch_size=32,
          validation_data=(val_data, val_labels))

3.3 Input tf.data datasets

使用数据集API可扩展到大型数据集或多设备培训。 将tf.data.Dataset实例传递给fit方法:
使用 Datasets API 可扩展到大型数据集或多设备训练。 给 fit 方法传递一个 tf.data.Dataset 实例:

# Instantiates a toy dataset instance:
dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32)
dataset = dataset.repeat()

# Don't forget to specify `steps_per_epoch` when calling `fit` on a dataset.
model.fit(dataset, epochs=10, steps_per_epoch=30)

这里,fit方法使用steps_per_epoch参数 - 这是模型在移动到下一个epoch之前运行的训练步数。 由于数据集生成批量数据,因此此代码段不需要batch_size。
Dataset API 也可以用于验证:

dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32).repeat()

val_dataset = tf.data.Dataset.from_tensor_slices((val_data, val_labels))
val_dataset = val_dataset.batch(32).repeat()

model.fit(dataset, epochs=10, steps_per_epoch=30,
          validation_data=val_dataset,
          validation_steps=3)

3.4 Evaluate and predict

tf.keras.Model.evaluatetf.keras.Model.predict 方法能够使用 NumPy 数据 和 tf.data.Dataset 数据。
要评估所提供数据的推理模式损失和指标:

model.evaluate(x, y, batch_size=32)

model.evaluate(dataset, steps=30)

并且作为NumPy数组,预测所提供数据的推断中最后一层的输出:

model.predict(x, batch_size=32)

model.predict(dataset, steps=30)

4. Build advanced models

4.1 Functional API

tf.keras.Sequential 模型只适用于多层简单堆叠网络,不能表示复杂模型。使用 Keras functional API 可以构建有复杂拓扑结构的模型。比如:

  • 多输入模型(Multi-input models)
  • 多输出模型(Multi-output models)
  • 有共享层的模型(Models with shared layers (the same layer called several times))
  • 具有非顺序数据流的模型(Models with non-sequential data flows (e.g. residual connections))
    使用函数式API构建模型的工作方式如下:
  1. 层实例可调用并返回张量。
  2. 输入 tensors 和输出 tensors 被用来定义一个 tf.keras.Model 实例
  3. 这个模型的训练就像Sequential模型一样。
    以下示例使用函数式API构建一个简单,全连接的网络:
inputs = keras.Input(shape=(32,))  # Returns a placeholder tensor

# A layer instance is callable on a tensor, and returns a tensor.
x = keras.layers.Dense(64, activation='relu')(inputs)
x = keras.layers.Dense(64, activation='relu')(x)
predictions = keras.layers.Dense(10, activation='softmax')(x)

# Instantiate the model given inputs and outputs.
model = keras.Model(inputs=inputs, outputs=predictions)

# The compile step specifies the training configuration.
model.compile(optimizer=tf.train.RMSPropOptimizer(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Trains for 5 epochs
model.fit(data, labels, batch_size=32, epochs=5)

4.2 Model subclassing

通过继承tf.keras.Model并定义自己的前向传递来构建完全可自定义的模型。 在init方法中创建图层并将它们设置为类实例的属性。 在call方法中定义正向传递。

当启用eager执行时,模型子类化特别有用,因为可以强制写入正向传递。

提示:为工作使用正确的API。 虽然模型子类化提供了灵活性,但其代价是更高的复杂性和更多的用户错误机会。 如果可能,请选择功能API。

以下示例显示了使用自定义正向传递的子类tf.keras.Model:

class MyModel(keras.Model):

    def __init__(self, num_classes=10):
        super(MyModel, self).__init__(name='my_model')
        self.num_classes = num_classes
        # Define your layers here.
        self.dense_1 = keras.layers.Dense(32, activation='relu')
        self.dense_2 = keras.layers.Dense(num_classes, activation='sigmoid')

    def call(self, inputs):
        # Define your forward pass here,
        # using layers you previously defined (in `__init__`).
        x = self.dense_1(inputs)
        return self.dense_2(x)

  def compute_output_shape(self, input_shape):
      # You need to override this function if you want to use the subclassed model
      # as part of a functional-style model.
      # Otherwise, this method is optional.
      shape = tf.TensorShape(input_shape).as_list()
      shape[-1] = self.num_classes
      return tf.TensorShape(shape)


# Instantiates the subclassed model.
model = MyModel(num_classes=10)

# The compile step specifies the training configuration.
model.compile(optimizer=tf.train.RMSPropOptimizer(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Trains for 5 epochs.
model.fit(data, labels, batch_size=32, epochs=5)

4.3 自定义 layers

通过继承tf.keras.layers.Layer并实现以下方法来创建自定义层:

  • build:创建图层的权重。 使用add_weight方法添加权重。
  • call:定义前向传播过程。
  • compute_output_shape:指定在给定输入形状的情况下如何计算图层的输出形状。
  • 或者,可以通过实现get_config方法和from_config类方法来序列化层。
    这里有一个自定义 layer 的例子,该 layer 将输入和一个矩阵进行相乘:
class MyLayer(keras.layers.Layer):

    def __init__(self, output_dim, **kwargs):
        self.output_dim = output_dim
        super(MyLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        shape = tf.TensorShape((input_shape[1], self.output_dim))
        # Create a trainable weight variable for this layer.
       self.kernel = self.add_weight(name='kernel',
                                    shape=shape,
                                    initializer='uniform',
                                    trainable=True)
    # Be sure to call this at the end
    super(MyLayer, self).build(input_shape)

    def call(self, inputs):
        return tf.matmul(inputs, self.kernel)

    def compute_output_shape(self, input_shape):
        shape = tf.TensorShape(input_shape).as_list()
        shape[-1] = self.output_dim
        return tf.TensorShape(shape)

    def get_config(self):
        base_config = super(MyLayer, self).get_config()
        base_config['output_dim'] = self.output_dim
        return base_config

    @classmethod
    def from_config(cls, config):
        return cls(**config)

# Create a model using the custom layer
model = keras.Sequential([MyLayer(10),
                          keras.layers.Activation('softmax')])

# The compile step specifies the training configuration
model.compile(optimizer=tf.train.RMSPropOptimizer(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Trains for 5 epochs.
model.fit(data, targets, batch_size=32, epochs=5)

5. 回调(Callbacks)

回调是传递给模型的对象,用于在训练期间自定义和扩展其行为。 您可以编写自己的自定义回调,或使用包含以下内置的tf.keras.callbacks:

callbacks = [
    # Interrupt training if `val_loss` stops improving for over 2 epochs
    keras.callbacks.EarlyStopping(patience=2, monitor='val_loss'),
    # Write TensorBoard logs to `./logs` directory
    keras.callbacks.TensorBoard(log_dir='./logs')
]
model.fit(data, labels, batch_size=32, epochs=5, callbacks=callbacks,
            validation_data=(val_data, val_targets))

6. Save and restore

6.1 Weights only

使用 tf.keras.Model.save_weights 来保存和加载模型的 weights:

# Save weights to a TensorFlow Checkpoint file
model.save_weights('./my_model')

# Restore the model's state,
# this requires a model with the same architecture.
model.load_weights('my_model')

默认情况下,这会以 TensorFlow checkpoint 格式保存模型的 weights。weights 也可以保存为 HDF5 格式(Keras 默认的保存格式):

# Save weights to a HDF5 file
model.save_weights('my_model.h5', save_format='h5')

# Restore the model's state
model.load_weights('my_model.h5')

6.2 Configuration only

一个模型的 configuration 可以被保存,序列化过程中不包含任何 weights。保存的 configuration 可以用来重新创建、初始化出相同的模型,即使没有模型原始的定义代码。Keras 支持 JSON,YAML 序列化格式:

# Serialize a model to JSON format
json_string = model.to_json()

# Recreate the model (freshly initialized)
fresh_model = keras.models.model_from_json(json_string)

# Serializes a model to YAML format
yaml_string = model.to_yaml()

# Recreate the model
fresh_model = keras.models.model_from_yaml(yaml_string)

注意:子类模型不可序列化,因为它们的体系结构由调用方法体中的Python代码定义。

6.3 Entire model

整个模型可以保存到包含权重值,模型配置甚至优化器配置的文件中。 这允许您检查模型并稍后从完全相同的状态恢复训练 - 无需访问原始代码。

# Create a trivial model
model = keras.Sequential([
    keras.layers.Dense(10, activation='softmax', input_shape=(32,)),
    keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='rmsprop',
                loss='categorical_crossentropy',
                metrics=['accuracy'])
model.fit(data, targets, batch_size=32, epochs=5)

# Save entire model to a HDF5 file
model.save('my_model.h5')

# Recreate the exact same model, including weights and optimizer.
model = keras.models.load_model('my_model.h5')

7. Eager execution

Eager execution是一个必要的编程环境,可以立即评估操作。 这对于Keras不是必需的,但是由tf.keras支持,对于检查程序和调试很有用。
tf.keras 里所有的模型构建 API 兼容 eager execution。并且,在编写 model subclassingcustom layers 时使用 eager execution
虽然可以使用Sequential和函数式API,但是eager execution尤其有利于模型子类化和构建自定义层 - 需要您将正向传递作为代码编写的API(而不是通过组合现有层来创建模型的API)。

请看 eager execution guide 里的例子:使用 Keras models with custom training loops and tf.GradientTape

8. Distribution

8.1 Estimators

Estimators API 被用来在分布时环境训练模型。Estimator API 旨在大型数据集的分布式训练,该 API 能够导出工业生产可用的模型。

一个 tf.keras.Model 可以用 tf.estimator API 来训练(通过 tf.keras.estimator.model_to_estimator 将模型转为一个 tf.estimator.Estimator 对象)。详情见 Creating Estimators from Keras models

model = keras.Sequential([layers.Dense(10,activation='softmax'),
                          layers.Dense(10,activation='softmax')])

model.compile(optimizer=tf.train.RMSPropOptimizer(0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

estimator = keras.estimator.model_to_estimator(model)

注意: 可以通过开启 eager execution 来调试 Estimator input functions、检查数据。

8.2 Multiple GPUs

tf.keras 模型可以使用 tf.contrib.distribute.DistributionStrategy 在多个 GPU 上运行。此API在多个GPU上提供分布式培训,几乎不对现有代码进行任何更改。

当前,tf.contrib.distribute.MirroredStrategy 是唯一支持的分布式策略。MirroredStrategy 对图进行复制,以同步的方式训练,并且梯度最后聚集在一个机器上。 为了使用 DistributionStrategy with Keras,首先用 tf.keras.estimator.model_to_estimatortf.keras.Model 转化为一个 tf.estimator.Estimator,然后训练转化来的estimator。
以下示例在单个计算机上的多个GPU之间分发tf.keras.Model。
首先,定义一个简单的模型:

model = keras.Sequential()
model.add(keras.layers.Dense(16, activation='relu', input_shape=(10,)))
model.add(keras.layers.Dense(1, activation='sigmoid'))

optimizer = tf.train.GradientDescentOptimizer(0.2)

model.compile(loss='binary_crossentropy', optimizer=optimizer)
model.summary()

定义输入pipeline。 input_fn返回一个tf.data.Dataset对象,用于在多个设备之间分配数据 - 每个设备处理输入批处理的一部分。

def input_fn():
    x = np.random.random((1024, 10))
    y = np.random.randint(2, size=(1024, 1))
    x = tf.cast(x, tf.float32)
    dataset = tf.data.Dataset.from_tensor_slices((x, y))
    dataset = dataset.repeat(10)
    dataset = dataset.batch(32)
    return dataset

接下来,创建一个 tf.estimator.RunConfig 并设置 train_distribute 参数为 tf.contrib.distribute.MirroredStrategy 实例。当创建 MirroredStrategy 时,你可以指定一个设备列表 或 通过 num_gpus 参数设置 GPU 的数量。默认使用所有的 GPU。如下所示:

strategy = tf.contrib.distribute.MirroredStrategy()
config = tf.estimator.RunConfig(train_distribute=strategy)

将 Keras model 转为一个 tf.estimator.Estimator 实例。

keras_estimator = keras.estimator.model_to_estimator(
    keras_model=model,
    config=config,
    model_dir='/tmp/model_dir')

最后,通过提供input_fn和steps参数来训练Estimator实例:

keras_estimator.train(input_fn=input_fn, steps=10)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容