Python 类及其在 Keras 中的使用

类是 Python 语言的基本构建块之一,可用于开发机器学习应用程序。正如我们将看到的,用于开发类的 Python 语法很简单,可以应用于在 Keras 中实现回调。  

在本教程中,您将了解 Python 类及其功能。  

完成本教程后,您将了解:

  • 为什么 Python 类很重要
  • 如何定义和实例化类并设置其属性  
  • 如何创建方法并传递参数
  • 什么是类继承
  • 如何使用类在 Keras 中实现回调

使用我的新书《Python for Machine Learning》快速开始您的项目,其中包含分步教程和所有示例的Python 源代码文件。

让我们开始吧。

Python 类及其在 Keras 中的使用
照片来源:S Migaj,部分权利保留。

教程概述

本教程分为六个部分;它们是:

  • 类简介
  • 定义类
  • 实例化和属性引用
  • 创建方法和传递参数
  • 类继承
  • 在 Keras 中使用类

类简介

在面向对象的语言(如 Python)中,类是基本构建块之一。  

它们可以被比作对象的蓝图,因为它们定义了对象应具有的属性和方法/行为。

-《Python Fundamentals》,2018 年。

创建新类会创建一个新对象,每个类实例都可以通过其属性来维护其状态,并通过方法来修改其状态。

定义类

class 关键字允许创建新的类定义,后面立即跟着类名

通过这种方式,将创建一个绑定到指定类名(在本例中为 MyClass)的新类对象。每个类对象都可以支持实例化和属性引用,我们稍后将看到。

实例化和属性引用

实例化是创建类的另一个实例。

要创建类的另一个实例,我们可以使用其类名对其进行调用,并将其分配给一个变量。这将创建一个新的、空的类对象

创建类的实例后,Python 会调用其对象构造函数方法 __init__(),该方法通常接受参数,用于设置已实例化对象的属性。  

我们可以在类中像定义函数一样定义此构造函数方法,并指定在实例化对象时需要传递的属性。

-《Python Fundamentals》,2018 年。

例如,假设我们想定义一个名为 Dog 的新类

在这里,构造函数方法接受两个参数 namebreed,在实例化对象时可以将它们传递给它。

在我们考虑的示例中,namebreed 被称为实例变量(或属性),因为它们绑定到特定实例。这意味着这些属性仅属于设置了它们的特定对象,而不属于从同一类实例化的任何其他对象。  

另一方面,family 是一个类变量(或属性),因为它由同一类的所有实例共享。

您可能还会注意到,构造函数方法(或任何其他方法)的第一个参数通常称为 self。此参数引用我们正在创建的对象。为了确保您的代码对其他程序员来说易于阅读,遵循将第一个参数设置为 self 的约定是一个好习惯。  

一旦设置了对象的属性,就可以使用点运算符访问它们。例如,再次考虑 Dog 类的 dog1 实例,其 name 属性可以按如下方式访问:

产生以下输出

想开始学习机器学习 Python 吗?

立即参加我为期7天的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

创建方法和传递参数

除了具有构造函数方法外,类对象还可以有几个其他方法来修改其状态。  

定义实例方法的语法很熟悉。我们传递参数 self……它始终是实例方法的第一个参数。

-《Python Fundamentals》,2018 年。

与构造函数方法类似,每个实例方法都可以接受几个参数,第一个参数是 self 参数,它允许我们设置和访问对象的属性。

同一对象的不同方法也可以使用 self 参数相互调用。

然后可以按如下方式生成输出字符串

我们发现,通过这样做,当 info() 方法调用 add_tricks() 方法时,“barks on command”输入会被追加到 tricks 列表中。产生以下输出:

类继承

Python 还支持另一个功能,即类的继承 

继承是一种机制,它允许子类(也称为派生类子类)访问超类(也称为基类父类)的所有属性和方法。  

使用子类的语法如下

子类也可以继承自多个基类。在这种情况下,语法如下

在基类以及多重继承的情况下,后续基类中也会搜索类属性和方法。  

Python 还允许子类中的方法覆盖基类中同名的方法。子类中的覆盖方法可以替换基类方法,也可以仅扩展其功能。当存在覆盖的子类方法时,执行调用时将执行此方法,而不是基类中同名的方法。  

在 Keras 中使用类

在 Keras 中使用类的实际用途是编写自己的回调。  

回调是 Keras 中一个强大的工具,它允许我们在模型训练、测试和预测的不同阶段查看模型的行为。  

