您的位置:首页 > 其它

TensorFlow2.0 学习笔记(六):TensorFlow2.0 和 Keras 的纠葛

2019-10-23 15:49 513 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/TeFuirnever/article/details/102702971

专栏——TensorFlow学习笔记

文章目录

  • 参考文章
  • 一、TensorFlow 2.0 和 Keras 的关系

    如果你学过

    Keras
    的话,就会发现上面的实例中均使用了
    Subclassing API
    建立模型,不过在
    TensorFlow 2.0
    中,是对
    tf.keras.Model
    类进行扩展以定义自己的新模型,同时手工编写了训练和评估模型的流程。这种方式灵活度高,且与其他流行的深度学习框架(如
    PyTorch、Chainer
    )共通(共通的意思不是可以一起使用,而是道理相同)。

    如果在某些时候,只需要一个结构相对简单和典型的神经网络,比如上文中的

    MLP
    TensorFlow2.0 学习笔记(二):多层感知机(MLP))和
    CNN
    TensorFlow2.0 学习笔记(三):卷积神经网络(CNN)),则可以使用
    Keras
    来提供了另一套更为简单高效的内置方法来建立网络。


    简单来说,就是

    Keras
    是在
    TensorFlow
    基础上构建的高层
    API

    二、Keras Sequential/Functional API 模式建立模型

    最典型和常用的神经网络结构就是将一堆层按特定顺序叠加起来,这样方便查看,也方便改动,即只需要提供一个层的列表,就能由

    Keras
    将它们自动首尾相连,形成模型,这便是
    Keras
    Sequential API
    的魅力。

    通过向

    tf.keras.models.Sequential()
    提供一个层的列表,就能快速地建立一个
    tf.keras.Model
    模型并返回:

    model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(100, activation=tf.nn.relu),
    tf.keras.layers.Dense(10),
    tf.keras.layers.Softmax()
    ])

    如上所见:

    • tf.keras.layers.Flatten()
      Flatten
      层用于将最终特征映射转换为一个一维向量,展开之后可以在某些
      卷积/maxpool
      层之后使用全连接层,它结合了以前卷积层提取的所有局部特征;
    • tf.keras.layers.Dense
      即全连接(
      dense
      )层是用于实现分类,即人工神经网络分类器;
    • tf.keras.layers.Softmax()
      多用于分类,使得网络输出每个类别的概率分布。

    不过,这种层叠结构并不能表示任意的神经网络结构,例如多输入 / 输出或存在参数共享的模型。其使用方法是将层作为可调用的对象并返回张量,并将输入向量和输出向量提供给

    tf.keras.Model
    3ff7
    inputs
    outputs
    参数,示例如下:

    inputs = tf.keras.Input(shape=(28, 28, 1))
    x = tf.keras.layers.Flatten()(inputs)
    x = tf.keras.layers.Dense(units=100, activation=tf.nn.relu)(x)
    x = tf.keras.layers.Dense(units=10)(x)
    outputs = tf.keras.layers.Softmax()(x)
    model = tf.keras.Model(inputs=inputs, outputs=outputs)

    我们在 Kaggle竞赛实战系列(一):手写数字识别器(Digit Recognizer)得分99.53%、99.91%和100% 中通过

    Keras
    实现了一个神经网络,
    Keras
    实现网络的实例如下:

    # 设置CNN模型
    model = Sequential()
    
    model.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same',
    activation ='relu', input_shape = (28,28,1)))
    model.add(BatchNormalization())
    model.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same',
    activation ='relu'))
    model.add(BatchNormalization())
    model.add(MaxPool2D(pool_size=(2,2)))
    
    model.add(Flatten())
    model.add(Dense(256, activation = "relu"))
    model.add(Dropout(0.5))
    model.add(Dense(10, activation = "softmax"))

    三、训练和评估模型

    当模型建立完成后,通过

    tf.keras.Model
    compile
    方法配置训练过程:

    model = tf.keras.Model(inputs=inputs, outputs=outputs)
    
    model.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
    loss=tf.keras.losses.sparse_categorical_crossentropy,
    metrics=[tf.keras.metrics.sparse_categorical_accuracy]
    )

    如上所见,

    tf.keras.Model.compile
    一共有 3 个重要的参数:

    • oplimizer
      即优化器,可从
      tf.keras.optimizers
      中选择;
    • loss
      即损失函数,可从
      tf.keras.losses
      中选择;
    • metrics
      即评估指标,可从
      tf.keras.metrics
      中选择。

    接下来,可以使用

    tf.keras.Model
    fit
    方法训练模型:

    model = tf.keras.Model(inputs=inputs, outputs=outputs)
    
    model.fit(data_loader.train_data, data_loader.train_label,
    epochs=num_epochs, batch_size=batch_size, verbose = 1)

    如上所见,

    tf.keras.Model.fit
    一共有 5 个重要的参数:

    • x
      即训练数据;
    • y
      即训练数据标签;
    • epochs
      即将训练数据迭代次数;
    • batch_size
      即批大小;
    • validation_data
      即验证数据,可用于在训练过程中监控模型的性能;
    • verbose
      即0, 1,默认为1,表示日志显示。
      verbose = 0
      在控制台没有任何输出;
      verbose = 1
      显示进度条。

    最后,使用

    tf.keras.Model.evaluate
    评估训练效果,提供测试数据及标签即可:

    model = tf.keras.Model(inputs=inputs, outputs=outputs)
    
    model.evaluate(data_loader.test_data, data_loader.test_label,
    batch_size=None, verbose=1, callbacks=None)

    如上所见,

    tf.keras.Model.evaluate
    一共有 5 个参数:

    • x
      即测试数据;
    • y
      即测试数据标签;
    • batch_size
      即批大小;
    • verbose
      即0, 1,默认为1,表示日志显示。
      verbose = 0
      在控制台没有任何输出;
      verbose = 1
      显示进度条;
    • callbacks
      即回调函数,用来回调参数。

    除了上面提到的这些,还有

    tf.keras.Model.fit_generator()
    ,可以在数据生成器上拟合模型,可以减少内存消耗,

    model.fit_generator(datagen.flow(X_train,Y_train, batch_size=batch_size),
    epochs = epochs, validation_data,
    verbose = 1, steps_per_epoch,
    callbacks=None)

    如上所见,

    tf.keras.Model.fit_generator()
    一共有 8 个参数:

    • x
      即测试数据;
    • y
      即测试数据标签;
    • batch_size
      即批大小;
    • epochs
      即将训练数据迭代次数;
    • validation_data
      即验证数据,可用于在训练过程中监控模型的性能;
    • verbose
      即0, 1,默认为1,表示日志显示。
      verbose = 0
      在控制台没有任何输出;
      verbose = 1
      显示进度条;
    • steps_per_epoch
      即每个
      epoch
      的迭代步数;
    • callbacks
      即回调函数,用来回调参数。

    这些方法其实都是基于

    Keras
    实现的,不过现在都是
    TensorFlow
    的了。。。

    四、自定义层

    很明显除了系统默认的这些层,你一定会有自己想要定义的层。

    那么怎么样来设置呢?

    可以继承

    tf.keras.layers.Layer
    编写自己的层,并重写
    __init__
    build
    call
    三个方法,如下所示:

    class MyLayer(tf.keras.layers.Layer):
    def __init__(self):
    super().__init__()
    # 初始化代码
    
    def build(self, input_shape):     # input_shape 是一个 TensorShape 类型对象,提供输入的形状
    # 在第一次使用该层的时候调用该部分代码
    # 在这里创建变量可以使得变量的形状自适应输入的形状
    # 而不需要使用者额外指定变量形状。
    # 如果已经可以完全确定变量的形状,也可以在__init__部分创建变量
    self.variable_0 = self.add_weight(...)
    self.variable_1 = self.add_weight(...)
    
    def call(self, inputs):
    # 模型调用的代码(处理输入并返回输出)
    return output

    例如,如果想要自己实现一个全连接层(

    tf.keras.layers.Dense
    ),可以按如下方式编写。此代码在
    build
    方法中创建两个变量,并在
    call
    方法中使用创建的变量进行运算:

    class LinearLayer(tf.keras.layers.Layer):
    def __init__(self, units):
    super().__init__()
    self.units = units
    
    def build(self, input_shape):     # 这里 input_shape 是第一次运行call()时参数inputs的形状
    self.w = self.add_variable(name='w',
    shape=[input_shape[-1], self.units], initializer=tf.zeros_initializer())
    self.b = self.add_variable(name='b',
    shape=[self.units], initializer=tf.zeros_initializer())
    
    def call(self, inputs):
    y_pred = tf.matmul(inputs, self.w) + self.b
    return y_pred

    在定义模型的时候,便可以如同

    Keras
    中的其他层一样,调用自定义的层
    LinearLayer

    class LinearModel(tf.keras.Model):
    def __init__(self):
    super().__init__()
    self.layer = LinearLayer(units=1)
    
    def call(self, inputs):
    output = self.layer(inputs)
    return output

    五、自定义损失函数

    TensorFlow2.0 学习笔记(三):卷积神经网络(CNN) 中我们是通过调用

    tf.keras.losses
    来实现损失函数的使用。

    那么如果我想自定义一个损失函数呢?

    自定义损失函数需要继承

    tf.keras.losses.Loss
    类,重写
    call
    方法即可,输入真实值
    y_true
    和模型预测值
    y_pred
    ,输出模型预测值和真实值之间通过自定义的损失函数计算出的损失值。

    如果想使用官方定义的均方差损失函数,可以在 https://tensorflow.google.cn/api_docs/python/tf/keras/losses?hl=zh-cn 中查询,

    tf.keras.losses.mean_squared_error
    即可,或者还有好多相同的写法:

    下面的示例为自定义的均方差损失函数:

    class MeanSquaredError(tf.keras.losses.Loss):
    def call(self, y_true, y_pred):
    return tf.reduce_mean(tf.square(y_pred - y_true))

    六、自定义评估指标

    自定义评估指标需要继承 tf.keras.metrics.Metric 类,并重写

    __init__
    update_state
    result
    三个方法。如果想要使用官方定义的评估指标,可以查询 https://tensorflow.google.cn/api_docs/python/tf/keras/metrics

    TensorFlow2.0 学习笔记(三):卷积神经网络(CNN) 中使用过如下评估指标:

    可以通过调用函数

    tf.keras.metrics.SparseCategoricalAccuracy
    实现,或者还有其他写法:

    下面的示例对
    SparseCategoricalAccuracy
    评估指标类做了一个简单的重实现:

    class SparseCategoricalAccuracy(tf.keras.metrics.Metric):
    def __init__(self):
    super().__init__()
    self.total = self.add_weight(name='total', dtype=tf.int32, initializer=tf.zeros_initializer())
    self.count = self.add_weight(name='count', dtype=tf.int32, initializer=tf.zeros_initializer())
    
    def update_state(self, y_true, y_pred, sample_weight=None):
    values = tf.cast(tf.equal(y_true, tf.argmax(y_pred, axis=-1, output_type=tf.int32)), tf.int32)
    self.total.assign_add(tf.shape(y_true)[0])
    self.count.assign_add(tf.reduce_sum(values))
    
    def result(self):
    return self.count / self.total

    七、Keras 概述

    tf.keras
    TensorFlow
    Keras API 规范的实现,这可以使得你拥有使用 Keras
    的机会,不至于牺牲掉
    Keras
    本身的灵活性和性能,使用如下语句进行
    TensorFlow
    程序设置的导入:

    from __future__ import absolute_import, division, print_function, unicode_literals
    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
      格式(或以
      .h5
      结尾的文件名)。

    近期会考虑在完成

    TensorFlow2.0
    pytorch
    之后,完善
    Keras
    的教程,可以期待一下。

    推荐阅读

    参考文章

    • TensorFlow 官方文档
    • 简单粗暴 TensorFlow 2.0
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: