• 【tf.keras】官方教程一 Keras overview



    Sequential Model:(the simplest type of model)

    Getting started with the Keras Sequential model

    Specifying the input shape

    Compilation

    Training

    使用tf.keras建立一个简易的模型

    使用Numpy数组进行训练:

    使用tf.data 数据集进行训练

    验证和预测

    使用tf.keras构建复杂模型

    The functional API

    模型子类化(Model subclassing)

    定制层(Custom layers)

    Callbacks

    模型的保存与导入

    只保存权重

    只保存模型的配置文件:

    保存完整的模型在一个文件中  


      之前在研读MobileNet V3的源码时,其代码在基于TensorFlow框架中使用了tf.keras。在基于tf.keras下,模型的构建更加容易,也略显高级。再次附上MobileNet V3代码:https://github.com/Bisonai/mobilenetv3-tensorflow  

      官方教程:https://tensorflow.google.cn/guide/keras/overview

      tf.keras是TensorFlow实现的keras API规范。这是一个用于构建和训练模型的高级API,包含对tensorflow特定功能的支持。

    1 import tf.keras
    2 # form tensorflow import keras

      Keras 2.2.5是最后一个支持TensorFlow1.的版本,也是2.2.*最后一个用Keras实现的版本。最新的版本是Keras2.3.0,其对API进行了重大的改进,并添加对TensorFlow 2.0的支持。  

    **************************************Keras使用基础*****************************************

    Sequential Model:(the simplest type of model)

      Sequential 模型就是多个网络层的线性堆叠。 model.add()

    1 from keras.models import Sequential
    2 from keras.layers import Dense
    3 model = Sequential()
    4 model.add(Dense(units=64, activation="relu", input_dim=100))
    5 model.add(Dense(units=10, activation="softmax"))

      一旦模型搭建完成,可以通过.compile()配置它的学习过程。

    1 model.compile(loss='categorical_crossentropy',
    2               optimizer='sgd',
    3               metrics=['accuracy']

      如果需要,也可以优化配置,如下所述。此时,损失、优化器的设置将会显式的调用方法,而不是通过某字段:

    1 model.compile(loss=keras.losses.categorical_crossentropy,
    2               optimizer=keras.optimizers.SGD(lr=0.01, momentum=0.9, nesterov=True))

      训练阶段:

      然后,可以将数据输入模型,并进行训练。自动将输入数据划分为batch进行训练:

    model.fit(x_train, y_train, epoch=5, batch_size=32)

      当然,也可以手动将batch数据集输入到模型中(这种情况通常是在需要手动建立样本对时,如siamese network):

    model.train_on_batch(x_batch, y_batch)

      训练时,验证模型:

    loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128)

      测试阶段:

    classes = model.predict(x_test, batch_size=128)

      以上是最简明的Keras教程。  

    Getting started with the Keras Sequential model

      Sequential model 就是一些层的线性堆叠。

      堆叠的方式包含两种:

    • 通过一个由层实例构成的列表:
    1 from keras.models import Sequential
    2 from keras.layers import Dense, Activation
    3 
    4 model = Sequential([
    5     Dense(32, input_shape=(784,)),
    6     Activation('relu'),
    7     Dense(10),
    8     Activation('softmax'),
    9 ])

      将由层构成的列表添加到Sequential中。

    • 简单的通过.add()函数添加层
    1 model = Sequential()
    2 model.add(Dense(32, input_dim=784))
    3 model.add(Activation('relu'))

      一般会直接把激活函数添加到层中:

    model.add(Dense(units=10, activation="softmax"))  

    Specifying the input shape

      模型需要明确输入形状(就像TensorFlow中占位符tf.placeholder()的声明)。

      因此,序列模型中的第一层(只有第一层,因为后续层可以进行自动形状推断)需要接收关于其输入形状的信息。Keras有几种可能的方法来做到这一点:

    • 将input_shape参数传递给第一层。这是一个形状元组(一个整数或无项的元组,其中None表示可能期望任何正整数)。在input_shape中,不包括批处理维度。
    1 model = Sequential() 
    2 model.add(Dense(32, input_shape=(784,)))

      如上所示,将input_shape传递给第一层中。

    • 一些2D层(如Dense)通过参数input_dim传递输入的形状;一些3D层支持参数input_dim和input_length。
    1 model = Sequential() 
    2 model.add(Dense(32, input_dim=784))

      如上所示,Dense中既包含input_dim参数的传递,也包含input_shape参数的传递。

    • 也可以将batch_size添加到输入形状中。batch_size=32和input_shape=(6,8)传递给一个层,那么它将期望每批输入都具有批处理形状(32,6,8)。 --这一部分与TensorFlow几乎一致

    Compilation

      在训练模型之前,需要配置训练过程的一些参数,通过compile函数完成。必需传递的三个参数:

      optimizer

      可以使用现存优化器的字符串或者是一个优化器类的实例来识别。

     1 from keras import optimizers
     2 
     3 model = Sequential()
     4 model.add(Dense(64, kernel_initializer='uniform', input_shape=(10,)))
     5 model.add(Activation('softmax'))
     6 # 情形1: 类的实例
     7 sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
     8 model.compile(loss='mean_squared_error', optimizer=sgd)
     9 # 情形2:字符串
    10 model.compile(loss='mean_squared_error', optimizer='sgd')

      优化器中可以添加clipnorm和clipvalue参数梯度进行截断

    1 from keras import optimizers
    2 
    3 # All parameter gradients will be clipped to
    4 # a maximum norm of 1.
    5 sgd = optimizers.SGD(lr=0.01, clipnorm=1.)
    1 from keras import optimizers
    2 
    3 # All parameter gradients will be clipped to
    4 # a maximum value of 0.5 and
    5 # a minimum value of -0.5.
    6 sgd = optimizers.SGD(lr=0.01, clipvalue=0.5)

      常用的优化方式包括SGD、RMSprop、Adagrad、Adadelta、Adam、Adamax、Nadam。具体使用详见:https://keras.io/optimizers/

           loss funtion:

      同样可以通过字符串或类实例来识别。

    1 from keras import losses
    2 # 情形1 字符串
    3 model.compile(loss='mean_squared_error', optimizer='sgd')
    4 # 情形2 类实例
    5 model.compile(loss=losses.mean_squared_error, optimizer='sgd')

      可以获取到的损失函数详见:https://keras.io/losses/

          metrics:

      对于任何分类问题,需要设置一些metrics=['accuracy'],也是通过字符串和类实例识别。

    1 from keras import metrics
    2 # 情形1 字符串
    3 model.compile(loss='mean_squared_error',
    4               optimizer='sgd',
    5               metrics=['mae', 'acc'])
    6 # 情形2 类实例
    7 model.compile(loss='mean_squared_error',
    8               optimizer='sgd',
    9               metrics=[metrics.mae, metrics.categorical_accuracy])

      可以获得的metrics详见:https://keras.io/metrics/

    Training

      Keras训练通过Numpy数组作为输入数据

     1 # For a single-input model with 2 classes (binary classification):
     2 
     3 model = Sequential()
     4 model.add(Dense(32, activation='relu', input_dim=100))
     5 model.add(Dense(1, activation='sigmoid'))
     6 model.compile(optimizer='rmsprop',
     7               loss='binary_crossentropy',
     8               metrics=['accuracy'])
     9 
    10 # Generate dummy data
    11 import numpy as np
    12 data = np.random.random((1000, 100))
    13 labels = np.random.randint(2, size=(1000, 1))
    14 
    15 # Train the model, iterating on the data in batches of 32 samples
    16 model.fit(data, labels, epochs=10, batch_size=32)

      one-hot操作:

    1 # Convert labels to categorical one-hot encoding
    2 one_hot_labels = keras.utils.to_categorical(labels, num_classes=10)

      更多Keras中函数参数使用详见:https://keras.io/models/sequential/

      后端使用详见:https://keras.io/backend/

      ************************************************************************************************************

      上面介绍了一些关于Keras的使用,这是使用tf.keras的基础。  

      言归正传,回到tf.keras的道路上...

      tf.keras是TensorFlow实现的keras API规范。这是一个用于构建和训练模型的高级API,包括对tensorflow特定功能(如eager execution、tf.data和Estimators) tf.keras使TensorFlow更易于使用,同时又不牺牲灵活性和性能。

      eager execution、tf.data和Estimators会在TensorFlow的介绍中详细解读,tf.keras中暂不作详述。

      首先,导入需要的一些设置:

    1 from __future__ import absolute_import, division, print_function, unicode_literals
    2 import tensorflow as tf
    3 from tensorflow import keras 

      tf.keras中可以运行与Keras兼容的任意代码,但需要注意的是:

    • 版本是否兼容,需要通过tf.keras.version确认版本信息
    • 模型保存问题,tf.keras默认使用 checkpoint format格式,而keras模型的保存格式HDF5需要借用函数save_format='h5'

    使用tf.keras建立一个简易的模型

      仿照Keras中的Sequential()方法,此时,在TensorFlow中也可以使用这种线性堆叠的方法:tf.keras.Sequentials()

     1 import tensorflow as tf
     2 from tensorflow.keras import layers
     3 
     4 model = tf.keras.Sequential()
     5 # Adds a densely-connected layer with 64 units to the model:
     6 model.add(layers.Dense(64, activation='relu'))
     7 # Add another:
     8 model.add(layers.Dense(64, activation='relu'))
     9 # Add an output layer with 10 output units:
    10 model.add(layers.Dense(10))

      tf.keras.layers中提供了一些可用的层,详见:https://tensorflow.google.cn/api_docs/python/tf/keras/layers

      这些层会包含一些共同的参数:

    • activation: 设置激活函数。 默认情况下为无激活函数。
    • kernel_initializerbias_initializer:初始化权重和偏执。通过这个操作,便不再需要手动为每一层的权重和偏执进行初始化。默认情况下是"Glorot uniform"初始化方式这个在tensorflow的slim API中会包含。
    • kernel_regularizer bias_regularizer : 权重和偏执正则化。通过这个操作,可以实现神经网络结构的正则化,防止过拟合的现象,可以使用L1正则化和L2正则化。默认情况下是不添加正则化。这个在tensorflow 的 slim API中也会包含。 --- 这个是需要手动添加的
     1 # 创建一个激活函数是relu的全连接层:
     2 layers.Dense(64, activation='relu')
     3 # 也可以通过 类实例 设置激活函数:
     4 layers.Dense(64, activation=tf.nn.relu)
     5 
     6 # 创建一个对权重使用L1正则化,并且参数为0.01的全连接层:
     7 layers.Dense(64, kernel_regularizer=tf.keras.regularizers.l1(0.01))
     8 
     9 # 创建一个对偏执使用L2正则化,并且参数为0.01的全连接层:
    10 layers.Dense(64, bias_regularizer=tf.keras.regularizers.l2(0.01))
    11 
    12 # 对权重选择orthogonal的初始化方式
    13 layers.Dense(64, kernel_initializer='orthogonal')
    14 
    15 # 将偏执初始化为2.0
    16 layers.Dense(64, bias_initializer=tf.keras.initializers.Constant(2.0))

      在模型搭建完成后,便可以配置训练过程的参数,这些过程与Keras一致,只不过是通过tf.keras来调用。

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

      在compile可以设置run_eager=True ,to make sure the model trains and evaluates eagerly。  

    使用Numpy数组进行训练:

      不需要将数据喂到张量中,可以直接将数据输入到.fit()函数中。

    1 import numpy as np
    2 
    3 data = np.random.random((1000, 32))
    4 labels = np.random.random((1000, 10))
    5 
    6 model.fit(data, labels, epochs=10, batch_size=32

      tf.keras.Model.fit()函数中包含3个重要参数:

    • epochs: 训练代数
    • batch_size:一个批次的数据量。当传递NumPy数据时,模型将数据分割成更小的批。这个值指定每个批处理的大小。请注意,如果样本总数不能被批次大小整除,那么最后一批可能会很小
    • validation_data:在构建模型原型时,希望在某些验证数据上方便地监视它的性能。传递这个参数(输入和标签的元组)允许模型在每个epoch结束时以推理模式显示传递的数据的损失和度量。 当然,不设置也可以。 ---- 此处应该有推理代数的设置,每个epoch结束都进行验证,会延长训练时间,而且实际上也没有必要。
     1 import numpy as np
     2 
     3 data = np.random.random((1000, 32))
     4 labels = np.random.random((1000, 10))
     5 
     6 val_data = np.random.random((100, 32))
     7 val_labels = np.random.random((100, 10))
     8 
     9 model.fit(data, labels, epochs=10, batch_size=32,
    10           validation_data=(val_data, val_labels))

    使用tf.data 数据集进行训练

      此处只是简单的介绍,tf.data是读取数据的API,可以实现数据在多设备上的训练。可以通过tf.data.Dataset实例获取数据,并将数据传入到 .fit 方法中。

      详见:https://tensorflow.google.cn/guide/data

    1 dataset = tf.data.Dataset.from_tensor_slices((data, labels))
    2 dataset = dataset.batch(32)
    3 
    4 model.fit(dataset, epochs=10)

      由于Dataset生成(yeild)批量数据,因此model.fit()中不再需要batch_size参数的设置。同时,Dataset也可以用于验证数据的生成:

    1 dataset = tf.data.Dataset.from_tensor_slices((data, labels))
    2 dataset = dataset.batch(32)
    3 
    4 val_dataset = tf.data.Dataset.from_tensor_slices((val_data, val_labels))
    5 val_dataset = val_dataset.batch(32)
    6 
    7 model.fit(dataset, epochs=10,
    8           validation_data=val_dataset)

    验证和预测

      tf.keras.Model.evaluatetf.keras.Model.predict方法可以使用Numpy数据tf.data.Dataset数据进行验证和预测

      .evaluate

     1 # With Numpy arrays
     2 data = np.random.random((1000, 32))
     3 labels = np.random.random((1000, 10))
     4 
     5 model.evaluate(data, labels, batch_size=32)
     6 
     7 # With a Dataset
     8 dataset = tf.data.Dataset.from_tensor_slices((data, labels))
     9 dataset = dataset.batch(32)   # 此处按照batch划分
    10 
    11 model.evaluate(dataset)  # 此处不再需要batch参数

      .predict

    1 result = model.predict(data, batch_size=32) 
    2 print(result.shape)

      详见:https://tensorflow.google.cn/guide/keras/train_and_evaluate  

    使用tf.keras构建复杂模型

      也许在上面的介绍中,你可能会觉得这只是在tensorflow中调用keras,搞出来了一个tf.keras这么个东东,还不如直接用Keras来的实惠。这只是创建简单的模型,在本节中,将会见到tf.keras的奇妙之处,也是在MobileNet V3源码中广泛使用的模型子类化(Model subclassing)和自定义层(Custom layers) ,一起揭开其神秘的面纱。

    The functional API 

      使用tf.keras.Sequential构建模型是一种层与层之间简单堆叠式的方式,其不能表征任意的模型。使用Keras functional API可以创建复杂的模型,例如:

    • 多输入模型
    • 多输出模型
    • 拥有共享层的模型(同一层被调用多次)
    • 不具有序列化输入的模型(残差网络的连接)

      创建一个由functional API 构建的模型需要如下几步:

    1. 层实例是可以调用的,并且返回一个张量;
    2. 输入张量和输出张量用于定义tf.keras.Model实例。
    3. 模型训练的方式如同Sequential 模型。

      下面的全连接网络实例便是使用的the functional API,在其中,可以隐约的看到keras版的YOLO v3的影子:

     1 inputs = tf.keras.Input(shape=(32,))  # Returns an input placeholder
     2 
     3 # 1. 层实例可以回调一个张量,也可以返回一个张量   --- 完成模型的构建
     4 x = layers.Dense(64, activation='relu')(inputs) 
     5 x = layers.Dense(64, activation='relu')(x)
     6 predictions = layers.Dense(10)(x)
     7 # 2. 通过给定输出 输出 实例化一个模型
     8 model = tf.keras.Model(inputs=inputs, outputs=predictions)
     9 
    10 # 3. 通过与sequential模型相同的训练方式训练模型
    11 model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
    12               loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
    13               metrics=['accuracy'])
    14 
    15 # Trains for 5 epochs
    16 model.fit(data, labels, batch_size=32, epochs=5)

    模型子类化(Model subclassing)

      通过tf.keras.Model子类化定义前向过程的方式完全自主的创建model。在_init__方法中创建层,并将它们设置为类实例的属性。在call方法中定义前向过程。

      当启用了立即执行时,模型子类化特别有用,因为它允许强制地编写正向传递。

      下面的实例中展示了一个使用子类化tf.keras.Model,并且自定义前向过程的模型:

     1 class MyModel(tf.keras.Model):
     2 
     3   def __init__(self, num_classes=10):
     4     super(MyModel, self).__init__(name='my_model')
     5     self.num_classes = num_classes
     6     # Define your layers here.
     7     self.dense_1 = layers.Dense(32, activation='relu')   # __init__中定义层
     8     self.dense_2 = layers.Dense(num_classes)
     9 
    10   def call(self, inputs):   # call 函数中定义前向过程
    11     # Define your forward pass here,
    12     # using layers you previously defined (in `__init__`).
    13     x = self.dense_1(inputs)
    14     return self.dense_2(x)

      实例化建立的MyModel类,那并进行编译训练:

    1 model = MyModel(num_classes=10)
    2 
    3 # The compile step specifies the training configuration.
    4 model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
    5               loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
    6               metrics=['accuracy'])
    7 
    8 # Trains for 5 epochs.
    9 model.fit(data, labels, batch_size=32, epochs=5)

      上面的使用过程可以描述为以下几个步骤:

    1. 为模型创建一个类;
    2. 模型中层的定义在__init__函数中;
    3. 前向的过程在call函数中定义;
    4. 实例化类,并使用与sequential相同的方式编译 训练模型。

    定制层(Custom layers)

      通过子类化tf.keras.layers创建一个自定义层。使用以下方法实现:

    • __init__ :可选地定义此层要使用的子层(类的继承);
    • build:生成层的权重,使用add_weights方法添加权重;
    • call:定义前向过程;
    • 可选地,可以通过实现get_config方法from_config类方法来序列化层。 (参数的保存与导入)

      下面是一个自定义层的例子,它实现了一个带有核矩阵的输入矩阵:

     1 class MyLayer(layers.Layer):
     2 
     3   def __init__(self, output_dim, **kwargs):
     4     self.output_dim = output_dim   # 输出个数的定义
     5     super(MyLayer, self).__init__(**kwargs)  # 初始化layers.Layer变量。
     6 
     7   def build(self, input_shape):  # 添加权重矩阵
     8     # Create a trainable weight variable for this layer.
     9     self.kernel = self.add_weight(name='kernel',
    10                                   shape=(input_shape[1], self.output_dim),
    11                                   initializer='uniform',
    12                                   trainable=True)   
    13 
    14   def call(self, inputs):   # 定义前向过程
    15     return tf.matmul(inputs, self.kernel)
    16 
    17   def get_config(self):
    18     base_config = super(MyLayer, self).get_config()
    19     base_config['output_dim'] = self.output_dim
    20     return base_config
    21 
    22   @classmethod
    23   def from_config(cls, config):
    24     return cls(**config)

      使用自定义的层,创建一个模型:

     1 model = tf.keras.Sequential([
     2     MyLayer(10)])
     3 
     4 # The compile step specifies the training configuration
     5 model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
     6               loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
     7               metrics=['accuracy'])
     8 
     9 # Trains for 5 epochs.
    10 model.fit(data, labels, batch_size=32, epochs=5)

      更加细致的内容详见: https://tensorflow.google.cn/guide/keras/custom_layers_and_models

    Callbacks

      回调是传递给模型的对象,用于在训练期间自定义和扩展其行为。编写自己的自定义回调,或者使用内置的tf.keras.callbacks,包括: ---- callbacks 参数是在.fit()中应用。

    • tf.keras.callbacks.ModelCheckpoint:每个一定代数定期的保存权重;
    • tf.keras.callbacks.LearningRateScheduler: 动态地改变学习率 lr;
    • tf.keras.callbacks.EarlyStopping: 关于earlystop的设置
    • tf.keras.callbacks.TensorBoard: 关于tensorboard的设置;
    1 callbacks = [
    2   # Interrupt training if `val_loss` stops improving for over 2 epochs
    3   tf.keras.callbacks.EarlyStopping(patience=2, monitor='val_loss'),
    4   # Write TensorBoard logs to `./logs` directory
    5   tf.keras.callbacks.TensorBoard(log_dir='./logs')
    6 ]
    7 model.fit(data, labels, batch_size=32, epochs=5, callbacks=callbacks,
    8           validation_data=(val_data, val_labels))

    模型的保存与导入

    只保存权重

    • tf.keras.Model.save_weights()保存权重;
    • tf.keras.Model.load_weights()导入权重
    1 # Save weights to a TensorFlow Checkpoint file
    2 model.save_weights('./weights/my_model')
    3 
    4 # Restore the model's state,
    5 # this requires a model with the same architecture.
    6 model.load_weights('./weights/my_model')

      上述函数默认保存的模型权重是TensorFlow的checkpoint(.ckpt)格式。也可以保存为Keras版的HDF5格式,只需要修改保存格式参数即可:

    1 # Save weights to a HDF5 file
    2 model.save_weights('my_model.h5', save_format='h5')
    3 
    4 # Restore the model's state
    5 model.load_weights('my_model.h5')

    只保存模型的配置文件:

      非训练过程调整的参数保存,如yolo中的cfg文件。可以保存为JSON和YAML两种格式:

    1 # Serialize a model to JSON format
    2 json_string = model.to_json()   # 保存  为json
    3 yaml_string = model.to_yaml()   # 保存 为yaml

      导入

    1 import json
    2 import pprint
    3 pprint.pprint(json.loads(json_string))

      复现模型:

    1 fresh_model = tf.keras.models.model_from_json(json_string)   # 由json复现
    2 fresh_model = tf.keras.models.model_from_yaml(yaml_string)   # 由yaml复现

    保存完整的模型在一个文件中

    1 # Save entire model to a HDF5 file
    2 model.save('my_model')
    3 
    4 # Recreate the exact same model, including weights and optimizer.
    5 model = tf.keras.models.load_model('my_model')

      更多关于保存模型内容详见:https://tensorflow.google.cn/guide/keras/save_and_serialize

      下一篇链接:https://www.cnblogs.com/monologuesmw/p/13534871.html

            https://tensorflow.google.cn/guide/keras

      

      

  • 相关阅读:
    类的继承
    垃圾回收GC
    网络层
    数据链路层
    TCP/IP协议分层模型
    OSI参考模型
    浏览器访问一个域名的过程
    Thread&ThreadLocal
    设计模式---单例模式
    内存泄漏和内存溢出
  • 原文地址:https://www.cnblogs.com/monologuesmw/p/13534857.html
Copyright © 2020-2023  润新知