Tensorflow2.x学习——4.Keras、层与模型

本系列为tensorflow官方教程与文档学习笔记,结合个人理解提取其中的关键内容,便于日后复习。

1. Keras、层与模型

1.1 建立一个简单的模型

1.1.1 序贯模型

tf.keras.Sequential支持方便地搭建序贯式模型:

import tensorflow as tf
from tensorflow.keras import layers

model = tf.keras.Sequential()
model.add(layers.Dense(64, activation = 'relu'))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10))

1.1.2 层的参数设置

所有的层对象都有相同的三个重要参数:

  1. activation:激活函数,缺省情况下没有激活函数
  2. kernel_initializerbias_initializer:该层的权重参数和偏置参数初始化的方法,缺省情况下分别为 "Glorot uniform" 和全零初始化;
  3. kernel_regularizerbias_regularizer:正则化参数。
# Create a relu layer:
layers.Dense(64, activation='relu')
# Or:
layers.Dense(64, activation=tf.nn.relu)

# A linear layer with L1 regularization of factor 0.01 applied to the kernel matrix:
layers.Dense(64, kernel_regularizer=tf.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=tf.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=tf.keras.initializers.Constant(2.0))

1.2 训练与评估

1.2.1 模型训练

在训练模型前需要先通过compile方法对模型进行编译:

model.compile(optimizer=tf.keras.optimizers.Adam(0.01),
              loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

compile方法中接收三个较为重要的参数:

  • optimizer:传入tf.keras.optimizers中的对象,如 tf.keras.optimizers.Adamtf.keras.optimizers.SGD
  • loss:损失函数, 传入tf.keras.losses 中的对象;
  • metircs:评估函数,以列表的方式传入;

通过tf.keras.Model.fit方法训练模型,方法接收三个重要参数:

  • epochs:数据训练的代数(即整个数据集在模型中输入输出epochs次);
  • batch_size:当传入numpy数据时,通过此参数决定批量的大小;
  • validation_data:测试数据,以元组的形式(features, labels)传入

训练模型时传入的数据可以有两种方式:

1. 传入numpy数据:

适用于数据集较小的情况。

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)

2. 传入dataset数据:

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

model.fit(dataset, epochs=10)

dataset对象可以生成相应的batch,因此fit方法中无需再传入batch_size参数。

dataset也可以用以评估:

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

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

model.fit(dataset, epochs=10,
          validation_data=val_dataset)

1.2.2 评估与预测

通过 tf.keras.Model.evaluatetf.keras.Model.predict 方法进行评估与预测。

# With Numpy arrays
data = np.random.random((1000, 32))
labels = np.random.random((1000, 10))

model.evaluate(data, labels, batch_size=32)

# With a Dataset
dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32)

model.evaluate(dataset)

result = model.predict(data, batch_size=32)
  • evaluate会使用定义的lossmetrics进行评估;

1.3 Keras的函数式API

通过Keras的函数式API可以实现更加复杂的模型,如:

  • 多输入模型;
  • 多输出模型;
  • 带有共享层的模型;
  • 带有非序贯式数据流的模型(如残差块);

通过函数式API建立序贯模型:

inputs = tf.keras.Input(shape=(32,))  # Returns an input placeholder

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

model = tf.keras.Model(inputs=inputs, outputs=predictions)

# The compile step specifies the training configuration.
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
              loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

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

1.4 编写自定义层与自定义模型

1.4.1 自定义模型

通过继承tf.keras.Model来编写自定义模型:

  • 重写__init__进行自定义初始化;
  • 重写call方法自定义前向传播过程。

例:

class MyModel(tf.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 = layers.Dense(32, activation='relu')
    self.dense_2 = layers.Dense(num_classes)

  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)

1.4.2 自定义层

继承tf.keras.layers.Layer来自定义层。需要实现以下方法:

  • __init__:自定义初始化方法;
  • build:为层创建权重,通过add_weight`方法添加权重;
  • call: 自定义前向传播过程。
  • 可以通过 get_config成员方法和 from_config类方法定义序列化规则。

例:

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

      def build(self, input_shape):
        # Create a trainable weight variable for this layer.
        self.kernel = self.add_weight(name='kernel',
                                      shape=(input_shape[1], self.output_dim),
                                      initializer='uniform',
                                      trainable=True)

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

      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)

model = tf.keras.Sequential([
    MyLayer(10)])

# The compile step specifies the training configuration
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
              loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

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

1.5 自定义回调函数

回调函数可以用于 tf.keras.Model.fit(), tf.keras.Model.evaluate(), 和 tf.keras.Model.predict(),内置的tf.keras.callbacks包括:

  • tf.keras.callbacks.ModelCheckpoint: 在规定的时机存储检查点;
  • tf.keras.callbacks.LearningRateScheduler: 动态改变学习率;
  • tf.keras.callbacks.EarlyStopping: 训练效果不再提升时提前终止训练;
  • tf.keras.callbacks.TensorBoard: 在TensorBoard中进行可视化。

例:

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

编写自定义回调函数:

编写自定义类继承tf.keras.callbacks.Callback,重写其中的方法:

import datetime

class MyCustomCallback(tf.keras.callbacks.Callback):

      def on_train_batch_begin(self, batch, logs=None):
        print('Training: batch {} begins at {}'.format(batch, datetime.datetime.now().time()))

      def on_train_batch_end(self, batch, logs=None):
        print('Training: batch {} ends at {}'.format(batch, datetime.datetime.now().time()))

      def on_test_batch_begin(self, batch, logs=None):
        print('Evaluating: batch {} begins at {}'.format(batch, datetime.datetime.now().time()))

      def on_test_batch_end(self, batch, logs=None):
        print('Evaluating: batch {} ends at {}'.format(batch, datetime.datetime.now().time()))
        
_ = model.fit(x_train, y_train,
          batch_size=64,
          epochs=1,
          steps_per_epoch=5,
          verbose=0,
          callbacks=[MyCustomCallback()])

可以重写的方法列表:

  • on_(train|test|predict)_begin(self, logs=None)

  • on_(train|test|predict)_end(self, logs=None)

  • on_(train|test|predict)_batch_begin(self, batch, logs=None)

  • on_(train|test|predict)_batch_end(self, batch, logs=None)

特别的,对于训练而言,有两个作用于每一个epoch特殊的方法:

  • on_epoch_begin(self, epoch, logs=None)

  • on_epoch_end(self, epoch, logs=None)

1.6 保存与序列化模型

本小节中所指的模型为“Keras模型”。

Keras的API允许保存模型中的指定内容,如:

  • 将模型的所有内容(架构、权重等)保存到 TensorFlow SavedModel格式的文件中(或旧版本的Keras H5格式),官方建议使用SavedModel格式。
  • 保存模型的架构(以JSON格式)。
  • 只保存模型的权重系数。

相关的API:

  • model.save() or tf.keras.models.save_model():默认情况下保存为SavedModel形式
  • tf.keras.models.load_model()
# Saving
model = ...  # Get model (Sequential, Functional Model, or Model subclass)
model.save('path/to/location')

# Loading
from tensorflow import keras
model = keras.models.load_model('path/to/location')

你可能感兴趣的:(深度学习,tensorflow,深度学习)