序言
“想象力比知识更重要。”
– 阿尔伯特·爱因斯坦,《爱因斯坦关于宇宙宗教和其他见解与格言》(2009)
在本书中,我们将探索生成式人工智能,这是一种使用先进的机器学习算法生成合成(但惊人逼真)数据的尖端技术。生成模型一直以来都引起了跨领域研究人员的兴趣。随着机器学习和更具体地说是深度学习领域的最新进展,生成式建模在研究作品数量和它们在不同领域的应用中迅速增长。从艺术作品和音乐作曲到合成医学数据集,生成建模正在推动想象力和智能的界限。理解、实现和利用这些方法所需的思考和努力量简直令人惊叹。一些较新的方法(如 GANs)非常强大,但难以控制,使得整个学习过程既令人兴奋又令人沮丧。
使用 Python 和 TensorFlow 2 进行生成式人工智能 是我们作者和 Packt Publishing 的才华横溢团队数小时辛勤工作的结果,帮助你理解这个生成式建模领域的 深度、广度 和 狂野 空间。本书的目标是成为生成式建模空间的万花筒,并涵盖广泛的主题。本书带你走向旅程,在这个过程中,你不仅仅是读懂理论和了解基础知识,还通过示例发现了这些模型的潜力和影响。我们将使用各种开源技术来实现这些模型——Python 编程语言、用于深度神经网络开发的 TensorFlow 2 库,以及云计算资源,如 Google Colab 和 Kubeflow 项目。
对本书中各种主题、模型、架构和示例的理解将帮助你轻松探索更复杂的主题和尖端研究。
本书适合对象
使用 Python 和 TensorFlow 2 进行生成式人工智能 面向数据科学家、机器学习工程师、研究人员和对生成式建模以及将最先进的架构应用于真实数据集感兴趣的开发者。这本书也适合那些具有中级深度学习相关技能的 TensorFlow 初学者,他们希望扩展自己的知识基础。
开始阅读本书只需要基本的 Python 和深度学习技能。
本书内容包括
第一章,生成式人工智能简介:从模型中“提取”数据,介绍了生成式人工智能领域,从概率论基础到最近的这些方法的应用产品。
第二章,建立一个 TensorFlow 实验室,描述了如何使用开源工具——Python、Docker、Kubernetes 和 Kubeflow——为使用 TensorFlow 开发生成式人工智能模型设置计算环境,以便在云中运行可扩展的代码实验室。
第三章,深度神经网络的构建模块,介绍了深度神经网络的基础概念,这些概念将在本卷的其余部分中被利用——它们是如何受生物研究启发的,研究人员在开发越来越大规模和复杂模型时克服了哪些挑战,以及网络架构、优化器和正则化器的各种构建模块,这些构建模块在本书其余部分的生成式人工智能示例中被利用。
第四章,教网络生成数字,演示了如何实现深度置信网络,这是一种突破性的神经网络架构,通过生成式人工智能方法在分类手写数字图像方面取得了最先进的结果,这种方法教会网络在学习对其进行分类之前生成图像。
第五章,使用 VAE 用神经网络绘制图片,描述了变分自动编码器(VAEs),这是从深度置信网络发展而来的一种先进技术,通过巧妙地使用贝叶斯统计学中的客观函数来创建复杂对象的更清晰图像。读者将实现一个基本和高级的 VAE,后者利用了逆自回归流(IAF),这是一种递归变换,可以将随机数映射到复杂的数据分布以创建引人注目的合成图像。
第六章,使用 GAN 进行图像生成,介绍了生成对抗网络,或 GANs,作为强大的生成建模深度学习架构。从 GANs 的基本构建模块和其他基本概念开始,本章介绍了许多 GAN 架构以及它们如何用于从随机噪声生成高分辨率图像。
第七章,使用 GAN 进行风格转移,专注于生成建模的创造性应用,特别是称为风格转移的 GAN。应用例如将黑白图像转换为彩色图像,航拍地图转换为类似谷歌地图的输出,以及去除背景,都可以通过风格转移实现。我们涵盖了许多成对和非成对的架构,如 pix2pix 和 CycleGAN。
第八章,使用 GAN 进行深度伪造,介绍了 GAN 的一个有趣且有争议的应用,称为深度伪造。该章节讨论了深度伪造的基本构建模块,例如特征和不同的操作模式,以及一些关键架构。它还包括了一些实际示例,以基于所涵盖的关键概念生成虚假照片和视频,这样读者就可以创建自己的深度伪造流水线。
第九章,文本生成方法的兴起,介绍了与文本生成任务相关的概念和技术。我们从深度学习模型中不同的文本向量表示方式入手,讲述了语言生成的基本知识。然后我们介绍了不同的架构选择和解码机制,以实现高质量的输出。本章为后续更复杂的文本生成方法奠定了基础。
第十章,NLP 2.0:使用 Transformer 生成文本,介绍了 NLP 领域最新最先进的技术,重点介绍了一些基于 Transformer 架构(如 GPT-x)的最先进的文本生成能力,以及它们如何彻底改变了语言生成和 NLP 领域。
第十一章,使用生成模型创作音乐,介绍了使用生成模型创作音乐。这是一种有趣但具有挑战性的生成模型应用,涉及理解与音乐相关的许多细微差别和概念。本章涵盖了许多不同的生成音乐的方法,从基本的 LSTMs 到简单的 GANs,最终到用于多声部音乐生成的 MuseGAN。
第十二章,使用生成式 AI 玩游戏:GAIL,描述了生成式 AI 和强化学习之间的联系,强化学习是一种机器学习的分支,教授“代理”在执行指定任务时在真实或虚拟“环境”中导航。通过 GAN 和强化学习之间的联系,读者将通过模仿跳跃运动的专家示例,教会一个跳跃形象在 3D 环境中导航。
第十三章,生成式 AI 的新兴应用,描述了最近在生成式 AI 领域的研究,涵盖了生物技术、流体力学、视频和文本合成等各个方面。
要最大限度地发挥本书的效益
要跟上本书的代码,请推荐以下要求:
- 硬件(用于本地计算):
- 128GB 硬盘
- 8GB 内存
- Intel Core i5 处理器或更高版本
- NVIDIA 8GB 及以上显卡(GTX1070 及以上)
- 软件:
- Python 3.6 及以上版本
- TensorFlow 2.x
- Chrome/Safari/Firefox 浏览器(如果在云中训练,则通过 Google Colab 或 Kubeflow 直接执行代码)
下载示例代码文件
本书的代码包托管在 GitHub 上,网址为 github.com/PacktPublishing/Hands-On-Generative-AI-with-Python-and-TensorFlow-2
。我们还有其他书籍和视频的代码包,请访问github.com/PacktPublishing/
。一并查看吧!
下载彩色图片
我们还提供了该书中所使用的屏幕截图/图表的彩色图像的 PDF 文件。您可以在此处下载:static.packt-cdn.com/downloads/9781800200883_ColorImages.pdf
。
使用的约定
本书中使用了许多文本约定。
CodeInText
:表示文本中的代码词,数据库表名,文件夹名,文件名,文件扩展名,路径名,虚拟 URL,用户输入和 Twitter 用户名。例如:“我们可以使用show_examples()
函数直观地绘制一些示例。”
一段代码块设置如下:
def cd_update(self, x): with tf.GradientTape(watch_accessed_variables=False) as g: h_sample = self.sample_h(x) for step in range(self.cd_steps): v_sample = tf.constant(self.sample_v(h_sample)) h_sample = self.sample_h(v_sample)
当我们希望引起您对代码块特定部分的注意时,相关行或项目将用粗体显示:
def cd_update(self, x): with tf.GradientTape(watch_accessed_variables=False) as g: h_sample = self.sample_h(x) **for** **step** **in****range****(self.cd_steps):** v_sample = tf.constant(self.sample_v(h_sample)) h_sample = self.sample_h(v_sample)
任何命令行输入或输出如下所示:
pip install tensorflow-datasets
粗体:表示一个新术语,一个重要词汇,或者您在屏幕上看到的单词,在菜单或对话框中也会以这种方式呈现在文本中。例如:“从管理面板中选择系统信息”。
警告或重要说明会出现在此处。
提示和技巧会出现在此处。
联系我们
我们的读者的反馈总是受欢迎的。
一般反馈:如果您对本书的任何方面有疑问,请在消息主题中提及书名,发送电子邮件至customercare@packtpub.com
。
勘误:尽管我们已尽一切努力确保内容的准确性,但错误是无法避免的。如果您在本书中发现了错误,我们将不胜感激。请访问www.packtpub.com/support/errata,选择您的书籍,点击勘误提交表单链接,并输入详细信息。
盗版:如果您在互联网上发现我们作品的任何非法复制形式,我们将不胜感激,如果您提供给我们位置地址或网站名称。请联系我们,发送邮件至copyright@packtpub.com
并附上链接到该材料的链接。
如果您有兴趣成为作者:如果您在某个专题上有专业知识,并且有兴趣撰写或为一本书作出贡献,请访问authors.packtpub.com
。
评论
请留下评论。一旦您阅读并使用了本书,为什么不在您购买的网站上留下评论呢?潜在读者可以看到并使用您的客观意见来做出购买决定,我们在 Packt 可以了解到您对我们产品的看法,我们的作者也能看到您对他们书籍的反馈。谢谢!
有关 Packt 的更多信息,请访问packtpub.com。
第一章:生成人工智能简介:“从模型中“勾画”数据
在本章中,我们将深入探讨生成模型的各种应用。在此之前,我们将退后一步,详细研究生成模型与其他类型的机器学习的区别。区别在于任何机器学习算法的基本单位:概率以及我们用数学量化我们遇到的数据的形状和分布的各种方法。
在本章的其余部分,我们将 covers:
- AI 的应用
- 判别和生成模型
- 实施生成模型
- 概率的规则
- 为什么使用生成模型?
- 生成模型的独特挑战
AI 的应用
在 2018 年 10 月的纽约,国际拍卖行佳士得在印刷品与多重品展销会上以 43.25 万美元的价格出售了埃德蒙·贝拉米的肖像(图 1.1)。这次销售之所以引人注目,既因为销售价格比这件作品的初步估计高出 45 倍,也因为这幅肖像的非同寻常的起源。与佳士得自 18 世纪以来出售的大多数其他艺术品不同,埃德蒙·贝拉米的肖像既不是用油画或水彩画完成的,其创作者甚至不是人类;相反,它是由一个复杂的机器学习算法完全产生的数字图像。创作者——一个名为 Obvious 的巴黎集体利用了从 14 世纪到 20 世纪创作的 1.5 万幅肖像的集合来调整一个能够生成美学上类似但合成的图像的人工神经网络模型。
图 1.1:埃德蒙·贝拉米的肖像¹
画像远非唯一一个展示机器学习惊人成果的领域。事实上,如果你在过去几年关注新闻,你可能已经看到许多关于现代 AI 系统应用于各种问题的开创性成果的故事,从硬科学到数字艺术。像 Obvious 创建的深度神经网络模型现在可以在训练有素的医生水平上对人体解剖的 X 光图像进行分类,²在传统棋类游戏如围棋(一种类似国际象棋的亚洲游戏)³和多人游戏⁴中战胜人类大师,并且对法语翻译成英语时对语法细微差别表现出惊人的敏感性。⁵
判别模型和生成模型
这些人工智能的其他示例与生成埃德蒙·贝拉米的肖像的模型在一个重要的方面有所不同。在所有这些其他应用中,模型被呈现一组输入数据,例如英文文本、X 射线图像或游戏棋盘上的位置,这些数据与目标输出配对,例如翻译句子中的下一个词、X 射线图的诊断分类或游戏中的下一步。事实上,这可能是您在以往预测建模经验中最熟悉的 AI 模型类型;它们被广泛称为判别模型,其目的是在一组输入变量和目标输出之间创建映射。目标输出可以是一组离散类别(例如在翻译中下一个出现的英文单词),也可以是连续结果(例如预期一个客户在接下来的 12 个月内在在线商店中的消费金额)。
应该注意的是,这种模型,其中数据被标记或评分,仅代表了现代机器学习能力的一半。另一类算法,比如生成了在佳士得拍卖会上出售的人造肖像的算法,不会从输入变量中计算得分或标签,而是生成新数据。与判别模型不同,输入变量通常是与现实世界值无关的数字向量,甚至经常是随机生成的。这种模型——被称为生成模型——可以从随机噪声中产生复杂的输出,例如文本、音乐或图像,并且是本书的主题。
即使您当时不知道,您可能也曾在新闻中看到其他生成模型的实例,与前面提到的判别示例并列。一个突出的例子是深度伪造,这是一种视频,其中一个人的脸被系统地替换为另一个人的脸,通过使用神经网络重新映射像素。⁶
图 1.2:一个深度伪造图像⁷
也许您还看到过关于 AI 模型生成虚假新闻的报道,最初由 OpenAI 公司的科学家因担心其可能被用于在线制造宣传和误导而感到恐慌。⁸
图 1.3:使用 GPT-2 创建的聊天机器人对话⁹
在这些以及其他应用中,例如谷歌的语音助手 Duplex,它可以通过与人类实时动态创建对话来进行餐厅预订¹⁰,或者可以生成原创音乐作品的软件¹¹,我们被环绕着生成式人工智能算法的输出。
图 1.4:使用生成对抗网络(GANs)进行风格迁移的示例¹²
这些模型能够处理各种领域的复杂信息:创建逼真的图像或照片上的滤镜 (图 1.4),合成声音,对话文本,甚至是最佳玩视频游戏的规则。你可能会问,这些模型从哪里来?我如何能自己实现它们?我们将在下一节中更多地讨论这个问题。
实现生成模型
尽管生成模型理论上可以使用各种机器学习算法来实现,但在实践中,它们通常是通过深度神经网络构建的,这些网络非常适合捕捉图像或语言等数据的复杂变化。
在本书中,我们将专注于使用TensorFlow 2.0来实现这些深度生成模型的许多不同应用。TensorFlow 是一个 C++框架,有 Python 编程语言的 API,用于开发和应用深度学习模型。它是谷歌在 2013 年开源的,并且已经成为研发和部署神经网络模型的最受欢迎的库之一。
随着 2.0 版的发布,以前版本中开发的那些样板代码得到了清理,使用了高级抽象层,使我们能够专注于模型而不是计算过程的其它部分。最新版本还引入了即时执行的概念,允许网络计算按需运行,这将是我们实现某些模型的重要好处。
在接下来的章节中,你将学习不仅是这些模型背后的理论,还有在流行的编程框架中实现它们所需的实际技能。在第二章,建立一个 TensorFlow 实验室中,你将学习如何设置一个云环境,以便你可以使用Kubeflow框架来分布式运行 TensorFlow,并记录你的实验。
实际上,正如我将在第三章,深度神经网络的构建模块中更详细地描述的那样,自 2006 年以来,大规模神经网络模型的深度学习研究已经产生了各种各样的生成模型应用。其中第一个是受限玻尔兹曼机,它被堆叠在多个层中以创建深度信念网络。我将在第四章,教网络生成数字中描述这两种模型。后来的创新包括变分自动编码器(VAEs),它们可以有效地从随机数生成复杂的数据样本,我将在第五章,使用 VAEs 用神经网络绘制图片中描述这些技术。
我们还将在本书的第六章,使用 GAN 生成图像中更详细地讨论用于创建埃德蒙·贝拉米的肖像的算法 GAN。从概念上讲,GAN 模型在两个神经网络之间创建竞争。一个(称为生成器)从一组随机数开始生成逼真的(或者在 Obvious 的实验中,艺术性的)图像,并应用数学变换。在某种意义上,生成器就像一名艺术学生,从笔触和创意灵感中创作新的绘画。
第二个网络,被称为判别器,试图分类一幅图片是否来自一组真实世界的图片,还是由生成器创建。因此,判别器就像一个老师,评分学生是否产生了与他们试图模仿的绘画相媲美的作品。随着生成器变得越来越擅长欺骗判别器,它的输出越来越接近于它被设计来复制的历史示例。
有许多类 GAN 模型,附加变体在第七章,使用 GAN 进行风格迁移,和第十一章,使用生成模型创作音乐,在我们讨论高级模型时涵盖。生成模型中的另一个关键创新是在自然语言数据领域。通过以一种计算可扩展的方式代表句子中单词之间的复杂相互关系,Transformer 网络及其基于其之上构建的双向编码器 Transformer(BERT)模型呈现了在应用中生成文本数据的强大构建模块,如聊天机器人,在第九章,文本生成方法的崛起,和第十章,NLP 2.0:使用 Transformer 生成文本中我们将更详细地讨论。
在第十二章,使用生成式 AI 玩视频游戏:GAIL 中,您还将看到诸如 GAN 和 VAE 等模型如何被用于生成不仅仅是图像或文本,而是一组允许使用强化学习算法开发的游戏网络更高效地处理和导航其环境的规则集——本质上,学会学习。生成模型是一个不断增长的巨大研究领域,所以遗憾的是,我们无法在本书中涵盖每一个主题。对于感兴趣的读者,进一步主题的参考资料将在第十三章,生成式 AI 的新兴应用中提供。
要开始一些背景信息,让我们讨论一下概率规则。
概率规则
在最简单的层面上,模型,无论是用于机器学习还是更经典的方法,如线性回归,都是关于各种数据如何相互关联的数学描述。
在建模任务中,我们通常考虑将数据集的变量分成两大类:
- 独立数据,主要是指模型的 输入,用 X 表示。这些可以是分类特征(例如某学生所在的六所学校中的“0”或“1”),连续的(例如相同学生的身高或考试成绩),或序数的(班级中学生的排名)。
- 依赖数据 相反,则是我们模型的输出,用 Y 表示。(请注意,在某些情况下,Y 是一个 标签,可用于条件产生输出,例如在条件 GAN 中。)与自变量一样,这些可以是连续的、分类的或序数的,它们可以是数据集每个元素的个体元素或多维矩阵(张量)。
那么如何使用统计描述我们模型中的数据呢?换句话说,我们如何定量描述我们可能看到的值,以及频率如何,哪些值更有可能一起出现?一种方式是询问数据中观察特定值的可能性,或者该值的概率。例如,如果我们想知道掷六面骰子出现 4 的概率是多少,答案是平均来说,我们会在六次掷骰子中看到一次 4。我们写为:
P(X=4) = ⅙ = 16.67%
其中 P 表示 概率为。
什么定义了特定数据集的允许概率值?如果我们想象数据集所有可能值的集合,比如掷骰子的所有值,那么概率将每个值映射到 0 和 1 之间的数。最小值是 0,因为我们不可能有看到结果的负概率;最不可能的结果是我们永远不会看到特定值的机会,或者是 0%的概率,比如在六面骰子上掷出 7。同样,我们也不可能有大于 100%的观察结果概率,其值为 1;概率为 1 的结果是绝对确定的。与数据集相关联的这组概率值属于离散类(例如骰子的面)或无限潜在值的集合(例如身高或体重的变化)。不过,在任一情况下,这些值必须遵循某些规则,这些规则是由数学家安德烈·科尔莫戈洛夫在 1933 年描述的 概率公理。
- 观察的概率(掷骰子点数、特定身高等)是 0 到 1 之间的非负有限数。
- 在所有可能观察空间中至少出现一项观察结果的概率是 1。
- 不同、互斥事件的联合概率是各个事件概率的总和。
尽管这些规则可能看起来抽象,但你将会在第三章,深度神经网络的基础组件中看到,它们与开发神经网络模型直接相关。例如,规则 1 的一个应用是在预测目标类别的softmax函数中生成介于 1 和 0 之间的概率。规则 3 用于将这些结果归一化到 0-1 范围内,保证它们是深度神经网络的相互独立的预测(换句话说,实际世界中的图像逻辑上不能同时被分类为狗和猫,而只能是狗或猫,这两个结果的概率是可加的)。最后,第二条规则提供了我们可以使用这些模型生成数据的理论保证。
然而,在机器学习和建模的背景下,我们通常不只是对观察到一条输入数据的概率X感兴趣;我们更想知道,基于这些数据,Y的条件概率是多少。换句话说,我们想知道基于数据对一组数据的标签有多大可能性。我们将此表示为给定 X 的 Y 的概率,或者给定 X 条件下的 Y 的概率:
P(Y|X)
我们还可以询问关于Y和X的另一个问题,即它们一起发生或它们的联合概率有多大,这可以使用前面的条件概率表达式表示如下:
P(X, Y) = P(Y|X)P(X) = P(X|Y)(Y)
此公式表示X 和 Y 的概率。在X和Y完全独立的情况下,这就是它们的乘积:
P(X|Y)P(Y) = P(Y|X)P(X) = P(X)P(Y)
你会发现,这些表达式在我们讨论第四章,教授网络生成数字中的补充先验和受限玻尔兹曼机模拟独立数据样本的能力中变得重要。它们也是贝叶斯定理的构建模块,我们将在下一节中讨论。
判别建模和生成建模以及贝叶斯定理
现在让我们考虑这些条件和联合概率规则如何与我们为各种机器学习应用构建的预测模型相关联。在大多数情况下——比如预测电子邮件是否欺诈性或客户未来生命周期价值的美元金额——我们对条件概率P(Y|X=x)感兴趣,其中Y是我们试图建模的结果集,X表示输入特征,x是输入特征的特定值。如前所述,这种方法被称为判别建模。¹⁴判别建模试图学习数据X与结果Y之间的直接映射。
另一种理解判别建模的方法是在贝叶斯定理的背景下,¹⁵它关联了数据集的条件和联合概率:
P(Y|X) = P(X|Y)P(Y)/P(X) = P(X, Y)/P(X)
在贝叶斯公式中,表达式P(X|Y)/P(X)被称为似然或观察到的X给出Y观察概率的支持证据。*P(Y)*是先验或结果的合理性,*P(Y|X)*是后验或给出到目前为止与结果相关的所有独立数据的观察概率。概念上,贝叶斯定理表明结果的概率是其基线概率与此结果的输入数据条件概率的乘积。
这个定理是作者去世两年后发表的,在前言中理查德·普赖斯描述它为上帝存在的一个数学论证,这或许是适当的,因为托马斯·贝叶斯在生前是一位牧师。
在判别学习的背景下,我们可以看到判别模型直接计算后验概率;我们可以有似然或先验模型,但在这种方法中并不需要。即使你可能没有意识到,你可能在机器学习工具包中使用的大多数模型都是判别模型,例如以下模型:
- 线性回归
- 逻辑回归
- 随机森林
- 梯度提升决策树(GBDT)
- 支持向量机(SVM)
前两种(线性回归和逻辑回归)是在数据X的条件下模型结果Y,使用正态或高斯函数(线性回归)或 S 型函数(逻辑回归)。相比之下,最后三种没有正式的概率模型—它们计算将X映射到Y的函数(一组树用于随机森林或 GDBT,或者 SVM 的内积分布),使用损失或错误函数来调整这些估计值。鉴于这种非参数性质,一些作者认为这构成了一类非模型判别算法。(16)
相比之下,生成模型试图学习标签和输入数据的联合分布P(Y, X)。回想一下通过联合概率的定义:
P(X, Y) = P(X|Y)P(Y)
我们可以将贝叶斯定理重写如下:
P(Y|X) = P(X, Y)/P(X)
与判别情况不同,我们的目标不是使用P(Y|X)直接映射X到Y,而是模拟X和Y的联合概率P(X, Y)。虽然我们可以使用X和Y的联合分布来计算后验概率P(Y|X)并学习一个目标模型,但我们也可以使用此分布来通过联合采样新的元组(x, y)或使用目标标签Y采样新的数据输入,使用以下表达式:
P(X|Y=y) = P(X, Y)/P(Y)
生成模型的例子包括以下内容:
- 朴素贝叶斯分类器
- 高斯混合模型
- 潜在狄利克雷分配(LDA)
- 隐马尔可夫模型
- 深度波尔兹曼机
- 变分自动编码器(VAEs)
- 生成对抗网络(GANs)
朴素贝叶斯分类器,虽然被称为判别模型,但利用贝叶斯定理来学习X和Y的联合分布,假设X变量是独立的。同样,高斯混合模型描述了数据点属于一组正态分布之一的可能性,使用标签和这些分布的联合概率。
LDA 将文档表示为单词和一组潜在关键字列表(主题)的联合概率,这些关键字列表在文档中使用。隐马尔可夫模型表示数据的状态和下一个状态的联合概率,例如一周中连续几天的天气。正如你将在第四章中看到的,教网络生成数字,深度波尔兹曼机学习标签和与之相关的数据向量的联合概率。我们将在第 5、6、7 和 11 章中涵盖的 VAE 和 GAN 模型也利用联合分布来映射复杂的数据类型。这种映射允许我们从随机向量生成数据,或者将一种数据转换为另一种。
如前所述,生成模型的另一个观点是,如果我们知道一个结果Y,它们允许我们生成X的样本。在前述列表中的前四个模型中,这种条件概率只是模型公式的一个组成部分,而后验估计仍然是最终目标。然而,在最后三个示例中,它们都是深度神经网络模型,学习关于一个隐藏或潜在变量Z的X的条件是实际上的主要目标,以便生成新的数据样本。利用多层神经网络所允许的丰富结构,这些模型可以近似表示复杂数据类型的分布,如图像、自然语言和声音。此外,Z不再是目标值,而在这些应用中通常是一个随机数,仅用作从中生成大量假设数据点的输入。在我们有标签的程度上(比如一个生成的图像应该是狗还是海豚,或者一个生成的歌曲的流派),模型就是P(X|Y=y, Z=z),其中标签Y控制着除了Z的随机性外其他数据的生成。
为什么使用生成模型?
现在我们已经回顾了生成模型的内容,并在概率语言中更正式地定义了它们,为什么我们首先需要这样的模型呢?它们在实际应用中提供了什么价值?为了回答这个问题,让我们简要地浏览一下我们将在本书的其余部分更详细地讨论的主题。
深度学习的承诺
正如已经指出的,我们将在本书中调查的许多模型都是深度的、多级的神经网络。过去 15 年来,深度学习模型在图像分类、自然语言处理和理解以及强化学习方面取得了复兴。这些进展是由于在调整和优化非常复杂的模型方面的传统挑战的突破,再加上对更大的数据集、分布式计算能力的访问以及诸如 TensorFlow 这样的框架,使得原型设计和复制研究变得更加容易。
构建更好的数字分类器
用于在机器学习和计算机视觉中基准算法的一个经典问题是对来自 MNIST 数据集的像素化图像中表示的 0-9 之间的哪个手写数字进行分类的任务。¹⁷ 在这个问题上取得的一个重大突破发生在 2006 年,当时多伦多大学和新加坡国立大学的研究人员发现了一种训练深度神经网络执行此任务的方法。¹⁸
他们的一个关键观察是,与其训练一个网络直接预测给定图像(X)的最可能的数字(Y),不如首先训练一个可以生成图像的网络,然后作为第二步对它们进行分类。在第四章,教网络生成数字中,我将描述这个模型是如何改进过去的尝试的,并且如何创建自己的受限玻尔兹曼机和深度玻尔兹曼机模型,这些模型可以生成新的 MNIST 数字图像。
生成图像
使用 MNIST 数据集的方法生成像Edmond Belamy 的肖像这样的图像的一个挑战是,图像通常没有标签(如数字);相反,我们想要使用一个潜在向量Z将随机数空间映射到一组人工图像,就像我在本章中早些时候描述的那样。
另一个限制是我们希望促进这些图像的多样性。如果我们输入在某个范围内的数字,我们希望知道它们生成不同的输出,并且能够调整生成的图像特征。为此,VAE 被开发出来生成多样化和逼真的图像(图 1.5)。
图 1.5:来自 VAE 的样本图像¹⁹
在图像分类任务的背景下,能够生成新图像可以帮助我们增加现有数据集中的示例数量,或者如果我们现有数据集严重偏向于特定类型的照片,则减少偏差。应用可能包括为时尚电子商务网站的产品照片生成替代姿势(角度、色调或透视镜头)(图 1.6):
图 1.6:使用深度生成模型模拟替代姿势²⁰
风格转移和图像变换
除了将人工图像映射到随机数空间之外,我们还可以使用生成模型学习将一种图像映射到另一种图像。这种模型可以用于将一幅马的图像转换为斑马的图像(图 1.7),创建深度伪造视频,其中一个演员的脸被另一个演员的脸替换,或将照片转换为绘画(图 1.2和1.4):²¹
图 1.7:CycleGAN 将条纹应用于马身上以生成斑马²²
应用生成建模的另一个引人注目的例子是一项研究,该研究发现了艺术家巴勃罗·毕加索的失落杰作被另一幅图像所覆盖的情况。在对**《老吉他手》和《蹲着的乞丐》进行 X 射线成像后,显示了一个女人和一个风景的早期图像位于其下面(图 1.8),研究人员使用了毕加索蓝色时期的其他绘画或其他彩色照片(图 1.8)来训练神经风格转移模型,该模型将黑白图像(覆盖绘画的 X 射线放射图)转换为原始艺术作品的着色。然后,将这种转换模型应用于隐藏图像使他们能够重建着色版本**的丢失绘画:
图 1.8:深度学习被用于给绘画场景的 X 射线图着色(中),通过从示例中学习颜色模式(列 d)生成失落艺术品的着色版本(极右)²³
所有这些模型都使用了之前提到的 GAN,这是一种在 2014 年提出的深度学习模型²⁴。除了改变图像的内容(如前面斑马的例子中),这些模型还可以用于将一幅图像映射到另一幅图像,比如成对的图像(例如具有相似面部特征的狗和人,如图 1.9),或者从图像生成文本描述(图 1.10):
图 1.9:Sim-GAN 用于将人类映射到动物或动漫脸部²⁵
图 1.10:Caption-GAN 用于从图像生成描述²⁶
我们还可以根据一些辅助信息如标签来调节生成图像的属性,这是 GAN-Gogh 算法中采用的方法,它通过将期望的艺术家作为输入提供给生成模型来合成不同艺术家风格的图像(图 1.4)。²⁷我将在第六章,使用 GAN 生成图像和第七章,使用 GAN 进行风格转移中描述这些应用。
虚假新闻和聊天机器人
人类一直想要与机器交谈;第一个聊天机器人,ELIZA,²⁸是在 1960 年代在麻省理工学院编写的,它使用一个简单的程序来转换用户的输入并生成一个回应,以心理治疗师的方式频繁地以问题形式回应。
更复杂的模型可以生成全新的文本,例如谷歌的 BERT 和 GPT-2,^(29 30)它们使用一种称为Transformers的单元。神经网络中的Transformers模块允许网络在文本中的前导词汇上提出新词汇,在生成合理的语言片段时强调更相关的词汇。然后,BERT 模型将Transformers单元结合成自然语言模式和上下文重要性的强大多维编码。此方法可用于自然语言处理(NLP)任务的文档创建,或用于聊天机器人对话系统(图 1.3)。
声音合成
声音,如图像或文本,是一种复杂的、高维度的数据。音乐尤其复杂:它可能涉及一个或多个音乐家,具有时间结构,并且可以分为主题相关的段落。所有这些组成部分都被纳入到先前提到的模型中,比如 MuseGAN,该模型使用 GAN 生成这些各种组件,并将它们合成为逼真但合成的音乐曲目。我将在第十一章“用生成模型创作音乐”中描述 MuseGAN 及其变种的实施。
游戏规则
前述应用涉及我们可以看到、听到或阅读的数据类型。然而,生成模型还可以用于生成规则。这在深度学习的一种流行应用中很有用:使用算法玩棋盘游戏或 Atari 视频游戏。³¹
虽然这些应用传统上使用强化学习(RL)技术来训练网络以在这些游戏中采用最佳策略,但新的研究表明使用 GAN 来提出新规则作为训练过程的一部分,³²或生成合成数据来激发整体学习过程。³³我们将在第十二章“用生成 AI 玩视频游戏:GAIL”中研究这两种应用。
生成模型的独特挑战
鉴于生成模型具有的强大应用,实施它们的主要挑战是什么?正如所述,这些模型大多利用复杂数据,需要我们拟合大型模型来捕捉其特征和分布的所有细微差别。这对于我们必须收集的示例数量以充分代表我们试图生成的数据类型,以及构建模型所需的计算资源都有影响。我们将在第二章“设置 TensorFlow 实验室”中讨论使用云计算框架和图形处理单元(GPU)并行训练这些模型的技术。
由于数据复杂性及我们试图生成数据而不是数字标签或值的事实,我们对模型准确度的概念变得更加复杂:我们不能简单地计算到单个标签或分数的距离。
我们将在第五章,使用 VAE 进行神经网络绘图,以及第六章,使用 GAN 进行图像生成中讨论深度生成模型(如 VAE 和 GAN 算法)采用不同方法来确定生成图像是否与真实世界图像可比。最后,正如提到的,我们的模型需要允许我们生成大量和多样化的样本,而我们将讨论的各种方法采用不同的方法来控制数据的多样性。
摘要
在本章中,我们讨论了生成建模是什么,以及它如何适应更熟悉的机器学习方法的格局。我使用概率论和贝叶斯定理来描述这些模型如何以与判别式学习相反的方式进行预测。
我们审查了生成式学习的用例,既针对特定类型的数据,也针对一般性的预测任务。最后,我们还研究了构建这些模型所面临的一些专门挑战。
在下一章中,我们将通过探索如何使用 Docker 和 Kubeflow 为 TensorFlow 2.0 设置开发环境,开始实际实现这些模型。
第二章:设置 TensorFlow 实验室
现在你已经在 第一章 中看到了生成模型的所有令人惊叹的应用,你可能想知道如何开始实施这些使用这些算法的项目。在本章中,我们将介绍一些工具,这些工具将在本书的其余部分中用于实现各种生成式 AI 模型中使用的深度神经网络。我们的主要工具是由 Google^(1 2) 开发的 TensorFlow 2.0 框架;然而,我们还将使用其他一些资源来简化实现过程(在 2.1 表格 中总结)。
我们可以广泛分类这些工具:
- 用于可复制的依赖管理的资源(Docker,Anaconda)
- 数据整理和算法开发的探索性工具(Jupyter)
- 部署这些资源到云端并管理其生命周期的工具(Kubernetes,Kubeflow,Terraform)
工具 | 项目网址 | 用途 |
Docker | www.docker.com/ |
应用程序运行时依赖封装 |
Anaconda | www.anaconda.com/ |
Python 语言包管理 |
Jupyter | jupyter.org/ |
交互式 Python 运行时和绘图/数据探索工具 |
Kubernetes | kubernetes.io/ |
Docker 容器编排和资源管理 |
Kubeflow | www.kubeflow.org/ |
基于 Kubernetes 开发的机器学习工作流引擎 |
Terraform | www.terraform.io/ |
用于可配置和一致部署 Kubeflow 和 Kubernetes 的基础设施脚本语言 |
VSCode | code.visualstudio.com/ |
集成开发环境(IDE) |
表格 2.1:用于生成对抗模型开发的技术栈
在本章中,我们将在我们将我们的代码从笔记本电脑移到云端的旅程中,首先描述一些有关 TensorFlow 在本地运行时的背景知识。然后,我们将描述一系列软件工具,这些工具将使在本地或云端运行全面的 TensorFlow 实验更加容易,如笔记本、容器和集群管理器等。最后,我们将通过一个简单的实例来介绍如何建立一个可重现的研究环境,运行本地和分布式训练,并记录我们的结果。我们还将探讨如何在一台机器内的多个 CPU/GPU 单元(纵向扩展)和云端的多台机器(横向扩展)上并行化 TensorFlow 以加速训练。通过本章的学习,我们将准备好扩展这个实验室框架,用各种生成式 AI 模型来实施项目。
首先,让我们深入了解 TensorFlow 的细节,这是本书剩余部分将用于开发模型的库。 TensorFlow 解决了神经网络模型开发中的哪些问题?它采用了哪些方法?它在多年来如何发展?为了回答这些问题,让我们回顾一些促成 TensorFlow 发展的深度神经网络库的历史。
深度神经网络的发展和 TensorFlow
正如我们将在 第三章 深度神经网络的构建模块 中看到的那样,深度神经网络本质上由矩阵运算(加法、减法、乘法)、非线性变换和使用这些组件的导数进行的基于梯度的更新组成。
在学术界,研究人员通常使用诸如 MATLAB³ 这样的高效原型工具来运行模型和准备分析。虽然这种方法允许进行快速实验,但它缺乏工业软件开发的元素,例如 面向对象(OO)开发,它可以实现可重现性和干净的软件抽象,从而使工具可以被大型组织所采用。这些工具对于大型数据集的扩展也存在困难,并且对于此类工业用途可能会带来繁重的许可费用。然而,在 2006 年之前,这种计算工具在大多数情况下仍然足够。然而,随着应用深度神经网络算法处理的数据集的增长,取得了突破性的成果,如:
- ImageNet 数据集上的图像分类⁴
- 在 YouTube 视频中大规模无监督地发现图像模式⁵
- 创造了能够像人类一样能够玩雅达利视频游戏和围棋的人工智能代理^(6 7)
- 通过 Google 开发的 BERT 模型实现的最先进的语言翻译⁸
在这些研究中开发的模型随着它们应用到的数据集的规模而变得复杂起来(请参阅表 2.2 以了解其中一些模型的巨大规模)。由于工业用例需要稳健且可扩展的框架来开发和部署新的神经网络,一些学术团体和大型技术公司投资于通用工具包的开发,用于实现深度学习模型。这些软件库将常见模式编码为可重用的抽象,使即使复杂的模型通常也可以体现在相对简单的实验脚本中。
模型名称 | 年份 | # 参数 |
AlexNet | 2012 | 61M |
YouTube CNN | 2012 | 1B |
Inception | 2014 | 5M |
VGG-16 | 2014 | 138M |
BERT | 2018 | 340M |
GPT-3 | 2020 | 175B |
表 2.2:按年份分类的模型参数数量
这些框架的早期示例包括 Theano,⁹ 蒙特利尔大学开发的 Python 包,以及 Torch,¹⁰ 由 Facebook 的研究人员在 Lua 语言中编写,后来被转移到 Python,以及由 Google¹¹开发的具有 Python 绑定的 C++运行时的 TensorFlow。
在本书中,我们将主要使用 TensorFlow 2.0,因为它被广泛采用,并且它具有方便的高级界面Keras,可以抽象出大部分关于定义常规层和模型架构的重复工作。
TensorFlow 是 Google 内部称为DistBelief的工具的开源版本。¹²DistBelief 框架由分布式工作者(在一组机器上运行的独立计算过程)组成,这些工作者会对网络进行正向和反向梯度下降处理(我们将在第三章,深度神经网络的构建基块中讨论训练神经网络的常见方式),并将结果发送给参数服务器进行更新。DistBelief 框架中的神经网络被表示为一个有向无环图(DAG),以损失函数结束,产生与观察目标(如图像类别或代表翻译模型中句子中最可能的下一个词的词汇概率分布)进行比较的标量(数值)。
DAG 是一种软件数据结构,由节点(操作)和数据(边)组成,信息仅沿着边的单向流动(因此有向
),而且没有循环(因此无环
)。
尽管 DistBelief 允许 Google 生产出多个大型模型,但它有一些限制:
- 首先,Python 脚本接口是使用一组对应 C++中底层实现的预定义层开发的;添加新颖的层类型需要在 C++中编码,这对生产力构成了障碍。
- 其次,虽然该系统非常适合使用基本的随机梯度下降(SGD)(我们将在第三章,深度神经网络的构建基块中更详细地描述的算法)在大规模数据上训练前馈网络,但它缺乏灵活性,无法容纳循环、强化学习或对抗学习范式 —— 后者对于我们在本书中实现的许多算法贯穿全文非常重要。
- 最后,这个系统难以缩小规模,比如在具有 GPU 的台式机和具有多个核心的分布式环境中运行相同的作业,部署还需要不同的技术栈。
这些考虑共同促使 TensorFlow 作为一种通用的深度学习计算框架的发展:一种可以让科学家灵活地尝试新的层架构或前沿的训练范式,同时还允许这种实验在笔记本电脑(用于早期工作)和计算集群(用于扩展更成熟的模型)上使用相同的工具运行,同时还通过为两者提供一个公共运行时来简化研究和开发代码之间的过渡。
尽管这两个库都共享计算图的概念(将网络表示为操作(节点)和数据(边缘)的图形)和数据流编程模型(其中矩阵操作通过图的有向边缘传递并对其应用操作),但 TensorFlow 与 DistBelief 不同,设计为图的边缘是张量(n 维矩阵),图的节点是原子操作(加法、减法、非线性卷积或队列和其他高级操作),而不是固定的层操作——这允许在定义新计算时具有更大的灵活性,甚至允许进行突变和有状态更新(这些仅是图中的附加节点)。
数据流图本质上充当一个“占位符”,其中数据被插入到定义的变量中,并可以在单台或多台机器上执行。TensorFlow 在 C++运行时优化构建的数据流图,允许优化,例如向 GPU 发送命令。图的不同计算也可以在多台机器和硬件上执行,包括 CPU、GPU 和 TPU(Google 开发的自定义张量处理芯片,在 Google Cloud 计算环境中可用)¹¹,因为在 TensorFlow 中以高层次描述的相同计算被实现为在多个后端系统上执行。
因为数据流图允许可变状态,本质上,不再像 DistBelief 那样有一个集中的参数服务器(尽管 TensorFlow 也可以以参数服务器配置的方式分布式运行),因为持有状态的不同节点可以执行与任何其他工作节点相同的操作。此外,控制流操作(例如循环)允许对可变长度输入进行训练,例如在循环网络中(参见第三章,深度神经网络的构建模块)。在训练神经网络的情况下,每一层的梯度简单地表示为图中的附加操作,允许使用相同框架包含像速度这样的优化(如 RMSProp 或 ADAM 优化器,在第三章,深度神经网络的构建模块中描述)而不是修改参数服务器逻辑。在分布式训练的情况下,TensorFlow 还具有几个检查点和冗余机制(“备份”工作节点以防单个任务失败),使其适用于在分布式环境中进行稳健的训练。
TensorFlow 2.0
尽管在数据流图中表示操作原语可以灵活定义 Python 客户端 API 内的新层,但也可能导致大量“样板”代码和重复的语法。出于这个原因,高级 API Keras¹⁴被开发出来提供高级抽象;层使用 Python 类表示,而特定运行环境(例如 TensorFlow 或 Theano)是执行该层的“后端”,就像原子 TensorFlow 运算符可以在 CPU、GPU 或 TPU 上具有不同的底层实现一样。尽管作为与框架无关的库开发,Keras 已包含在 TensorFlow 2.0 版本的主要发布中。为了可读性的目的,我们将在本书中大部分模型使用 Keras 来实现,而在需要实现特定操作或突出基础逻辑时,将恢复到底层的 TensorFlow 2.0 代码。请参阅表 2.3以比较这些库在低(TensorFlow)或高(Keras)级别上如何实现各种神经网络算法概念。
对象 | TensorFlow 实现 | Keras 实现 |
神经网络层 | 张量计算 | Python 层类 |
梯度计算 | 图运行操作符 | Python 优化器类 |
损失函数 | 张量计算 | Python 损失函数 |
神经网络模型 | 图运行会话 | Python 模型类实例 |
表 2.3:TensorFlow 和 Keras 比较
为了向您展示 Keras 和 TensorFlow 1.0 在实现基本神经网络模型时所做的抽象的区别,让我们看一下使用这两个框架编写卷积层的示例(请参阅第三章,深度神经网络的构建块)。在第一种情况下,在 TensorFlow 1.0 中,您可以看到很多代码涉及显式指定变量、函数和矩阵操作,以及梯度函数和运行时会话来计算网络的更新。
这是 TensorFlow 1.0 中的多层感知器¹⁵:
X = tf.placeholder(dtype=tf.float64) Y = tf.placeholder(dtype=tf.float64) num_hidden=128 # Build a hidden layer W_hidden = tf.Variable(np.random.randn(784, num_hidden)) b_hidden = tf.Variable(np.random.randn(num_hidden)) p_hidden = tf.nn.sigmoid( tf.add(tf.matmul(X, W_hidden), b_hidden) ) # Build another hidden layer W_hidden2 = tf.Variable(np.random.randn(num_hidden, num_hidden)) b_hidden2 = tf.Variable(np.random.randn(num_hidden)) p_hidden2 = tf.nn.sigmoid( tf.add(tf.matmul(p_hidden, W_hidden2), b_hidden2) ) # Build the output layer W_output = tf.Variable(np.random.randn(num_hidden, 10)) b_output = tf.Variable(np.random.randn(10)) p_output = tf.nn.softmax( tf.add(tf.matmul(p_hidden2, W_output), b_output) ) loss = tf.reduce_mean(tf.losses.mean_squared_error( labels=Y,predictions=p_output)) accuracy=1-tf.sqrt(loss) minimization_op = tf.train.AdamOptimizer(learning_rate=0.01).minimize(loss) feed_dict = { X: x_train.reshape(-1,784), Y: pd.get_dummies(y_train) } with tf.Session() as session: session.run(tf.global_variables_initializer()) for step in range(10000): J_value = session.run(loss, feed_dict) acc = session.run(accuracy, feed_dict) if step % 100 == 0: print("Step:", step, " Loss:", J_value," Accuracy:", acc) session.run(minimization_op, feed_dict) pred00 = session.run([p_output], feed_dict={X: x_test.reshape(-1,784)})
相比之下,Keras 中相同卷积层的实现通过使用在 Python 类中体现的抽象概念(如层、模型和优化器)大大简化了。这些类封装了计算的底层细节,使代码逻辑更易读。
还要注意,在 TensorFlow 2.0 中,运行会话的概念(惰性执行,即仅在显式编译和调用时才计算网络)已经被弃用,而采用了渴望执行的方式,在调用网络函数(如 call
和 compile
)时动态调用会话和图,网络行为就像任何其他 Python 类一样,而无需显式创建 session
作用域。使用 tf.Variable()
声明变量的全局命名空间概念也已被替换为默认垃圾收集机制。
这是 Keras 中的多层感知器层¹⁵:
import TensorFlow as tf from TensorFlow.keras.layers import Input, Dense from keras.models import Model l = tf.keras.layers model = tf.keras.Sequential([ l.Flatten(input_shape=(784,)), l.Dense(128, activation='relu'), l.Dense(128, activation='relu'), l.Dense(10, activation='softmax') ]) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics = ['accuracy']) model.summary() model.fit(x_train.reshape(-1,784),pd.get_dummies(y_train),nb_epoch=15,batch_size=128,verbose=1)
现在我们已经了解了 TensorFlow 库的一些细节以及它为深度神经网络模型的开发(包括我们将在本书中实现的生成模型)而非常合适的原因,让我们开始建立我们的研究环境。虽然我们可以简单地使用像 pip 这样的 Python 包管理器在我们的笔记本电脑上安装 TensorFlow,但我们希望确保我们的过程尽可能健壮和可复制 - 这将使我们更容易将我们的代码打包到不同的机器上运行,或者通过指定我们在实验中使用的每个 Python 库的确切版本来保持我们的计算一致。我们将首先安装一个集成开发环境(IDE),这将使我们的研究更容易 - VSCode。
VSCode
Visual Studio Code(VSCode)是由微软公司开发的开源代码编辑器,可用于许多编程语言,包括 Python。它允许调试,并与诸如 Git 等版本控制工具集成; 我们甚至可以在 VSCode 中运行 Jupyter 笔记本(我们将在本章后面描述)。安装说明因您使用的是 Linux、macOS 还是 Windows 操作系统而异:请查看您系统的单独说明,网址为 code.visualstudio.com
。安装完成后,我们需要使用 Git 克隆本书项目的源代码副本,命令如下:
git clone git@github.com:PacktPublishing/Hands-On-Generative-AI-with-Python-and-TensorFlow-2.git
此命令将把本书项目的源代码复制到我们的笔记本电脑上,允许我们本地运行和修改代码。一旦您复制了代码,请使用 VSCode 打开此书的 GitHub 存储库(图 2.1)。我们现在准备开始安装我们将需要的一些工具;打开install.sh
文件。
图 2.1:VSCode IDE
对于我们来说特别有用的一个功能是,VSCode 具有集成(图 2.2)终端,我们可以在其中运行命令:您可以通过选择View,然后从下拉列表中选择Terminal来访问此功能,这将打开一个命令行提示:
图 2.2:VSCode 终端
选择TERMINAL选项卡,并选择解释器为bash;现在您应该能够输入正常的命令。将目录更改为Chapter_2
,我们将在其中运行我们的安装脚本,您可以在 VSCode 中打开该脚本。
我们将运行的安装脚本将下载并安装我们在最后几章中将使用到的各种组件;我们将使用的全面框架是Kubeflow
库,它处理我们在本卷的后几章中将使用到的各种数据和培训流水线。在本章的其余部分,我们将介绍 Kubeflow 是如何构建在 Docker 和 Kubernetes 之上的,以及如何在几个流行的云提供商上设置 Kubeflow。
Kubernetes(Kubeflow 基于此技术)本质上是一种管理使用Docker创建的容器化应用程序的方式,它允许创建和持久化可重现、轻量级的执行环境以适用于各种应用。虽然我们将使用 Docker 创建可重复的实验运行时,以了解其在虚拟化解决方案整体景观中的位置以及为什么它对现代应用程序开发如此重要,让我们稍微偏离一下,详细描述 Docker 的背景。
Docker:一个轻量级的虚拟化解决方案
开发强大的软件应用程序的一个持续挑战是使它们在与开发它们的机器不同的机器上运行相同。这些环境上的差异可能涵盖多个变量:操作系统、编程语言库版本和硬件,如 CPU 型号。
在处理这种异构性时,传统上一种方法是使用虚拟机(VM)。虽然虚拟机能够在多样化的硬件和操作系统上运行应用程序,但它们也受到资源密集型的限制(图 2.3):每个运行在主机上的虚拟机都需要资源开销来运行完全独立的操作系统,以及所有来宾系统中的应用程序或依赖项。
图 2.3:虚拟机与容器¹⁶
然而,在某些情况下,这是一种不必要的开销级别;我们不一定需要运行一个完全独立的操作系统,而只需要一个一致的环境,包括一个操作系统内的库和依赖项。对于指定运行时环境的轻量级框架的需求促使了 2013 年Docker 项目的创建,用于容器化。本质上,容器是运行应用程序的环境,包括所有依赖项和库,允许可重现部署 Web 应用程序和其他程序,例如数据库或机器学习流水线中的计算。对于我们的用例,我们将使用它提供一个可重现的 Python 执行环境(Python 语言版本和库)来运行我们生成式机器学习流水线中的步骤。
本章余下部分的许多示例和本书中的项目需要安装 Docker。有关如何为您的特定操作系统安装 Docker 的说明,请参阅此处的指南。要验证您已成功安装该应用程序,请在终端上运行以下命令,该命令将打印出可用的选项:
docker run hello-world
Python 与 TensorFlow2 生成式 AI(一)(2)https://developer.aliyun.com/article/1512062