事实上,我们可以将回调列表传递给以下任何一个:

  • keras.Model.fit()
  • keras.Model.evaluate()
  • keras.Model.predict()

Keras API 附带了几个内置回调。尽管如此,我们可能希望编写自己的回调,为此,我们将研究如何构建一个自定义回调类。要做到这一点,我们可以从回调基类继承几个方法,这些方法可以为我们提供有关何时

  • 训练、测试和预测开始和结束
  • 一个 epoch 开始和结束
  • 训练、测试和预测批次开始和结束

让我们首先考虑一个自定义回调的简单示例,该回调在每个 epoch 开始和结束时报告。我们将把这个自定义回调类命名为 EpochCallback,并覆盖基类 keras.callbacks.Callback 中的 epoch 级方法 on_epoch_begin()on_epoch_end()

为了测试我们刚刚定义的自定义回调,我们需要一个模型来训练。为此,让我们定义一个简单的 Keras 模型。

我们还需要一个数据集来进行训练,为此我们将使用 MNIST 数据集。

现在,让我们通过将自定义回调添加到传递给 keras.Model.fit() 方法的回调列表中来尝试自定义回调。

 

我们刚刚创建的回调产生以下输出:

我们可以创建另一个自定义回调,该回调监控每个 epoch 结束时的损失值,并且仅当损失下降时才存储模型权重。为此,我们将从 log 字典中读取损失值,该字典存储每个批次和 epoch 结束时的指标。我们还将通过 self.model 访问对应于当前训练、测试或预测回合的模型。  

我们将这个自定义回调称为 CheckpointCallback

我们可以再次尝试,这次将 CheckpointCallback 包含在回调列表中。

现在将生成两个回调组合的以下输出:

Keras 中的其他类

除了回调之外,我们还可以在 Keras 中为自定义指标(派生自 keras.metrics.Metrics)、自定义层(派生自 keras.layers.Layer)、自定义正则化器(派生自 keras.regularizers.Regularizer)甚至自定义模型(派生自 keras.Model,例如更改模型调用行为)创建派生类。您所要做的就是遵循指南来更改类的成员函数。您必须在成员函数中使用完全相同的名称和参数。

以下是 Keras 文档中的一个示例:

这揭示了为什么我们需要为自定义指标创建一个类:指标不仅仅是一个函数,而是一个在训练周期中每批训练数据计算其值的函数。最终,结果将在一个 epoch 结束时通过 result() 函数报告,并使用 reset_state() 函数重置其内存,以便您可以在下一个 epoch 中重新开始。

有关必须派生的确切内容的详细信息,您应该参考 Keras 的文档。

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

书籍

网站

总结

在本教程中,您将了解 Python 类及其功能。

具体来说,你学到了:

  • 为什么 Python 类很重要
  • 如何定义和实例化类并设置其属性  
  • 如何创建方法并传递参数
  • 什么是类继承
  • 如何使用类在 Keras 中实现回调

你有什么问题吗?
在下面的评论中提出您的问题,我将尽力回答。

掌握机器学习 Python!

Python For Machine Learning

更自信地用 Python 编写代码

...从学习实用的 Python 技巧开始

在我的新电子书中探索如何实现
用于机器学习的 Python

它提供自学教程数百个可运行的代码,为您提供包括以下技能:
调试性能分析鸭子类型装饰器部署等等...

向您展示高级 Python 工具箱,用于
您的项目


查看内容

Python 类及其在 Keras 中的使用 的 4 条回复

  1. Walle 2021年12月22日上午1:21 #

    对代码示例的一些小更正/评论
    – 为 simple_model 函数定义添加冒号
    – y_train -> y_train_cat 在 model.fit 中
    – verbose=0 也添加到第一个 EpochCallback model.fit 示例中

    • James Carmichael 2022年1月10日上午11:41 #

      感谢 Walle 的反馈!

  2. Michael L 2021年12月25日凌晨2:46 #

    谢谢 Stefania。非常重要的主题。

    您能否说明一下,将模型定义为类(即 https://tensorflowcn.cn/guide/keras/custom_layers_and_models#the_model_class)还是通过函数简单地定义模型是更可取的(以及为什么)?

    我最近一直在使用子类化来构建模型,因为这似乎是更 Pythonic 的方法。定义一个类,然后实例化该类的实例作为模型。但是,我见过的每个代码库和网站都使用函数来构建模型。子类化有什么好处吗?

    如果没有,为什么 TensorFlow 要费力实现它?

发表回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。