量子机器学习教程-全-
量子机器学习教程(全)
原文:Quantum Machine Learning
协议:CC BY-NC-SA 4.0
一、量子机器的崛起:基础
小智慧就像玻璃杯里的水:清澈、透明、纯净。大智慧就像大海中的水:黑暗、神秘、不可渗透。
—罗宾德拉纳特·泰戈尔
1983 年 4 月 14 日,洛斯阿拉莫斯实验室庆祝成立四十周年。物理学奖得主理查德·p·费曼(Richard P. Feynman)在题为“遵守量子力学定律的微型计算机”的演讲中指出,基于经典逻辑的计算无法轻松有效地处理描述量子现象的计算。他提出了他对能够以量子方式运行的计算的设想。在做出这些历史性的评论之前,费曼一直是计算机利用量子力学定律的思想倡导者,他说,“底部有足够的空间”和“自然不是经典的”。如果你想对自然进行模拟,你最好把它做成量子力学,”这意味着要正确地模拟量子系统,你必须使用量子计算机。
量子计算是在量子模拟的背景下发展起来的,人们努力建造遵循量子力学定律的计算设备。加州理工学院于 1999 年发布了约翰·普雷斯基尔教授关于量子计算的讲稿供公众查阅[1]。随后,人们对这个令人兴奋的领域越来越感兴趣,这个领域有望成为物理学定律与应用技术实践相结合的奇点。
文献中对量子计算机有各种定义。就本书的一般目的而言,量子计算机是一种计算设备,其计算过程可以用量子理论的定律明确描述。为什么我们期望量子计算机比经典计算机更有优势?这是因为传统计算机固有的构造方式。将传统计算机的能力加倍,需要两倍的电路和相关的门电路来解决问题。相比之下,每次只添加一个量子位,量子计算机的能力就可以提高大约一倍。
这本书是如何组织的
前三章提供了对量子力学科学和经典机器学习技术相结合的见解,这将成为经典信息技术力量与物理力量相遇的奇点。后续章节对各种量子机器学习算法、量子优化和高级 QML 算法的应用(例如,HHL、量子退火、量子相位估计、优化、量子神经网络)进行了系统、结构化的研究。这本书最后讨论了先进的研究领域,如量子行走,哈密顿模拟,和量子升压。
一切都辅以当今行业和研究中常用的开源库的实践练习,如 Rigetti 的森林和 QVM,谷歌的 tensor flow Quantum(2020 年 3 月发布),以及 Xanadu 的 PennyLane,并附有实现说明。在适用的情况下,讨论了访问与特定算法相关的量子计算和机器学习生态系统的各种选项。这本书附有练习中使用的所有代码示例。这些代码将定期更新,以跟上该领域的进展,并可从以下网站下载: https://www.apress.com/de/book/9781484270974
。
量子计算的本质
现代计算机是建立在处理信息的电子电路基础上的物理设备。算法,即计算机程序或软件,是我们操纵这些电路来执行我们想要的计算并获得其输出的管道。这些计算设备的物理过程涉及电子、原子和分子等微观粒子,可以用电路电特性的宏观经典理论来描述。
如果光子、生物 DNA、电子和原子等非常小规模的系统被直接用于处理相同的信息,这将涉及使用一套特定的数学结构,与我们现有的经典计算案例中的结构不同。这个被称为量子理论的数学框架被用来捕捉这样一个事实,即大自然的行为与我们的直觉告诉我们的非常不同。量子理论自二十世纪初发展以来,一般来说是小尺度物理最全面的描述。
当考虑数字计算和通信的基础时,人们通常会想到二进制数字或位。一个比特在任何时候都可以是 0 或 1,就像我们桌子上的硬币可以是正面也可以是反面一样。量子计算机使用量子比特,或量子比特,它们在任何给定的时间可以是 0 或 1,或者处于两种状态(称为叠加态)。这就像抛硬币一样;当硬币在空中旋转时,它肯定不会显示正面或反面;我们可以认为它是一个叠加(将在本章后面以及第四章中进一步阐述)。
这允许某些操作并行运行,而不是顺序运行,这意味着它们以指数方式减少了某些算法中所需的操作数量。因此,它们并不是普遍更快(即,每个操作本身仍然需要相同的时间来完成),这意味着在量子计算机(QC)上浏览互联网、编写 Word 文档或播放视频不一定更快。这就是为什么量子计算机无法取代日常使用的标准经典计算设备。
量子计算机到底有什么优势?一个例子在分子模拟领域很有用。为了模拟具有 42 个原子的青霉素分子,电子配置的指数大参数空间将需要 10 个 86 个状态,这比宇宙中的原子数目还多;量子系统只用 286 个量子比特就可以做到这一点。在经典系统中,模拟一个咖啡因分子需要 1048比特,这大约是地球上原子的 5 %- 10%。一个量子系统只需要 160 个量子位元就可以执行相同的任务。
作为另一个例子,假设我们想在一台 64 位计算机上做一些“简单”的事情:在一台“快速”的经典计算机上,一直添加数字 1,直到 64 位寄存器溢出。你可以合理地估计,一台现代的“快速”计算机每秒可以执行 20 亿次+1 加法;但是,按照这种速度,为了完成使寄存器溢出的任务,计算机要运算大约 400 年,因为它是一点一点地增加的。然而,一台 64 量子位量子计算机可以同时拥有所有这些数字 0 到 2 64 ?? ?? ??!如图 1-1 所示。每一台经典计算机都可以用量子物理学的原理完全描述,但反过来就不正确了。
图 1-1
经典计算与量子计算
许多公司和联邦机构都采用了质量控制。谷歌、IBM、Xanadu、Rigetti、D-Wave 和许多其他公司都在争夺“量子霸权”。众所周知,空中客车公司举办了一场量子计算竞赛,以解决航空航天业中长期存在的计算挑战。D-Wave 的 2000Q 型量子退火计算机安装在美国宇航局、 1 谷歌和 USRA(大学太空研究协会)。
QC 时代正在到来,也许比许多人想象的要快得多。随着这个时代的到来,随着世界各国政府继续投资于这项诱人的未来技术,更广泛的工业机构也意识到了一个日益严峻的挑战:合格和训练有素的劳动力。质量控制的基础是跨职能的,需要物理、数学和编码。这一领域的发展需要在人员发展方面的投资,需要大学和学术机构承诺为感兴趣的学生开设越来越多的相关课程。
这本书从现有的机器学习算法和研究人员目前正在研究的算法中汲取灵感、激情、算法和框架。附录涵盖了一些数学背景作为参考,如张量积和傅立叶变换。
量子位
量子位或量子位是一个两级量子力学系统,由量子态表示。任何可以在两种离散状态下测量的量子粒子都可以被用作量子位;例如,俘获的离子,如单个钙离子(使用电磁场限制在光腔中)、极化的光子和电子自旋。
量子位类似于经典计算系统中的经典位。两者之间的基本区别是,在经典系统中,一个比特可以取值 0 或 1,而量子比特可以取值∣0⟩和∣1⟩之间的一整套值,代表状态的叠加,如图 1-4 所示。在量子力学中,通常使用竖线和尖括号将抽象复向量空间的元素 ψ 表示为 ket ∣ ψ ⟩,并将它们称为 kets 而不是向量。
量子位的状态
经典位的状态是数字(00 或 11),量子位的状态是二维向量空间中的向量。这个向量空间也被称为状态空间。量子系统的状态由一个矢量∣ ψ ( t )⟩给出,它包含了系统在任何给定时间的所有可能信息。向量∣ ψ ( t )⟩是希尔伯特空间的成员(稍后描述),并且可以是时间变量(即,可以随时间改变)。在量子力学中,通常将状态规范化(即,找到一种方法来设置内积⟨ * ψ * | * ψ * ⟩ = 1)。图 1-2 显示了一个量子位的量子态的二维表示。
图 1-2 中的两个上图显示了如果基础状态是∣0⟩和∣1⟩.时向量的位置请注意,向量的顶部是常规 x 轴或∣0⟩轴上的位置,底部是常规 y 轴或∣1⟩.上的位置最上面的两个图显示了州∣0⟩以及∣0⟩和∣1⟩.的州向量量子位读取∣0⟩的输出的概率为 1(或 100%),反之亦然
图 1-2
用于量子计算的二维量子态
如果我们假设一个量子比特态是由∣ ψ ⟩给出的,那么 α 和 β 的平方分别是∣ ψ ⟩分别在∣0⟩和∣1⟩被发现的个体概率,并且 α 和 β 的平方之和为 1,其中 α 和 β 被称为换句话说,有 100%的可能性出现这样的结果,∣是∣0⟩或者是∣1⟩,并且这种结果的概率总和是 1。图 1-2 的底部图示出了一个例子,∣0⟩操纵量子态 0.8,∣1⟩操纵量子态 0.6,分别转化为 36%和 64%的概率。
布洛赫球
布洛赫球是量子位状态空间的三维几何表示,作为虚拟单位球表面上的点。这是表示量子位的两种方式之一。另一种方式是用狄拉克符号表示量子位。简而言之,布洛赫表示采用二维(2-D)图形表示,并以三维表示来描述它,量子位的状态由球体上的一个点来表示,如图 1-3 所示。
图 1-3
布洛赫球
图 1-3 中布洛赫 2 球面的角度 ϕ 称为方位角角,从正 x 轴到状态∣ ψ ⟩在xyy平面上的投影测量。角度 θ 被称为极角,是从正 z 轴到代表∣ ψ ⟩.的布洛赫向量的距离
布洛赫球允许概率中出现负数和复数。在量子信息处理中通常使用的单个量子位的操作可以在布洛赫球描述中完全描述。布洛赫球对于解释量子门特别有用。我们前面的例子和相关讨论中使用的概率( α 和 β )可以换成表示状态所在球面上的振幅或纬度。量子计算中的态可以表示为一个向量,它从原点开始,到单位布洛赫球的表面结束。通过对状态向量∣ ψ ⟩应用酉运算(稍后描述),它可以围绕图 1-3 中的球面旋转和移动。按照惯例,球体的两极分别取为球体顶部 z + (或北极点)的∣0⟩和球体底部z-(或南极点)的∣1⟩。在经典极限中,一个量子位元可以在布洛赫球上的任何地方拥有量子状态,但它会缩减为经典位元,只能在两极找到。
量子计算中使用的线性代数符号可能需要快速介绍。在量子力学中,向量用保罗·狄拉克发明的狄拉克符号来表示。在狄拉克符号中,标识矢量的符号写在一个 ket 内,例如,矢量或T6a在量子力学中写成∣ * a * ⟩.向量 a 的对偶向量用 bra 表示,写成⟨ * a * |。他们的内积写成 bra-kets 。换句话说,两个向量∣ψ1⟩和∣ψ2⟩之间的内积由⟨ψ1|ψ2⟩给出,结果类似于向量代数的点积。另一方面,两个向量| * ψ * 1 ⟩和| * ψ * 2 ⟩的外积在 Dirac bra-ket 符号中给出|ψ1⟩⟨ψ2|并且它产生一个维数为 m × n 的矩阵两个向量|ψ1⟩和|ψ2⟩称为正交如果⟨ψ1|ψ2⟩= 0。
可观测量和算子
在量子计算中,对于任何一个动态变化的、物理上可以作为量来测量的变量 x ,都有一个对应的算符。操作员
本质上是隐士。它由向量空间中的正交特征向量基组成。特征向量的定义包含在附录中。
希尔伯特空间
从数学的角度来看,向量∣ ψ ⟩是定义了内积的完备向量,是一类称为希尔伯特空间的向量空间的元素,用表示。本书中提到的向量空间包括实数和复数空间,并且是有限维的,这简化了处理 QC 所需的数学。由于
是有限维的,可以选择一个基将这个基中的向量表示为有限列向量,用有限矩阵表示算子。对于某个正整数 n ,量子计算感兴趣的希尔伯特空间通常具有 2 * n 维。一个量子位状态的数学表示存在于一个 2 维的希尔伯特空间中。原则上,量子系统的状态向量可以是任意维的希尔伯特空间的元素。在本书中,让我们考虑有限维*希尔伯特空间。
当在量子系统中执行计算时,固定一个基并将其称为计算基通常是方便的。在此基础上,我们使用长度为 n 的二进制字符串将狄拉克符号中的 2n基向量标记如下。
(1.1)
在等式 1.1 中, n 是指二进制字符串的长度。
希尔伯特空间由一组向量 ψ 、 ϕ 、 φ 组成...以及 a 、 b 、 c 、。。,它展示并遵循四个属性。
-
是线性空间。线性向量空间由两组元素和两个代数规则组成。
-
一组向量 ψ , ϕ , φ ...以及 a 、 b 、 c 、。。
-
向量加法规则和标量乘法规则。
-
-
中的标量积是严格正的。
*** 是可分的。
*  **完成**
**
**如果你对希尔伯特空间的进一步讨论感兴趣,试试 R. Shankar (Plenum,2010) [2]的量子力学原理。
量子计算和量子机器学习最重要的两个基础是叠加和纠缠。让我们快速浏览一下这两者的基本原理,然后在我们浏览书中各种例子时进一步展开,在这些例子中,每个属性都被利用了。
一般来说,如果一个算子满足下列关系,就说它是线性的。
(1.2)
衡量
与经典物理学相比,量子力学中的测量具有挑战性。在经典世界中,测量是简单的,并且被假定为不影响其参数或特征被测量的项目;例如,我们可以自由地测量一个球的重量,然后测量这个球的周长,并确信另一次测量这个球的重量会得到同样的结果。
在量子世界中,任何给定量子态的测量都会导致相应波函数的坍缩。根据量子力学的假设,一个物理变量必须有真实的期望值和特征值。这意味着代表物理变量的算子具有特殊的性质。通过计算物理变量期望值的复共轭,可以看出物理算符是它们自己的厄米共轭ℍ= ℍ.自身为埃尔米特共轭的算子称为埃尔米特算子。
根据量子力学的假设,作为动态变量的测量的可能结果的结果是应用于状态 ψ 的线性厄米算符 A 的本征值A??n。在这种情况下,厄米算符是可观测的,例如粒子的可观测位置向量
。获得∣0⟩或∣1⟩的概率与量子位在测量基础上的投影有关。厄米共轭可以用作数学工具来计算一个状态到另一个状态的投影。
埃尔米特复数的一个性质是:一个数的共轭或共轭υ??, υ 是这个数的复共轭υ⋆:υ??=υ⋆。厄米算符的另一个性质是它们的特征值是实数,这有助于测量某些物理性质。测量的结果保证是一个特征值,比如说,被观察系统的 λ 。测量结果由投影操作员 P 描述。 P 在性质上是埃尔米特,因此根据埃尔米特算子的定义P=P+,等于其自身的平方:P2=P。
按照量子力学的假设,量子系统被测量后,描述该状态的波函数会坍缩。因此,尽管在之前的系统状态,测量可能是基础的叠加。但是,在测量完成后,系统坍缩到对应于测量结果的基态。数学上,如果测量前的原始状态是∣ ψ ⟩,则测量后系统的状态∣ψ′⟩由下式给出
(1.3)
投影测量也可以用一个可观测值来描述,它是一个埃尔米特算子 A 作用于系统的状态空间。由于 A 是厄米的,它的谱分解由下式给出
(1.4)
其中AI为 A 的特征值 P i 为 A 的特征空间上的正交投影。在这种情况下,执行投影测量与测量关于分解的可观测值I=∑PI相同,其中特征值 a i 对应于第 i 个测量结果。
谱分解定理(SDT)告诉我们,对于作用在有限维希尔伯特空间上的每一个正规算子 T ,都有一个由 T 的特征向量∣ * T * * j * ⟩构成的
的正交基。换句话说,属于某个向量空间的算子 T 相对于该向量空间的某个基具有对角矩阵表示。这个结果被称为谱分解定理。假设算子 A 满足某种基的谱分解定理。根据 SDT,我们总是可以对角化有限维中的正规算子。从线性代数中我们知道,对角化可以通过将基变换为由特征向量组成的基来实现。基的改变是通过将运算符 T 与酉运算符共轭来完成的。假设一个算子 T 带特征值 T * j 满足谱分解定理对于某些基∣vj*⟩.然后,SDT 的运算符 T 由下式给出
叠加
叠加原理是量子物理学的基础。该原理指出,量子系统的状态可以叠加,以形成几个状态的组合,例如经典物理中的波,以形成相干量子状态,该状态是与其组成状态分离且不同的状态。因此,尽管一个量子位可以存在于∣0⟩状态或∣1⟩状态,它也可以存在于∣0⟩状态和∣1⟩.状态的线性组合状态因此,如果一个量子位状态由∣ ψ ⟩给出,那么这个量子位的叠加态可以写成
(1.5)
其中 α 和 β 是复数,称为量子位状态的振幅。
设想叠加原理的最简单的方法是想象一束光经过一个偏振滤光器,这个滤光器会使光垂直偏振,比如说,在∣0⟩.状态下现在考虑第二偏振器,其轴水平于从第一偏振器出射的垂直偏振光束(即,强制水平偏振);在这种情况下,不再有任何光从第二偏振器射出。这是因为水平偏振轴与垂直偏振轴成 90 度∘,光束通过第一偏振滤光器已经具有垂直偏振轴,这加强了水平状态。在我们的例子中,根据等式 1.5 ,水平状态是∣1⟩.状态状态∣1⟩与垂直偏振光正交,并且两个偏振器抵消出射光的剩余部分,从而完全不给出任何东西。现在,如果第二个偏振镜的轴倾斜到另一个角度,比如 30 度 ∘ ,那么我们将有一些光从整个装置中射出。
在另一个例子中,我们考虑一个原子量子位,它是基于一个呈现上下自旋并受磁场影响的电子。电子不是传统意义上的自旋;自旋这个词描述了它的角动量,可以量子化表示向上或向下(1 或 0)。在我们测量量子位以查看它是 0 还是 1 之前,它处于叠加状态,这意味着它可以是 0 或 1 的一部分,或者换句话说,像 0-37%,1-63%这样的加权组合(参数 α 和 β )。物理学家还没有开发出自旋背后的物理现实的可视化。但是他们可以用数学方法描述自旋,并在实验室实验中预测其行为。
在任何给定的时刻,量子位可能会以某种比例的自旋偏向 1 或 0。只有当我们测量量子位时,它才会坍缩成一个确定的状态,∣0⟩或∣1⟩,如图 1-4 所示。
图 1-4
量子叠加和测量效应——当测量到一个离散的状态时,叠加就崩溃了
∣0⟩和∣1⟩可以用列向量的形式表示如下。
和
因此,通过取 0 和 1 路径的状态向量的线性组合来描述叠加,因此一般路径状态由类似于等式 1.5 的向量来描述。
(1.6)
如果量子位(例子中的光子或电子)被物理测量以查看它当前在哪个路径中,我们以概率| α | 2 在路径 0 中找到它,并且以概率| β | 2 在路径 1 中找到它。最后,因为我们应该在中找到光子,正好一个路径,从概率的角度来看,我们必须有,
(1.7)
等式 1.7 也被称为玻恩法则【3】的数学表示。
如果你有兴趣了解更多关于叠加态的知识,可以参考 Nielsen & Chuang [3]的《量子计算与量子信息》一书。
纠缠
纠缠是多个量子系统之间关联的一个特例。这种性质在古典世界中是没有类比的。当两个(或更多)粒子,例如两个光子或两个电子,处于纠缠态,并且对它们中的一个进行测量时,那么该测量可以立即影响对其他粒子的相同测量的行为,与它们之间的物理距离无关。这种现象的非直觉性质是如此奇怪,以至于阿尔伯特·爱因斯坦称之为“幽灵般的超距作用”,因为还没有关于它为什么会发生的已知解释。当我们测量一个量子位元时,测量的行为会瓦解它的状态,同时瓦解其他纠缠量子位元的状态。
图 1-5
测量单个量子位会导致它的叠加态崩溃一个确定的状态,从而导致所有其他纠缠的量子位崩溃
如图 1-5 所示,这种现象使我们能够推断出其他纠缠量子位的状态,无论它们之间的物理距离有多远。纠缠的量子比特成为一个具有单一量子态的系统。
量子算符和门
像经典的可逆门一样,量子门在逻辑上是可逆的,但是它们在普适性上有显著的不同。最小的通用经典可逆门必须使用三位,而最小的通用量子门只需要使用两位。一些通用的经典逻辑门,如 Toffoli 门,提供了可逆性,可以直接映射到量子逻辑门。量子逻辑门由酉矩阵表示。任何作用于二维量子系统或一个量子比特的幺正算符被称为单量子比特量子门。在量子电路模型中,逻辑量子位沿着线传输,量子门作用于这些量子位。一个作用于 n 量子位的量子门通过 n 线将输入量子位传送给它,其他 n 线将输出量子位带离量子门。因此,量子门可以由具有正交行的 2n×2×2n矩阵来表示。单量子位门如哈达玛门用 2 × 2 矩阵表示。
在数学上,一个运算符被描述为一个规则,当它被应用到由一个 ket 描述的一个状态时,比如∣ * ψ * ⟩,它就被转换成在同一空间中的另一个 ket,比如∣ψ’⟩;当同一个操作符应用于一个胸罩时,它输出另一个胸罩。
和
这本书突出了一些基本的量子门,相关的矩阵,和算子,如酉,泡利,交换,等等。强烈建议您学习更多关于运算符和门的知识[3]。
标识运算符
恒等运算符,通常用 I 表示,是一个对角元素全为 1,其余元素全为 0 的方阵。因此,单位矩阵在数学上可以定义为
(and) and
Inm= 0,当n≦m1.9
下面是一个 2 × 2 单位矩阵的例子。
酉算子
如果一个算子与它自己的伴随算子相乘时产生一个单位矩阵作为输出,则该算子被认为是酉的。酉算子有一个与其共轭算子相等的逆算子。
算子 U 的逆用U1 表示。这满足以下关系。
(1.10)
其中 I 是恒等运算符。
为了使 U 成为一体,
(1.11)
和
(1.12)
酉变换将一种基中的算子矩阵变换为另一种基中的同一算子的表示。例如,对于二维矩阵,从∣ r i ⟩到∣eI⟩的基的变化由下式给出
值得注意的是,量子进化的酉性意味着量子操作是可逆的,除了那些用于测量的算符。这种可逆性是把注意力限制在封闭系统上的结果。任何不可逆的经典计算都可以被可逆的经典计算有效地模拟。量子计算也是如此。
矩阵和门的泡利群
泡利矩阵组是一组单量子位量子算符,它产生泡利门(应用于量子电路),并跨越所有单量子位算符形成的向量空间。泡利门在量子计算中的重要性是巨大的,因为任何单量子位酉算符都可以表示为泡利门的线性组合。
认为有四种不同的泡利算符,包括恒等算符(但有些作者省略了恒等算符)。在各种文献中有许多不同的符号用来描述泡利算符。在本书中,出于上下文的考虑, I 、 X 、 Y 和 Z 被一致使用。然而,出于完整性的原因,提到了所有的符号,因为泡利算符是在计算的基础上定义的。
有趣的是,NOT 门通常等同于 Pauli X 门,因为两者具有相同的矩阵表示和相同的基矢效应(即,它们反转基矢)。例如,零状态的列符号是
如果你将音符或 X 门应用于它,你有
(1.14)
类似地,x 运算符应用于∣1⟩时,会将其反转为∣0⟩,产生与非门相同的效果(因此,x 门也被称为位翻转门)。我们鼓励您验证这一点。
Z 算子也被称为相位翻转算子,因为它的作用是将状态向量围绕 Z 轴旋转 π 弧度或 180 度。泡利门 X、Y 和 Z 分别对应于绕布洛赫球的 X、Y 和 Z 轴的旋转。
相位门
相移运算器或旋转门使状态∣0⟩保持不变,但将∣1⟩状态旋转一个定义的角度或相位 θ 。
(1.15)
利用欧拉恒等式在 1.15 中,如果我们设 θ = π ,我们恢复泡利 Z 门是因为eIθ= cos(π)+I。sin(π)= 1。
如果我们在方程 1.15 中代入 θ = π /2,则得到eIθ=I,进而给出另一个叫做 S 的算子。
(1.16)
其中 S 操作器将原始状态绕 z 轴旋转 90 ∘ 或弧度。
t 操作符将原始状态绕 z 轴旋转 45 ∘ 或 π /4 弧度。T 门也被称为 π /8 门,因为 e iπ /8 可以被分解,留下绝对相位为| π /8|的对角线分量。
(1.17)
关于旋转类型和参数化门的更详细的讨论可以在 Nielsen 和 Chuang 的教科书中找到[3]。
笛卡尔旋转门
之前,您看到了几个相位门的属性。以下是 QC 和 QML 中常用的一些附加旋转门表示。
(1.18)
(1.19)
(1.20)
哈达马德门
哈达玛门创造叠加态。哈达玛门具有以下矩阵表示。
(1.21)
它将计算基础状态映射如下。
(1.22)
同理,。该操作将量子位状态旋转 π 弧度或 180 度,围绕xz 平面中的轴对角线。
哈达玛门的另一个性质是它是自逆的(即H=H—1);因此,
和
(1.23)
该操作相当于应用一个 x 门,然后绕 Y 轴旋转。
CNOT 门
CNOT 门,也被称为受控非门,是一个两量子位门。量子计算中的控制门涉及使用控制或 C 量子位作为第一个输入量子位,第二个量子位作为目标量子位。CNOT 门的第一个输入充当控制量子位:如果控制量子位处于∣0⟩状态,则该门不对目标量子位做任何事情;但是如果控制量子位的状态是∣1⟩,那么 gate 对目标量子位应用 NOT 或 X 运算符(等式 1.14 )。换句话说,在量子计算领域,CNOT 门迫使两个量子位纠缠在一起。
CNOT 门可能的输入状态如下:∣00⟩、∣01⟩、∣10⟩、∣11⟩.CNOT 门对这些状态的作用如下。
CNOT 门的电路表示如下
受控 CNOT 门的矩阵表示由下式给出
(1.24)
CNOT 的外部产品表示是
(1.25)
CNOT 门对于制备纠缠态是有用的。它是自伴的;第二次使用它会逆转它的效果。
交换门
交换门也是两量子位门。一个交换操作符反转输入量子比特状态中比特的状态。例如,它可以接收∣10⟩,并将其反转为∣01⟩. SWAP 运算符由以下矩阵表示。
(1.26)
密度算子
在本书遇到的其他算子中,最后一个重要的算子是密度算子。在一个封闭的纯量子系统中,很容易计算出找到某个状态∣ x ⟩.的概率是其振幅| α | 2 的平方(参考方程 1.7 )。一个纯单态∣ ψ ⟩的密度算符由其外积给出。
(1.27)
一个纯系统唯一的密度算符的平方的迹为 1:Tr(ρ2)= 1
如果一个封闭的纯系统的密度依赖于时间,那么密度算符的时间演化就幺正算符而言由下式给出
(1.28)
但是,在混合量子系统存在统计分布的环境下(例如系统-1 的 n 1 和系统-2 的 n 2 ),密度算符的一般描述可以解释这样一个混合物的性质。这是通过首先为每个状态制定密度算符,对这些状态应用适当的权重,然后总结所有的可能性来完成的。
于是,让∣ψI⟩代表混合量子系统中系综的 n 个可能态,其中 i ∈ {1... n },而 p i 是某成员处于相应状态的概率∣ψI⟩.因此,在这种情况下,整个混合量子系统的密度算符由下式给出
(1.29)
密度算子是厄米算子(即ρ=ρ;密度算子的迹是 1),并且密度算子对于任何状态向量总是正的。
哈密顿函数
系统的哈密顿量是量子力学、量子计算和量子机器学习中最重要的概念之一。量子优化、机器学习、变分算法中一些最重要的算法都依赖于哈密顿量。一个哈密顿量就是一个系统的总能量。它提供了经典力学和量子力学之间的物理联系。每个系统都有自己的哈密顿函数。决定系统如何随时间演变的是这个函数的形式,而不是这个值。哈密顿算符是量子力学中应用最广泛的算符之一。因此,理解构造哈密顿函数的过程在 QML 是非常重要的,正如你在后面的章节中看到的。
系统的时间演化
物理隔离或“封闭”量子系统的时间演化由薛定谔方程给出如下。
(1.30)
其中 H 是系统的哈密顿量。由于哈密顿量对应系统的总能量,量子系统可能的能量已经由算符 H 的本征值给出。时间 t 之后的系统状态由下式给出
(1.31)
而系统量子态的时间演化由么正算符描述。
(1.32)
不克隆定理
1982 年,Wootters 和 Zurek [4]推导出了现在所知的不可克隆定理,这是量子系统最基本的属性之一。这表明不可能创造一个属于特定希尔伯特空间的任意量子系统的精确完美的副本。与经典计算机相比,这增加了对量子计算机编程的挑战。因此,根据不可克隆定理,没有有效的量子操作可以将任意状态∣ ψ ⟩映射到∣ ψ ⟩ ∣ ψ ⟩.
忠诚
保真度是量子系统中一个状态与另一个状态“有多接近”的量度。保真度被描述为两个量子分布之间的统计混合或重叠量。
与经典系统不同,一般来说,要区分两个量子位元序列是不可能的,除非它们彼此正交。因此,如果两个状态不正交,则对这两个状态进行投影测量是没有意义的。该属性将度量限制为作为正运算符值度量或 POVM 进行。保真度是两种不同状态的可区分性的度量,给出了区分这两种状态的最佳度量。
保真度衡量两种状态之间的重叠。因此,如果ρ1=∣ψ⟩⟨ψ和ρ2=∣ϕ⟩⟨ϕ|是两种不同分布的密度算子,则系统的保真度由下式给出
(1.33)
等式 1.33 暗示|⟨ϕ|ψ⟩|2是系统处于状态∣ ϕ ⟩的概率,已知它已经处于状态∣ ψ ⟩.
以下是保真的基本属性。
-
两个纯态的保真度在{0,1}范围内的自变量中是对称的(即
)。
-
Fidelity is invariant when a unitary operator acts on it.
(1.34)
-
保真度等于 1 当且仅当ρ1=ρ2。
-
Tensor product of the density operators for fidelity is given by
(1.35)
复杂性
问题的复杂度是指对问题类别的研究,比如 NP-hard 或者 PSPACE。计算练习涉及从算法和计算时间的角度使用资源来解决特定的问题。为了估计总的计算成本等等,您需要分析运行算法(在计算系统上)所需的资源,这是解决问题所需要的。
问题可以是任何计算问题;例如,使用一系列图像对猫和狗进行分类。为了解释这两种动物之间的区别,我们可以将猫和狗的大小和形状定义为约束或标签。然后我们选择一种算法,它通常独立于硬件,来为我们完成这项工作。当我们运行该算法时,它需要两个主要的计算资源:运行时间和内存。
计算机运行一个算法的时间就是该算法在特定计算平台上的运行时间。根据经典计算的基本原理,通过验证数据库中的项目直到找到一个期望的项目,可以获得数据库搜索目标的解决方案。这个练习需要时间复杂度为 O ( n )的最坏情况场景。
量子复杂性理论[5]试图回答量子计算机相对于经典计算机在运行时的加速和效率问题。在本书中,复杂度一词指的是量子系统的渐近运行时复杂度。第二章第二章和第三章第五章详细阐述了复杂性。
格罗弗算法
最初,Grover 的搜索算法是为了在没有重复元素的非结构化环境中,在量子数据库中对特定元素进行无序搜索而创建的。在以随机顺序存储元素的数据库中找到特定元素的唯一方法是进行彻底搜索。Grover 的算法可以推广到搜索具有重复元素的数据库。Grover 的算法对于乘法常数也是最优的(即不可能提高其计算复杂度)。如果数据库由 N 元素{x1,x2 的数据库条目组成...、xN},那么 Grover 的算法利用量子性质查询数据库次使用 O (log N )存储空间找到一个标记元素 x 0 的概率很大。格罗弗算法可以用
通用门实现。从统计上来说,Grover 的算法大约需要一个
的顺序来尝试在量子数据库中找到一个标记的对象。例如,如果位串是 4 位,那么在经典上下文中,搜索算法将需要 241 = 15 次尝试来正确标记条目;相比之下,格罗弗的算法需要
次尝试。随着位串变得更大,Grover 算法提供的改进变得更加显著。
格罗弗的算法基于振幅放大,这是本书后面章节描述的一种技术。
为了解释格罗弗算法的机制,让我们考虑一个函数 f ( x )在空间中具有 n 个输入,其中N= 2= N和 x = ∈ {0,1} n 。设函数 f ( x )使得 f ( x ) = 1,当且仅当x=x??0对于特定的x0。因此,
(1.36)
挑战在于用尽可能少的评估数找到 x 0 。函数 f ( x )称为甲骨文 x 0 称为标记元素。
在实践中,神谕可能被视为一个黑匣子,其内部机制的细节可能被忽略。oracle 被建模为一个门,它接受一个 n 位输入并产生一个 1 位输出。神谕是不是一个有效的量子门,因为它不是单一的和不可逆的。
首先,∣0⟩1⨂∣0⟩2⨂∣0⟩3的 n 输入状态...⨂∣0⟩n≡∣0⟩⨂n全部初始化为∣0⟩.
作为第二步,哈达玛门被应用于这些∣0⟩输入状态中的每一个,从而总共有 H ⨂ n 门将每个∣0⟩ ⨂ n 输入转换成叠加状态。如果∣ ψ ⟩是所有可能的∣ x ⟩的叠加态,那么
(1.37)
Grover 算法的应用利用 Grover 算子,也称为 Grover 扩散算子 G 。
Grover 算子由下式给出
(1.38)
格罗弗算法的实现涉及两个哈达玛门,每个门需要 n 次运算。酉门控制条件相移,尽管整体复杂度取决于应用,但是时间复杂度是有效的,因为每次迭代只需要一次调用。发现 Grover 算法高效到需要计算 f ( x )小于 N 次才能找到 x 0 的地步。它按照的顺序求值,这是渐近最优的。与经典情境相比,这种量子情境在时间复杂度上有二次增益。
Grover 算法一般实现如下。
| **算法:格罗弗算法** | | **输入**:*N*= 2??【N和*f*;初始状态∣0⟩⨂*n* | | **输出** : *x* 0 概率 | | 第一步。应用 *n* + 1 个量子比特的二能级量子计算机 | | 第二步。应用哈达玛门初始化叠加:*h*⨂*n*∣0⟩⨂*n*。 | | 第三步。`for` 次`do`应用 Grover 运算符 *G* | | 第四步。在计算的基础上测量系统。 |图 1-6 显示了一个用五量子位电路实现 Grover 算法的例子。显示为绿色的 On 框表示如果测量,量子位的概率处于 On 状态。在这种情况下,它们开启的概率是 100%,除了中间的量子位,这是炫耀。如前所述,预言是按照渐近最优的顺序的评估。
图 1-6
代表五个量子位的 Grover 算法的电路。第一个登记处最初设在∣0⟩.方框中的 H 代表实现超级运算的 Hadamard 门。在这种情况下,预期迭代的顺序为,在模拟图像中表示为“Oracle”。[6]
肖尔算法
Shor 的算法是展示量子计算能力和重要性的基础。它可以用来分解质数,这意味着它可以在实际的量子计算机上破解加密代码(在本书写作时,一台足够大的量子计算机尚未建成)。
Shor 的有效因子分解算法由量子部分和经典部分组成。前一个是对所谓的寻序问题的基于量子的解决方案。因为这种算法隐藏了开创性的思想,它允许在步骤或门中分解大量的 N ,而不是最著名的经典方法,该方法要求渐近地,其中常数通常取为 0.9。
is a constant often taken as 0.9.
where
这意味着在经典(非量子)计算机上分解素数的最著名算法需要的时间量基本上与 N 的大小成指数关系。这就是 Shor 算法被认为重要的原因;运行它的量子计算机只需要多项式(而不是指数)时间。由于流行的 RSA 密码系统的安全性是基于素数分解的困难性,Shor 算法吸引了隐私和数据安全社区的大量兴趣。这个算法得到了很多人的关注!
寻序部分是肖尔算法的 only 量子部分;剩下的涉及经典计算。Shor 算法的一个简单表述就是,它利用寻序来寻找某个奇数 N 的因子。
肖尔的算法通过将问题简化为一个阶或周期的寻找练习来分解质数。如果 x 和 N 都是互为质数的正整数,也就是说,它们没有任何公因数并且<N,那么 x 的阶就是下面给出的关系中最小的正整数 r
xr= 1 mod1.39
肖尔算法的目的是当 N 为要因式分解的数时,求 r 即x*r的周期。
Shor 算法的基础起源于数论,如下所述。
f(r)=x【r【mod】1.40
其中 f ( r )是周期函数, x 与 N 互质(即它们没有公因数,而 N 是要因式分解的数)。
海森堡的测不准原理
理解量子计算和量子机器学习挑战的深度的关键在于实现海森堡的不确定性原理。
沃纳·海森堡(1901-1976)指出了经典世界和量子世界的主要区别。根据经典的自然定律,如果作用在物体上的初始位置、速度和所有其他力都是已知的,那么借助牛顿定律,就可以以绝对的准确度精确地预测这个物理系统的未来路径(位置和速度)。既然这个预测是准确的,那么经典物理就是确定性。
海森堡的测不准原理,在其原始形式[7]中陈述:如果用不确定度δp??]??]xT7]测量一个粒子的动量分量x,那么它的x位置,同时不能比δx=/(2δp??]xT17)更精确地测量;普朗克常数在哪里?因此,量子物理系统的测量结果有一个自然的精度极限。三维中的不确定关系可以用数学方法表示如下。
⑼??]xpx≥2;⑼??〖和〗??〗p〖??〖??〗??〗和〖??〖??〗2;δ??【z】【p】【z】≥2 1.41
根据海森堡的原理,尽管有可能同时精确测量一个粒子的位置或动量,但是当同时测量这两个时不可能以任意精度测量这两个可观测量。对一个量子系统的位置的测量不能在不对系统产生大动量的情况下完成;量子粒子的位置测量不能被动完成。测量行为扰乱了粒子位置的固有性质,并给了它动量。测不准原理是物质本身固有的性质,因为它嵌入在物质的波动性质中。**
认识到测不准原理适用于物理观察和相关测量以及经典和量子系统*之间的任何相互作用,而不考虑任何特定的观察者,这一点非常重要。这一原理深刻地影响了量子光学、光子学、各种形式的量子计算机的硬件设计工作,以及我们从中受益的无数其他设备和过程。
从数据中学习:人工智能、人工智能和深度学习
从数据中学习用于分析和确定性结果不可用的情况。这一基本事实导致了数据科学与量子力学世界的联姻,在量子力学世界中,决定论基本上是不存在的。
在我们的日常生活中,决定论失效的情况围绕着我们。例如,如果我们给一个五岁的孩子看一张动物园的照片,并问里面是否有一头大象,我们很可能会得到正确的答案。然而,如果我们问一个二十岁的人,大象的定义是什么,我们可能会得到一个不确定的答案。通过数学定义向我们解释了对大象的描述;我们通过观察大象或它们的照片来了解什么是大象。换句话说,我们从数据中学习。
人工智能这个术语是在 1956 年创造的。从那时起,人工智能(AI)就占据了人们的想象力,尤其是科幻迷。A. C. Clarke 在 2001:太空漫游中的 HAL the computer 和星球大战中的 C-3PO 就是两个例子。机器学习(ML)起源于人工智能的早期思想家,他们多年来试图简化算法方法来解决现实生活中的问题,包括决策树学习、归纳逻辑编程、聚类、强化学习和贝叶斯网络等。
术语 AI 、 ML 和深度学习经常互换使用。然而,当大多数人谈论 AI 时,他们指的是 ML。从根本上说,ML 使用算法从数据中学习,然后对数据集所代表的系统或环境进行确定性的预测或预测。因此,通过使用大量数据和算法来“训练”机器,使其能够学习如何执行特定任务,而不是用特定的指令集重复手动编写软件例程来完成特定任务。图 1-7 展示了深度学习(DL)、AI、ML 之间的区别。
人工智能是一门类似于物理或化学的科学。这门学科利用数学和统计理论,并着眼于创造智能程序或机器的过程,这些程序或机器可以主动解决自己的问题,这一直被认为是人类的特权。人工智能通常被分为弱人工智能、强人工智能和超智能(强)人工智能。
机器学习是人工智能(AI)的一个子集,它使用数学和统计见解赋予计算系统自动学习和提高效率的能力,因为它从经验中学习,而不需要任何进一步的手动编程调整。与人工智能一样,人工智能中的任务可以使用各种算法来完成,这些算法可以用来解决各种相应的问题。
深度学习是机器学习的一个子集,它在很大程度上使用神经网络来分析类似于人类神经系统的结构内的不同问题。
图 1-7
AI、ML 和 DL 之间的关系
第 2 和 3 章详细阐述了与这些理论相关的算法。
量子机器学习
计算智能利用机器学习算法解决优化问题。ML 的最大挑战之一是处理多维数据。叠加、纠缠和上下文敏感性的原理被证明是为难题提供解决方案的有力支持者。量子力学在解决被研究的系统表现出上下文行为的问题上是有用的。在这种情况下,自然的量子力学性质被证明是理想的匹配[8]。
近年来,量子神经网络 (QNN)和量子卷积神经网络 (QCNN)成为研究人员深感兴趣的领域。这些领域研究量子状态下的经典数据编码选项,并利用量子系统的叠加特性来解决特定问题,例如利用 QCNN 或 QNN 算法的图像分类,以及使用量子图像灵活表示(FRQI)、数字图像的新型增强量子表示(NEQR)和量子布尔图像处理(QBIP)等算法的量子图像处理(QIP)[9,10]。
量子理论的前景和承诺对数据科学家越来越有吸引力,因为它的固有性质将几何和概率统一在一个框架中。随着大数据的激增接管了数字世界,实时处理不同维度空间中不断增长的数据量给行业和政府带来了挑战;例如,金融行业正试图理解 QML 和量子场论的深度,以开发用于风险分析、预测等的金融算法,而联邦政府正从安全和减轻威胁的角度研究 QML 和优化理论。随着全球安全威胁的出现,对相同的威胁进行建模并在此基础上进行预测对经典算法来说是一个越来越大的挑战[11]。
这本书主要集中在从经典系统获得的经典数据集的 QC 处理作为可观测量,如文本,图像和金融数据,利用经典量子接口。当你阅读这本书时,你会看到 QC 和 QML 任务的各种选项;也就是说,并不是所有形式的量子计算机都能以同样的效率做同样的工作。为此,我们利用谷歌的 Cirq、OpenFermion 和 TensorFlow Quantum、D-Wave 的工具、Xanadu 的 PennyLane 和 Strawberry Fields 等。
当你阅读这本书时,你会看到几个由物理学推动的领先的机器学习算法,最后是量子行走和 QBoost 等前沿作品。
设置软件环境
在你变得量子化并开始根据物理定律进行黑客攻击之前,设置好你的基本软件环境是一个很好的实践。当你阅读这本书时,我们在我们的基础环境上安装了各种其他的库。
我的操作系统是 Linux Ubuntu 18.04 LTS。Python 3.6.x 及更高版本应支持该代码。对于 TensorFlow Quantum、Cirq 等的最新支持,建议使用 Python 3.7+版本。网站上有在 Windows 和 macOS 上安装 Python 的说明,供您选择 Python 安装。本书中的大部分代码都基于 Jupyter 笔记本。你应该为你的操作系统下载相关的库;因此,代码独立于操作系统。
Python 可以从各种网站以各种风格下载。以下是两个例子。
图 1-8
Anaconda Python 支持的版本
-
默认的 Python 下载站点在
www.python.org/downloads/
。这里提供了在 Windows、Linux 和 macOS 上下载和安装 Python 的选择和说明。 -
我的偏好是 Anaconda Python(Anaconda 3)at
www.anaconda.com/products/individual
,提供各种操作系统支持的免费 Python,如图 1-8 所示。
Python 在 Ubuntu Linux 上的安装是使用其原生打包系统完成的。
apt-get install
macOS 提供 MacPorts 或 HomeBrew 作为打包系统。Anaconda 有一个叫做 conda 的包装系统。Python 使用pip
或pip3
进行 Python 3.x 安装。
你需要安装一个 Jupyter 笔记本来使用这本书里的代码。如果你想访问 Python IDE,可以从 www.jetbrains.com/pycharm/download/#section=linux
下载非商业用途的免费 PyCharm。
Anaconda Python 的个人免费发行包可以通过 Jupyter 笔记本和名为 Spyder 的免费 IDE 下载,如图 1-9 所示。
图 1-9
Anaconda Python dashboard 提供了 Jupyter、Spyder 等软件包
如果 Anaconda 是在 Windows 上下载的,那么可以通过从启动➤ Anaconda3 ➤ Anaconda PowerShell 提示符打开 Anaconda PowerShell 并运行conda
命令来完成包升级。巨蟒的安装说明在 https://docs.anaconda.com/anaconda/user-guide/tasks/install-packages/
。
一旦安装了 Python,例如,建议为 QML 代码创建一个永久的工作空间目录(随意将名称或路径更改为更有意义的名称)。
$ export QML = "$HOME/qml" # path and directory
$ mkdir – p $QML
强烈建议为本书中的所有编码工作创建一个单独的隔离环境。这可以防止同一环境中其他项目和编码版本之间的意外重叠。
选项 1:原生 Python
为此,需要将 Python 中的virtualenv
安装在 Python 中,如下所示。
$ pip3 install –user –upgrade virtualenv
collecting virtualenv
[...]
Successfully installed virtualenv
一旦安装了 virtualenv,就可以如下创建独立的 Python 环境。
$ cd $QML
$ virtualenv qml # create isolated environment "qml"
[...]
Installing setuptools, pip, wheel...done
然后激活创建的虚拟环境。
$ source qml/bin/activate #activates the isolated env
(qml) sgangoly@ubuntu:~$
要退出隔离系统以恢复到您的全局 Python 环境,请输入下面的deactivate
命令。
(qml) sgangoly@ubuntu:~$ deactivate
选项 2: Anaconda Python
使用conda
包管理器创建隔离的虚拟环境很容易。
$ conda create --name qml # create isolated environment "qml"
[...]
$ conda activate qml # activate isolated environment
(qml) sgangoly@ubuntu:~$
要退出隔离系统以恢复到您的全局 Python 环境,请键入下面的conda deactivate
命令。
(qml) sgangoly@ubuntu:~$ conda deactivate
只要环境处于活动状态,安装在隔离虚拟环境中的任何软件包都不会与安装在系统任何其他部分的任何其他软件包或库进行交互。
安装所需的软件包和库
您需要安装一些必要的包和库来设置我们的基本系统。随着您阅读本书的进展,您可以在需要时安装额外的库和包。如果您使用的是全局 Python 环境,请使用pip3
,如果是在隔离的虚拟 Python 3.x+环境中,请使用pip
,比如前面例子中的"qml"
。如果使用 Anaconda 安装,使用conda
命令。Ubuntu 环境可能需要sudo
命令。
对于原生 Python(选项 1)
$ pip3 install –upgrade jupyter numpy pandas scipy scikit-learn matplotlib
Collecting jupyter
[...]
对于蟒蛇(选项 2)
$ conda install -c anaconda scikit-learn
$ conda install -c anaconda matplotlib
如果安装成功,没有任何错误或警告,尝试使用以下命令打开 Jupyter 笔记本(参见图 1-10 )。
图 1-10
Jupyter 笔记本:终端输出和浏览器界面
$ jupyter notebook
[...]
[I 21:26:32.372 NotebookApp] The Jupyter Notebook is running at:
[I 21:26:32.372 NotebookApp] http://localhost:8888/?token=2c99c1f3108242781947a02d6ff692187f19af7565c355cb
Jupyter 笔记本浏览器打开后,点击新建选项卡,选择 Python 3,如图 1-10 所示。这将打开 Python 3.x 安装的第二个 Jupyter 笔记本浏览器。您已经准备好编码了!
如果你不想安装任何东西,欢迎你在 https://colab.research.google.com
试用谷歌的 Colab。它构建在 Jupyter 笔记本上,并且原生支持 Python。除了编码友好之外,它还支持 GPU 和 TPU (Google 的 TensorFlow 处理单元)。
量子计算云接入
如果你有兴趣接触真实量子位,以下是建立免费(但有限)公共云访问各种真实量子硬件系统的指南。除了 Xanadu 之外,大多数 QC 环境都基于超导量子位,Xanadu 是业界第一个使用半导体光子量子位创建 QC 的公司,最近还开放了对其 QC 平台的云访问。
对 QC 环境的云访问非常容易。这只是一个向他们注册并获得访问权限的问题。除了提供基于云的访问,几乎所有的质量控制供应商都提供模拟器选项,你可以在上面尝试算法,如 Rigetti 的 QVM。以下是一些提供商的网站,它们通过云提供有限数量的量子位。
-
瑞迪:
www.rigetti.com
-
IBM Q 体验:
https://quantum-computing.ibm.com
-
世外桃源:
https://xanadu.ai/request-access
-
d 波飞跃:
https://cloud.dwavesys.com/leap/login/?next=/leap/
-
亚马逊(Amazon)最近推出了一款名为 Braket 的云产品。客户可以使用 Amazon Braket 在他们选择的基于不同技术的量子处理器上运行他们的量子算法,包括来自 D-Wave、IonQ 和 Rigetti 的系统。模拟和量子硬件作业都通过统一的开发体验进行管理,客户只需为使用的计算资源付费。要开始使用 Amazon Braket,请访问
https://aws.amazon.com/braket
摘要
量子计算和机器学习算法在工业中的应用近年来出现了历史性的增长。第一章讲述了进入 QML 世界所需的一些基础知识。附录 A 涵盖了一些重要的数学背景作为参考,如张量积和傅立叶变换。下一章涵盖了经典机器学习概念的本质,作为翻译到量子领域的发射台。
Footnotes 1
www . nas . NASA . gov/project/quantum . html
2
在圣安德鲁斯大学的网站上可以找到一个很棒的布洛赫球体模拟。圣安德鲁斯。交流电。uk/physics/quvis/simulations _ html 5/sims/Bloch sphere/Bloch sphere。html
****
二、机器学习
机器学习(ML)作为人工智能和认知科学的一个子领域出现。机器学习的三种主要类型是监督学习、非监督学习和强化学习。还有其他几种,包括半监督学习、批量学习、在线学习。深度学习(DL)是一个特殊的子集,包括这些不同类型的 ML。它扩展它们来解决人工智能中的其他问题,如推理、规划和知识表示。
什么是机器学习?1959 年,阿瑟·塞缪尔(Arthur Samuel)将机器学习定义为“在没有明确编程的情况下赋予计算机学习能力的研究领域。”ML 是一门专注于教计算机如何学习的学科,在今天的背景下不需要任何特定任务的编程。机器学习探索创建从数据中学习并对数据进行预测的算法。
Note
这一章从应用的角度看经典机器学习的一些基本原理,例如学习的类型、方差和偏差。它沉迷于使用公开可用的数据类型的实践练习。代码可以从该书的网站上下载。ML 本身是一个庞大的领域,不可能在一章中包含它的所有方面。我们在整本书中重温经典概念,包括深入的误差校正和特征工程,以适应数据驱动的预测中的量子概念。
传统上,手工制作和优化算法以完成特定任务一直是构建遗留软件和处理数据操作和分析工作负载的方式。从高层次来看,传统编程关注的是对充分理解的输入数据的确定性结果。相比之下,最大似然法有能力解决一类或一系列输入-输出对应关系不清楚的数据集的问题。
ML 构成了从数据中学习。ML 的一个例子是垃圾邮件过滤器。垃圾邮件过滤器基本上是从用户标记的垃圾邮件示例、常规的非垃圾邮件示例、垃圾邮件造成的已知广泛欺诈案例(如钓鱼邮件、要求个人信息的众所周知的欺诈等)中“学习”。),以及其他类型的用例。
由 ML 管理的垃圾邮件过滤器从示例中学习,并将其所学应用于可疑的垃圾邮件。然而,这种学习过程和“学习”结果的后续算法应用是概率性的(即,它并不总是完美的或确定的)。因此,有时你会在垃圾邮件文件夹中发现合法邮件,在收件箱中发现垃圾邮件。垃圾邮件过滤器“看到”的例子越多,它训练自己检测合法垃圾邮件的次数就越多,它在保护我们的邮箱方面的表现就越好。
在这种类型的任务中,ML 比传统编程成功的主要原因之一是不断增长的数据量。垃圾邮件过滤器通常根据规则进行操作。过去,我们必须手动定义规则来阻止邮箱中的垃圾邮件,我们必须定义“发件人”、“收件人”、“主题”等等,如图 2-1 所示。
图 2-1
手动输入规则以获得理想结果的传统方法
随着现代世界大数据时代流量和数据的爆炸式增长,人类手动定义规则并跟上不断增长的数据量的能力已经远远低于所需的效率水平。因此,机器已经接管了这项任务,来定义处理大块数据的综合规则,并应用这些规则来提供问题的解决方案。ML 系统用来学习的数据被称为训练集。在垃圾邮件过滤器的例子中,标记和过滤垃圾邮件或定义算法的性能的训练数据。在这种情况下,性能测量可以是正确或不正确的垃圾邮件的比率。性能测量被称为准确度,这个值,正如本章中的一些例子所展示的,通常会随着训练和时间的推移而提高。图 2-2 显示了将 ML 应用于垃圾邮件过滤器的工作流程。
图 2-2
用 ML 过滤垃圾邮件
本章介绍了机器学习算法的基础知识、数据驱动预测的原理、性能和复杂性。本章从经典的角度探索了数据驱动的模型和预测以及各种学习算法,随后是一些实际操作的例子。随后的章节建立在由量子物理学驱动的经典机器学习的概念上。
在我们深入一些基本和必要的机器学习概念之前,快速浏览一下该主题中涉及的一些术语可能是有益的。
机器学习和大数据 :直到最近,大多数 ML 工作负载都是在单机(计算机)上执行的。然而,GPU(图形处理单元)、谷歌的 TPU(张量处理单元)和分布式计算的发展现在使得大规模运行大数据的机器学习算法成为可能,这些算法分布在各个集群中。
算法和模型
这些天有太多关于 ML 和它的各个方面的文献。通常,很难区分算法和模型,因为这两个术语在文献中可以互换使用。在本文中,我们将两者区分如下。
算法是由数学或统计公式定义的方法论。
模型是定义输入数据和输出之间关系的数学对象,是用数据训练算法后得到的。一旦输入进入模型,输出就产生了;但是模型需要首先被训练以获得有意义的输出。
算法和模型的区别如图 2-3 所示。
图 2-3
算法和模型
不同的训练数据导致产生具有不同系数的不同模型。有效算法的一个例子是房价预测,其中价格基于房间数量、地块大小、居住空间等。然而,在算法被采用并且由它产生的结果可以被信任之前,需要有一些它工作的证明。
来自算法的“预期”值是指构建一个估计器。所有的 ML 算法都是估计量。评估者告诉我们对未来的预期,但实际上并不预测未来。理想情况下,我们更希望有一个能完美预测未来的估计器!但那将类似于具有远见或精神洞察力。从数学和科学的角度来看,我们创建模型并优化它们,以尽我们最大的能力提高精确度。
以下是数据的一些基本属性和相关模型,在衡量算法的成功时会考虑这些属性。
偏见
偏差表示估计器离目标有多远,或者换句话说,模型预测离正确值有多远。这直接取决于对训练数据的假设。假设的数量越多,模型泛化的可能性越低;泛化错误的一个例子是假设数据是多项式,而它是线性。因此,根据经验,低偏置通常是首选。高偏差模型通常使训练数据受到欠拟合(本章稍后讨论)。偏差告诉我们预测的平均值是否接近正确的位置,或者误差是否在一个方向或另一个方向偏向(或偏斜)。
数学上,偏差定义如下。
(2.1)
其中, X 是概率分布,是同一概率分布的估计量。
从方程 2.1 中可以看出,偏差显示了一个估计值平均可能会偏离目标值多少。
综上所述,以下是偏倚的主要性质。
-
偏差误差最常见的原因之一是模型简化假设,以实现更容易学习的目标函数。
-
作为一个算法家族,参数算法通常会有很高的偏差。
-
学习很快,因此计算成本更低,因此很有吸引力
-
它们很简单,但不太灵活
-
它们在预测复杂数据时表现不佳,因为这些数据特征不太适合简化的假设。
-
减少对目标函数的假设数量是达到低偏差的一种方式。其中一些技术是决策树、 k 近邻 (KNN)和支持向量机 (SVM)。
变化
方差是预测对训练集敏感程度的指标。方差直接取决于数据的分布。方差告诉我们,与未来预测的实际值相比,估计值有多宽或多窄。由许多自由度组成的模型,如多项式模型,通常表现出高度的变化,这导致训练数据的过拟合(在本章后面详述)。数学上,
(2.2)
换句话说,方差是平均值的平方差的平均值。方差衡量相关数据的分布程度。方差有两个更广泛的品种:总体方差和样本方差。
总体方差通常用 sigma 平方(σ2 设计。以下是计算数据集的总体方差的步骤。
总体方差在数学上由下式给出
(2.3)
其中 x 表示个体数据点, μ 是平均值, N 是整个总体中数据点的个数。
以下是计算σ2 的步骤。
-
计算数据集的平均值。例如,我需要计算一小时内在我的街道上看到的汽车数量。为此,我们记录了对三辆车的观察,一辆车、两辆车、六辆车和三辆车。平均值是数据的平均值,在本例中为
。
-
每个数据点与平均值的差异由下式给出
(3 − 3 = 0); (1 − 3 = − 2); (2 − 3 = − 1); (6 − 3 = 3); (3 − 3 = 0)
-
差值的平方给出如下:0,4,1,9,0。
-
The average of the squared differences gives the final variance value.
样本方差的计算略有不同。总体方差指的是整个数据集,而样本方差指的是数据集的子集。样本方差通常是在定义明确的数据集空间中获取的,例如连续五个小时计算每小时看到的汽车数量。在这种情况下,我们可能希望通过每小时分组的数据块来计算每小时的汽车数量。然后我们将平均值的平方差除以N1。换句话说,样本方差s2 由下式给出
(2.4)
其中 y 表示单个数据点,是平均值, n 是在样本空间中数据点的数量。
方差是如果使用了不同的训练数据,目标函数的估计值将改变的量【15】。与方差相关,目标函数是根据训练数据计算的,因此受到训练数据的影响。在理想情况下,如果训练数据集发生变化,目标函数的变化应该是最小的。一个好的算法应该解决输入和输出变量之间隐藏的潜在映射。
当目标函数的估计变化相对于训练数据集中的变化为小时,表示低方差,例如,诸如线性回归和逻辑回归的参数算法。
当目标函数的估计值的变化相对于训练数据集中的变化较高时,指示高方差。通常,像决策树这样的非参数算法往往具有很高的方差。算法中较高的灵活性会导致较高的方差误差。
标准差计算为方差的平方根σ2σ。这里, σ 是标准差。
不可约误差由于数据中的噪声和未知变量而产生。因此,在任何与数据科学相关的项目中,数据清理都是至关重要的。
这本书有可供下载的实践练习代码。从这一章开始,我们遵循惯例,用以下图标标注的代码片段可以下载。
下面是一个使用matplotlib
Python 库和分布式随机数据可视化方差概念的快速练习。
如果您使用 Python 3.7 或 3.8 打开 Jupyter 笔记本中的variance.ipynb
代码文件(如第一章所述),您会看到一个住宅区房价假设数据分布的方差和标准差计算示例。代码如清单 2-1 所示,对应的直方图如图 2-4 所示。
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
houseprice = np.random.normal(150.0, 50.0, 20000)
plt.hist(houseprice, 75)
plt.show()
Listing 2-1variance.ipynb
对于正态分布,数据是随机生成的。分布以大约 150 为中心,20,000 个数据点的标准偏差为 50.0。
图 2-4
方差直方图. ipynb
直方图显示,标准偏差约为 50.0,约为 100 和 200,数据以约 150 为中心。
可以分别使用.std
和.var
函数调用计算数据的标准差和方差,如图 2-5 所示。
图 2-5
方差的标准差和方差
对于标准偏差,获得的值约为 50.38,非常接近清单 2-1 中指定的值。方差是 2538.34,大约是我们预期的 50.38 2 ,因为标准差是方差的平方根。
偏差与方差的权衡
方差与模型的复杂性直接相关。如果模型的复杂性增加,方差通常也会增加。然而,增加复杂度也会减少偏差。正如预期的那样,降低复杂性会增加其偏差并减少其方差。因此,在选择模型时,通常需要在方差和偏差之间进行权衡,并且需要精确平衡这两者。
权衡取舍的选择通常归结为数据的过拟合与欠拟合。高度的方差会导致过度拟合,而高偏差模型会使训练数据欠拟合。图 2-6a 显示了一个低偏置的例子。之字形图有一个低偏差,但高方差。在图 2-6b 中,线性图相对于数据具有较低的方差,但是具有较高的偏差,与每个数据点的误差有关。
图 2-6
偏差和方差权衡
方差和偏差之间的权衡对于减少误差很重要,这是任何模型的目标。误差可以用方差和偏差来表示,如下所示。
(2.5)
其中 ϵ 为误差, β 为偏差,σ2 为方差。
默认情况下,对目标函数值的假设越少,灵活性越大,因此偏差越小。另一方面,与训练数据的变化相关的目标函数的变化越少,方差越小,算法越不灵活但越稳定。图 2-7 描绘了两者之间的关系。
图 2-7
偏差和方差权衡
参数或线性算法通常具有高偏差但低方差,而非参数或非线性算法通常具有低偏差但高方差。
机器学习中偏差和方差之间的权衡关系对于算法决策者来说是一个不可避免且无处不在的问题:增加偏差会减少方差,减少偏差会增加方差。这里的圣杯是在模型复杂性允许的情况下找到优化性能的最佳点。
数据过度拟合
假设在一场足球比赛中,一名前锋在她得到的第一个得分机会就射门得分。那么我们是否可以推测所有的前锋都能抓住每一个机会进球?我们不能做出这样的假设,因为更多的得分机会最终没有进球。基于数据量不足而高估预测结果在 ML 中被称为过拟合。如图 2-8 所示。
图 2-8
过度拟合
当模型与训练数据集的拟合过于精确时,乍一看似乎是“正确的”,但因为它与训练数据的拟合过于“接近”,所以它可能会排除在测试时在之前没有“看到”的有效数据。一个例子是一个曲线函数,几乎触及图 2-8 中的每个数据点,误差很小或根本没有误差。在这种情况下,最佳拟合曲线与训练数据吻合得非常好,但在使用模型以前未见过的测试数据进行评估时,可能表现不佳。因此,模型预测的准确性由于过度拟合而受损,因为它倾向于记忆训练数据,而不是从中学习。过于灵活的模型往往显示出高方差和低偏差。
定义明确的特征可以检测过度拟合。通常,过度拟合的模型对于训练数据给出了很好的结果,但是对于看不见的新测试数据却表现不佳。一个例子是 96%的训练准确率和 68%的测试准确率。一种解决方案是使用更适合数据的算法或模型,如 k 倍交叉验证(本章稍后解释)。
数据拟合不足
当相对僵化的模型运行时,会发生欠拟合,该模型过于简单,无法捕捉输入数据中的所有趋势。这通常在训练数据和测试数据上都得分较低。拟合不足、不太灵活的模型具有低方差和高偏差。图 2-9 显示了与图 2-8 中的过拟合模型相同的原始数据的欠拟合。
图 2-9
欠拟合
数据的理想拟合
理想情况下,您需要一个基于方差的误差和基于偏置的误差都较低的模型,如图 2-10 所示。因为,如等式 2.5 所示,误差与偏差的平方成比例,与方差成线性比例。因此,偏差与方差的权衡非常重要。
图 2-10
理想匹配
在 ML 中,一个重要的期望方面是实现一个“完美点”或“甜蜜点”,作为过度拟合和欠拟合模型之间的平衡,如图 2-11 所示。
图 2-11
完美或甜蜜的地点
为了实现良好的拟合,遵循以下经验法则。
-
过度拟合和欠拟合都会降低模型性能。
-
过度拟合相对难以发现,因为它在训练数据上表现很好,但在看不见的新测试数据上表现很差。过度拟合模型倾向于“记忆”数据。确认的几种方法是尝试不同的算法,如 k-fold 交叉验证来验证或阻止验证数据集或尝试重采样。
-
欠拟合更容易发现,因为它在训练和测试数据上都表现不佳。
减轻模型中过度拟合的过程称为正则化。正如本章前面所讨论的,正则化可以通过几种方式实现。最近与量子机器学习相关的工作正在寻找正则化的方法之一是优化,这将在接下来的章节中讨论。
学习过程中应用的正则化量可以用超参数来控制。超参数是与学习算法相关但与模型无关的参数。超参数在训练数据之前是固定的,并且在整个训练过程中保持不变。超参数调整是构建 ML 系统的一个非常重要的方面。随着我们在书中的深入,我们会对其进行扩展。超参数调整在计算上是昂贵的,但有时是不可避免的。设置错误的超参数的影响可能是深远的。例如,如果正则化超参数设置得非常大,则绘图可能几乎是平坦的,梯度接近于零。相关的学习算法可能不会表现出过度拟合,但是它不会产生可接受的好的解决方案。
优化的一个例子是通过将参数子集删减为零来防止算法中的长迭代。如果模型的参数由 τ 给出,那么它与由 a 成本函数 C 定义的成本相关联。成本函数 C 由几个不同的方面组成,其中最重要的是损失。损失函数将在本章后面更详细地讨论。损失衡量一个模型的预测与目标的接近程度。
模型准确性和质量
机器学习使用类似于学校考试分数的评分策略。精度由下式定义
另一方面,误差被定义为准确性的反义词。
从定义可以直观的看出,误差是错误分类的病例数与总病例数的比值。这种估计精度和误差的方案类似于利用近似值的经验法则,而不是采用面向精度的算法。
在实践中,有明确定义的方法来估计精度和误差以及两者之间的关系。例如,一些方法包括假阳性和假阴性。正则化可以由成本函数定义如下。
2.6(a)
其中,正则子是惩罚表达式。正则化器向训练参数添加约束。这涉及一种将乘以非负数的较小系数向量相加的方法:
2.6(b)
其中 λ 是小系数向量。 α 为非负数。 α ( λ )是惩罚项(或正则项),可以根据我们希望赋予它的权重而变化。如果 α = 0,则正则化为零,因此正则化不存在。随着 α 变大,具有较大范数的参数受到严重惩罚。范数的选择通常被认为是 L1 或 L2,这是量子计算和量子机器学习未来章节的重点。
贝叶斯学习
贝叶斯学习 (BL) [17]是一种重要的机器学习方法,因为它具有根本不同的逻辑,并使用概率模型。BL 试图将学习转化为一个计算问题。这种学习视角利用的是整合而不是优化。
贝叶斯定理指出,给定 B 的概率, A 的概率等于 A 的概率乘以给定 A 的 B 的概率除以 B 的概率。从数学上讲,这意味着以下几点。
(2.7)
其中, a 和 b 是随机变量 A 和 B 的子集或值,并且
(2.8)
其中, P ( a , b )是 a 和 b 都发生的概率。术语P(a|b)称为后,P(b|a)称为可能性,和 P ( a )称为前。如果给我们一个训练数据集, D ,随机变量 a 和 b ,目标是考察概率, P ( a , a | D )。 P ( a , a | D )是发现发生事件的概率 a ,给定 a 给定 D 。在数学上,该模型表示为
(2.9)
其中, τ 为模型的参数。 P ( a , b | τ )是模型的参数化分布,写成无条件概率。P(τ|D)是给定数据,某个期望的参数集是正确选择的参数集的概率。从概念上讲,训练数据集的根本原因是为给定数据找到一个最佳参数,在这种情况下,由 τ 表示。未知项P(τ|D)可以使用贝叶斯公式计算,公式如下
(2.10)
这里, P ( τ )解决了之前对参数的假设,这导致了在模型看到数据之前的最佳模型。贝叶斯学习中的先验 P ( τ )允许在没有看到数据的情况下对参数 τ 进行有根据的猜测。如方程式 2.6 所示,在某些情况下,它可以与正则化子相关联。基于集成的方法和基于优化的方法之间存在权衡。当缺乏已知的结构时,两者都具有挑战性,并很快成为难以解决的问题。**
应用 ML 工作流
我们经常得到大量的数据,坐下来思考,“我到底该如何处理这些数据,我该如何解决这个问题?”。解决 ML 问题有一些基本的经验法则。以下是大致的步骤。
-
获取数据。
-
探索数据。数据是关于什么的?
-
建立一个模型。
-
评估模型。这个模型有效吗?
-
优化模型。
-
部署模型并监控性能。如有必要,调整模型并重试。
数据探索是开始构建高效 ML 模型的关键步骤。这包括三个主要步骤。
-
数据收集
-
数据清理
-
数据处理
尽管数据收集是标准流程,但数据清理可能是整个 ML 工作流程中最耗时的流程之一。清理脏数据、充满不可理解的特殊字符的数据、算法不能很好理解的空格以及各种其他类型的噪音一直是数据工程师和科学家的灾难。如今,有一些现成的数据清理解决方案;例如,谷歌云平台(GCP)托管的 Dataprep 工具。
如果预期目标不明确,数据处理的任务可能会很棘手。一个 ML 爱好者需要定义一个目标,她/他试图通过向模型提供数据集来实现这个目标。现在有 Python 和其他语言的专用库,极大地方便了数据处理。Python 特别有 NumPy、Pandas 和 scikit-learn,它们贯穿于本书。ML 的整体工作流程如图 2-12 所示。
图 2-12
机器学习工作流
数据探索的下一步是建模。这包括数据检查、从数据中提取特征集、选择最适合数据集的适当算法,以及最终构建所需的模型。
第三步模型评估,涉及误差估计和精度计算。
第四步是模型优化,向模型输入更多数据,并调整参数以获得更好的性能。一旦优化完成,输出将反馈到步骤 2 和 3,直到误差和精度水平被认为是可接受的。
第五步也是最后一步是模型部署,涉及生产级使用和可视化。
模型验证
一旦我们决定了一个模型,并构建和测试了它,我们需要验证它。用已经看到的数据来验证模型是错误的。例如,如果我们重用训练数据来测试模型,那么它的预测将会非常好,因为它是在已经看到的数据上测试的。因为模型对该数据集的预测是“正确的”,所以它对模型预测的效率产生了错误的信心。同样的模型,当用新数据测试时,可能会在预测中表现得更差。因此,一种常见的做法是将数据集分开用于训练和测试,下面将简要讨论其中的一些数据集。
坚持的方法
这种方法只是将部分数据作为训练集进行“筛选”,以评估模型并选择最佳模型;然后测试模型(即,用剩余的数据作为测试集来验证它)。这意味着“测试集”是随机选择的,并保留用于测试。
在 hold-out 方法中拆分数据是 ML 中的常见做法。根据经验,数据被随机分成 80%或 75%,或 70%的训练数据和 20%或 25%或 30%的测试数据,如图 2-13 所示。
这种分割没有固定的规则。在进行分割时,要牢记数据的性质和训练的计算成本。训练数据量越大,计算成本越高。作为一个讨论的问题,如果数据集中的划分是,例如,50%训练和 50%测试,那么这是而不是被认为是“好的”,因为训练数据量太低,增加了模型可能没有看到足够的数据来有效训练的风险。类似地,大约 95%的训练数据和 5%的测试数据的分割是不理想的,因为这样测试数据的百分比太低了。这是不可接受的,因为如果最终模型在太大的数据集上训练,那么用在小得多的数据集上训练的模型来测试它是不理想的。这可能类似于选择一辆 f1 赛车参加沙漠中的达喀尔拉力赛。
图 2-13
坚持验证
尽管保留法适用于通用数据,但当某些数据可能有偏差时,它不是很有效。例如,考虑一个 ML 考试,学生从 50 个问题库中得到 20 个问题,这些问题是简单和困难问题的混合。因为在坚持法中,数据是随机选择的,所以我们在这种情况下随机选择问题。假设这个学生在这次考试中得了 80 分。在这种情况下,我们可以认为他的分数反映了他对该学科的真实知识吗?我们不能。这可能是因为由于问题选择的随机性,大多数问题都比较容易。为了获得他的知识的真正精髓,我们需要对同一名学生和类似的随机选择的数据集进行更多的测试,然后取平均分数。
由于保留方法中的训练/测试分割是随机进行的,如果选择了代表整个数据特征的全面数据集,模型可以很好地学习并提供很好的预测。此外,如果测试集也是相对容易的测试集,则该模型可以提供高精度。但是数据选择的随机性使得训练和后续预测的准确性有些不可靠。例如,我们可以选择一个缺乏数据多样性的“弱”数据集进行训练,其中模型没有学到多少东西,并最终根据剩余的数据对其进行测试,这些数据包括模型未知的大多数多样性,从而导致模型性能较差。因此,在排除法中,模型精度可能会因数据的随机分割而发生显著变化。
交叉验证法
我们如何确保更好、更有效地验证数据驱动模型?一个解决方案是交叉验证。交叉验证的基础如下:在训练集上训练模型,然后每个验证集评估一次。然后对评估进行平均。这种方法提供了更高的精确度。然而,因为训练时间乘以验证集的数量,所以这在计算上比以前的保留方法更昂贵。其中一种也很常见的交叉验证方法是 k 倍交叉验证。
在选择模型的一般情况下,训练数据有可能不代表整个数据集,在这种情况下,数据集可能是偏斜的,并且可能发生过度拟合。k 重交叉验证有助于避免这种情况,因为在这种情况下,模型是使用训练数据集中的数据来训练的。然后,使用为测试保留的数据来评估模型性能。
在 k 重交叉验证中,数据被分成 10 到 20 块 k 等截面,称为 k 重。图 2-14 显示了 k 重交叉验证工作流程图。
图 2-14
k 倍交叉验证
通常情况下,其中一个褶皱,比如褶皱- i (图 2-14 中=5),是预留给测试的。图 2-14 中的其他褶皱用于训练。一旦训练完成,模型将根据 fold- i 进行测试。以这种方式,在通过训练和测试循环所有折叠之后,比较预测的准确性。
图 2-15 描述了一个 k 倍交叉验证的例子,其中 k = 6。
图 2-15
六重交叉验证
这种六重交叉验证将其数据分成六个块,一个保留用于测试,其余五个数据折叠保留用于训练。精确度栏显示精确度在 80%到 92%之间变化。平均精度由下式给出
可以对同一数据集的不同范围的不同算法运行交叉验证。根据哪种算法提供了可接受的精度范围,可以选择该算法作为给定数据集的最佳算法。
总之,交叉验证是而不是通常用于寻找最佳表现模型。它更多地用于验证或了解特定模型对于给定数据集和新测试数据的性能。现实生活中的一般方法是通过测量模型来调整它,同时用不同的参数改变它。
交叉验证的优点是,它有助于用数据系统地测试新模型,并且可以识别具有高方差或过度拟合问题的模型。
交叉验证的一个缺点是对数据集运行多个模型可能计算量大且耗时。目前解决时间问题的一种方法是在多个 CPU/GPU 核心或集群上并行运行交叉验证任务。
作为一个体验 k-fold CV(交叉验证)的练习,让我们看一下kFoldCV.ipynb
代码。这里使用的数据是一个公开的数据集,名为虹膜。这个特定的数据集由 150 朵鸢尾花的花瓣和萼片的长度和宽度的测量值组成。数据集中有三类鸢尾花,每类 50 个实例:海滨鸢尾、杂色鸢尾和刚毛鸢尾[13],如图 2-16 所示。
图 2-16
鸢尾(Radomil,CC BY-SA 3.0)、杂色鸢尾(Dlanglois,CC BY-SA 3.0)和海滨鸢尾(Frank Mayfield,CC BY-SA 2.0)
清单 2-2a 、 2-2b 和 2-2c 中的代码查看一个模型,该模型试图根据给定的属性(花瓣和萼片的宽度和长度)预测正确的鸢尾属物种。
#Import Libraries
import numpy as np
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn import svm #import (SVM) for classification
from sklearn import datasets
iris = datasets.load_iris() #load the data
# Data split into train/test sets with 25% for testing
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.25, random_state=0)
# Train data for Linear Support Vector Classifier (SVC) model for prediction
clf = svm.SVC(kernel='linear', C=1).fit(X_train, y_train)
# Performance measurement with the test data
clf.score(X_test, y_test)
Listing 2-2a
k-Fold Cross-Validation
of Iris Dataset from kFoldCV.ipynb
scikit-learn [14]的 val_score 库允许我们通过交叉验证来评估分数。数据被输入到 train_test_split()函数,该函数便于将数据分割成训练和测试块。在这个模型中,我们从训练 75%的数据和测试 25%的数据开始,这由 test_size=0.25 指定。按照 k-fold CV 的惯例,测试数据是随机抽取的(random_state=0)并留作测试之用。
该方案给我们四个数据集:X_train
包含 75%的虹膜测量数据,X_test
包含 25%的保留用于测试的虹膜测量数据,y_train
和y_test
包含对应于测量的物种。
使用的模型是支持向量分类 (SVC),它是支持向量机(SVM)的一部分。这将在本章后面讨论。此处型号命名为svc
。score()
函数测量 SVC 模型的性能。针对保留的测试数据集对 SVC 模型进行评分。分数给定为
(2.11)
然而,由于数据集大小只有 150,这是一个相当小的数据集,其中 75%用于训练,25%用于测试。因此,我们很有可能过度适应。k 倍交叉验证是一个很好的方法来验证这一点,看看我们是否有更好的拟合。
在kFoldCV.ipynb
代码的下一部分,如清单 2-2b 所示,SVC 模型用于将整个数据集(即iris.data
的测量值)和目标数据iris.target
传递给函数cross_val_score().
,我们使用交叉验证cv=5,
,这意味着它将使用五个不同的数据集,并保留一个数据集用于测试。数据集是随机选择的。
#cross_val_score a model, the data set, and the number of folds:
cvs = cross_val_score(svc, iris.data, iris.target, cv=5)
# Print accuracy of each fold:
print(cvs)
# Mean accuracy of all 5 folds:
print(cvs.mean())
Listing 2-2bContinued: 5-Fold Cross Validation
kFoldCV.ipynb
这段代码从每次迭代(总共 5 次)或“折叠”中返回一个错误值列表,如下所示。
然后对这五个值进行平均,以给出虹膜数据集的 k 倍 CV 的误差度量。
(2.12)
如果我们比较 2.12 和 2.11 的结果,我们可以立即推测 5 倍 CV (2.12)的结果比以前更好;因此,这是一个明确的改进。
这里通常的方法是看看是否有比这个结果更好的方法。为了获得 2.6 的结果,使用了线性核(kernel=
' linear
')。一种方法是用可能更适合的基于多项式的内核来测试模型和相应的数据行为。线性拟合是否优于多项式拟合取决于数据特征。因此,看看清单 2-2c 中所示的kFoldCV.ipynb
代码的下一部分,我们尝试了一个内核,它是多项式的 poly 。
svc = svm.SVC(kernel='poly', C=1).fit(X_train, y_train)
cvs = cross_val_score(svc, iris.data, iris.target, cv=5)
print(cvs)
print(cvs.mean())
Listing 2-2cContinued: K-Fold Cross-Validation with Polynomial Kernel
from kFoldCV.ipynb
运行多项式内核后,它会给出以下五倍误差值和相应的平均值。
(2.13)
2.13 和 2.11 之间的比较表明,多项式核给出的值低于线性核。这表明多项式可能过拟合。这里要吸取的教训是,如果我们没有使用 k 倍 CV 进行验证,而是使用标准的训练/测试分割,我们就不会意识到我们过度拟合了。这是一个简单但很好的例子,说明了 k 倍简历的重要性。
线性模型通常不太灵活,因为它只有两个自由度,而高次多项式由于有几个自由度而非常灵活。k 倍交叉验证运行的结果通常用模型技能得分的平均值来概括。一个好的做法是测量技能分数的方差,如标准差或标准误差。CV 因为简单而受欢迎。与其他方法(例如简单的训练/测试分割)相比,它通常会导致对模型技能的更少偏差或更少乐观的估计。
回归
回归是研究如何最好地拟合一条曲线来汇总数据。例如,农业产量“通常”与降雨量直接相关。回归构成了监督学习的一些最强大和最广泛研究的算法。在这种方法中,我们试图通过可能最适合它们的曲线来理解数据点。回归算法有几种类型。随着我们进入量子机器学习的领域,将有更多关于回归和相关算法的内容要说。
线性回归
顾名思义,线性回归是对一组观测数据进行直线拟合。一个例子是足球队队员的身高和体重。图 2-17 显示了该数据集中的数据和曲线。
图 2-17
线性回归
在图 2-17 中,X 轴表示身高,Y 轴表示体重。一旦绘制了数据点,教练可能会看着图并认为虽然大多数球员的身高和体重匹配,但有些人不匹配,他们可能需要开始健身制度来增加或减少一些体重。如果教练画一条曲线来最好地拟合这些数据点,他可能会以一条直曲线或一个线性图结束。
在这个例子中,曲线的方程由一条直线给出,它是 y = mx + c ,其中 m 是直线的斜率 c 是常数。线性回归可以建模为确定性函数[5]。
(2.14)
其中,参数包含在向量τ∈ℝn和 x∈ℝn中,其中ℝ是实数的空间, N 是参数的维数。偏差τ0 可以包含在τϵx中作为一个额外的维度。
线性回归中的学习考虑寻找参数 τ ,该参数可以将方程 2.14 中的函数 f 拟合到训练数据以进行有效预测。
最小平方技术
最小二乘技术包括使用平方损失(本章稍后解释)。直线拟合中产生的误差由各个数据点到直线的距离给出。我们将所有这些误差平方,并计算它们的总和。这样,如果有负误差,那么从误差产生的角度来看,它们不会抵消正误差,给我们一个假阳性。
这类似于方差计算。一旦知道了数据点的距离,就可以计算出误差并使其最小化。
梯度下降
梯度下降 (GD)是一种迭代技术,它逐渐调整一组特定训练数据集的模型参数,以最小化成本函数。这种技术可以找到各种问题的最佳解决方案。GD 的理论性深入文献可以在参考文献[15]中找到。GD 中的一个标准挑战是在不知道误差曲线的情况下找到一个最优值!
该过程包括从图 2-18a 中 X 轴上变量 X 的随机值开始。X1 的随机误差可通过关系式 error = f(x1)计算。误差的梯度也可以用斜率来计算。数学上,我们需要取误差函数的导数来计算梯度。
图 2-18a
梯度下降步骤 1
误差导数给了我们斜率或梯度倾斜方向的指示。此时,随机计算第二个数据点 x2(如果未知),如图 2-18b 所示。
图 2-18b
梯度下降步骤 2
接下来,如图 2-18c 所示,点 x2 的误差计算为 error = f(x2),测量误差梯度,然后我们“猜测”点 x3 的值并重复该过程。
图 2-18c
梯度下降步骤 3
最后,计算完所有数据点及其梯度后,梯度下降曲线如图 2-18d 所示。
图 2-18d
梯度下降步骤 4
GD 计算从一个随机点开始,猜测下一个。随着我们越来越接近收敛,这些步骤变得越来越小。步长在接近收敛时变得重要,以免错过或超过最小值。GD 中的一个常见问题是接近最小值。对此的解决方案是从随机点开始多次运行该算法,最终,该算法找到最小值。
梯度下降有几种变化。以下是最重要的两个。
-
批量梯度下降:在这种方案中,每种算法在整个训练数据集上为梯度的每次迭代计算成本。该算法的一次迭代被称为批次。
-
随机梯度下降(SGD) : SGD 为每个训练实例计算系数,而不是在一批实例结束时。相比之下,对于大型数据集,GD 可能会很慢,因为每次迭代都需要对数百万个数据集进行计算。SGD 将训练集随机化以减少系数多样性,并帮助避免陷入局部最小值。SGD 对于大型数据集非常有效,因为它只需要相对很少的次数(通常为 10 到 20 次)就可以收敛。
非线性和多项式回归
多项式回归用于更一般的回归情况,其中数据分布可能不太适合线性(直线)拟合。多项式拟合允许更多的自由度。然而,更多的自由度并不总是好的;根据数据集的不同,它可能会导致过度拟合。
目前 ML 中最成功的非线性回归模型是神经网络,你在下一章看。
分类
机器学习算法中的分类是一项基本任务,它处理将类别标签分配给来自问题领域的示例。
机器学习中的预测建模有各种类型的分类。本节重点介绍以下类型。
-
二元分类器
-
多类分类器
-
多标签分类器
-
不平衡的分类
唯一标记数据的类别提供了为特定任务表征数据的明显优势。前一节讨论了回归,它主要是关于数据集的曲线拟合。您已经看到最佳拟合曲线是一个输入数据项并分配一个数字的函数。与回归相反,分类指的是一个 ML 模型,它为其输入分配离散的标签。分类通常是处理类或离散值的监督学习算法。典型的输入是特征向量,典型的输出是类。
预测建模的一个很好的例子是我们在本章前面的 ML 的第一个用例:垃圾邮件过滤器。这基本上包括将电子邮件分类为“垃圾邮件”或“非垃圾邮件”
对于一个二进制分类器,输出是二进制(即是/否、真/假、开/关等。).从一个神经网络(下一章讨论)来看,输出层只有一个神经元可以做到这一点,常见的激活函数有sigmoid
或logistic
。下面是二进制分类工作的例子。
-
垃圾邮件过滤器:它是垃圾邮件吗?是/否
-
交易欺诈预测:是欺诈吗?是/否
二元分类任务通常包括被认为是正常状态的类别 0 和被称为异常状态的类别 1。例如,“非垃圾邮件”将被视为正常状态,而“垃圾邮件”将被视为异常状态。某些算法,如逻辑回归和支持向量机(SVM),支持二进制分类,但不支持两个以上的类别。就其基本形式而言,SVM 不支持多分类[272]。它只是通过将多分类问题分解成多个二元分类问题的过程来实现的。
直观地说,多类分类器不是二元的。例如,将一个数字归类为前十个数字{0 到 9}之一。从神经网络的角度来看,这需要每类一个神经元。因此,这种类型的分类器通常需要多于一个神经元。多类分类器的另一个例子是光学对象分类(面部、植物等。).在神经元网络处理中,softmax
函数处理多类分类器。
多标签分类是指具有两个或两个以上类别标签的任务,其中每个数据点可以预测一个或多个类别标签。一个例子是其中具有多个对象的照片和可以预测多个已知对象的存在的相应模型,诸如汽车、大象、人等等。在二进制和多类情况下,处理单个类标签,而在多类情况下,有两个或多个类标签。
不平衡分类涉及每类中的实例数量而非平均分布的任务。典型地,不平衡分类任务是二元分类任务。例如,训练数据集中的许多数据点属于类 0,少数示例属于类 1。为了简化计算任务,有时使用诸如对多数类欠采样或对少数类过采样之类的专门技术来操纵训练数据集。类似地,也使用专门的建模算法。
数据驱动预测
大多数 ML 算法都有相同的总体特征:它们被输入数据并输出对查询的响应。在这个大数据时代,实时原始数据的检查和评估至关重要,尤其是在金融行业和网络安全领域。当一个金融机构希望预测股票价格时,他们可以查看价格预测的时间序列值。
如果数据的处理涉及图像分析,那么图像的内容和相应的排序被视为分类。通常,数据被认为是输入,模型的预测被认为是输出。
预测模型及其用法的例子多种多样。其中一个就是图像识别。如果我们看到一头大象,我们通过视觉刺激认出它是一头大象,因为我们通过观察它们或它们的照片了解了大象是什么。然而,如何给计算机编程以本能地识别大象并不是直观上显而易见的。在 ML 中,我们向计算机呈现许多图像,它从这些图像中学习大象的“样子”。同样,也可以教会计算机老虎长什么样。因此,在用图像作为输入数据的几次这样的训练之后,计算机学会了如何对大象和老虎进行分类。系统看到的各种形状、大小和姿势的大象和老虎的图像越多,识别和分类它们的效率就越高。
时间序列数据的预测是一个重要的预测应用。在不同时间点记录的一组数据点构成了时间序列数据。数据点是在相邻的时间段收集的;因此,考虑观察值之间存在相关性的可能性是合乎逻辑的。如果我们考虑涵盖两次美国选举的连续八年的美元记录值,我们可以找到同一时期的重要宏观经济变量的记录,如国内生产总值(GDP)、黄金价格或原油价格。由于美元的价格受其他指标和政治变化的影响,并且我们通过时间了解其价格行为,如果某个政党赢得总统选举,我们可能能够预测美元价格在给定年份的变化。
另一个重要的预测与医学或故障查找有关,它被称为诊断。例如,如果我们试图根据人们的胆固醇水平、血压、年龄、体重、吸烟习惯或锻炼方式来预测心脏骤停的发生,我们将无法肯定地预测心脏病发作。相反,考虑到这些因素,我们也许能够预测它发生的可能性有多大。这种类型的预测基于逻辑回归。
Note
逻辑回归,尽管听起来好像是一个回归算法,但它是一个分类算法。逻辑回归被认为是机器学习研究人员采用的统计回归模型,他们将其用作分类器。
以下是一些常见的预测模型。
-
线性回归
-
多变量回归
-
多项式回归
复杂性
问题的复杂性是指从算法、计算时间等角度对涉及资源使用的问题类别的研究。为了估计总的计算成本,需要对资源进行分析。这是通过运行解决问题所需的算法来完成的。
计算机运行一个算法的时间就是该算法在特定计算平台上的运行时间。根据经典计算的基本原理,通过验证数据库中的项目直到找到一个期望的项目,可以获得数据库搜索目标的解决方案。这个练习需要时间复杂度为 O ( n )的最坏情况场景。
算法的计算复杂度是算法的时间、规模和相关资源需求如何随着数据集或问题规模的增长而发展的量化表达。算法旨在应用于未知函数或一组数据,以确定函数的属性(如周期或最小值)、因数或分类数据。
函数的输入数量(即数据大小)可以是从一位数到数万亿或更多。有很多算法,我们有足够的时间去挑选和试验它们,直到我们找到完成这项工作的算法。一旦我们选择了一个我们认为服务于我们的目的或目标的算法,我们需要决定对以下问题的回答。随着输入数量的增加,算法的运行时间表现如何?这被称为算法对大小的敏感度。
随着算法问题规模的增长,它的运行时间也在增长。这被称为时间复杂度。以下是下一章要讨论的一些时间复杂性。
-
恒定时间复杂度
-
多项式时间复杂度
-
非多项式时间复杂度
第一章提到了计算复杂性,这将贯穿全书。当我们谈到量子机器学习的复杂性时,我们会深入讨论它。
混淆矩阵
现在我们已经探讨了分类的基本原理,接下来我们来看看真阳性(TP)假阳性(FP)真阴性(TN)假阴性 (FN)。当一个分类器说一个数据点是 X 时,它就是 X ,这就是所谓的真正。当分类器将一个数据点识别为 X ,但它实际上是一个 Y 时,就会出现假阳性。当一个数据点被归类为而不是 X ,并且它真的不是时,为真否定。
最重要的分类指标是准确度,这在本章前面讨论方差和偏差时已经讨论过了。精确度是有定义的,但是让我们在这里扩展一下这个定义。
数据科学家和工程师也有兴趣知道分类器如何避免错误警报。这是由分类器的精度定义的。
如果我们不希望错过任何一个 TPs,并且希望尽可能多地捕捉到 X s,那么衡量成功的标准就是所谓的召回。
直观表示 TPs、FPs、TNs 和 FNs 的标准方法称为混淆矩阵。例如,对于二进制分类,混淆矩阵是一个 2 × 2 的表格,如下所示。
| | 归类为**是** | 分类为**否** | | 真**是** | TPs 数量 | 联合国编号 | | 真**否** | FPs 数量 | TNs 数量 |其中,TP 为真正;FP 是假阳性;TN 是真阴性;FN 是假阴性。
例如,如果诊所中的患者被分类为正确诊断患有癌症,或错误诊断患有癌症,或患有癌症但未被诊断,或未患癌症但被正确诊断为未患疾病,则癌症诊断过程的混淆矩阵如下表所示。
f -score 或 f-measure 是精度和召回的调和平均值。使用 f 分数是因为虽然精确度和召回率是非常重要的度量,但是只处理其中一个并不能向我们呈现完整的场景。F-score 是总结这两个值的一种方式,并且提供了对分类器性能的更现实的测量。
监督学习
一个监督学习 ML 算法被呈现为输入数据样本或训练集 s 被标记为,并输出对特定问题的响应。在这种情况下,训练集包括期望的解决方案或标签,这允许它从数据中学习。这里的目标是从训练集中学习,以便可以对算法以前看不到的新数据进行有意义的预测。监督学习通常分为两种:回归和分类。
垃圾邮件过滤器用例是一个名为分类的监督学习任务的例子。该过滤器一直使用已知的垃圾邮件样本进行训练。它看到的训练数据越多,就越能更好地完成分类哪些邮件是垃圾邮件,哪些不是的任务。该算法会将电子邮件归类为垃圾邮件分类和“欺诈”或“非欺诈”表 2-1 列出了一些最常见的监督学习算法和相关的用例。
表 2-1
监督学习算法的例子
|监督学习方法
|
例子
|
算法
|
| --- | --- | --- |
| 回归 | 股价预测,房价预测 | 线性回归,岭,套索,多项式 |
| 分类 | 垃圾邮件:欺诈/非欺诈,癌症/非癌症 | 逻辑回归,SVM,KNN |
| 决策树 | 预测股票价格(回归),分类(信用卡欺诈) | 决策树,随机森林 |
类似地,如果我们使用威斯康星州乳腺癌数据集1【12】来训练诸如逻辑回归或 KNN 的 ML 模型,则可以基于特征的分类来预测患者是否患有癌症。
监督学习的主要目标之一是实现低偏差和低方差误差。
从数据到预测
从监督模型中的数据进行预测的途径包括四个基本步骤。
作为第一步,数据被清理、处理,并且选择模型族作为第一猜测。由于这是监督学习,所以需要对数据进行标注,并且知道数据特征和定义。例如,数据可以用线性加权函数来表示。通过拟合参数来训练模型。步骤如图 2-19(a-d)所示。
图 2-19d
数据驱动预测的第 4 步
图 2-19c
数据驱动预测的第 3 步
图 2-19b
数据驱动预测的步骤 2
图 2-19a
数据驱动预测的第一步
在图 2-19a 中,显示了具有未知关系的输入 x 和输出 y 的一维数据集。在图 2-19b 中,选择一个模型;例如,诸如回归的线性模型和用于分类的双曲正切函数。图 2-19c 显示了使用训练集拟合数据的训练模型,同时测试数据集在训练后验证模型。在图 2-19d 中,输入x’被馈入模型,得到输出y’。
在监督学习中,一个目标函数通常是通过先定义一个函数 up 来估计,比如 y = f ( x ),其中 x 是输入, y 是输出。
错误有三种主要类型。
-
方差误差
-
偏移误差
-
不可约误差
与方差或偏差误差不同,不可约误差,顾名思义,是不能减少或最小化的。它们通常是由未知的变量或参数或数据中无法消除的噪声引起的。
支持向量机(SVM)
SVM 是一种监督学习技术。支持向量机在 ML 中非常流行,是所有 ML 爱好者都应该知道的工具。支持向量机对于表现出复杂性的中小型数据集的分类特别有用。本节重点介绍 SVM 的核心功能。这些最大似然算法在数学上是稳健的,并且自 20 世纪 90 年代以来一直在研究。我推荐浏览 Aurélien Géron 的使用 Scikit-Learn 和 TensorFlow 进行机器学习:构建智能系统的概念、工具和技术,第二版(O'Reilly Media,2019) [15]。
SVM 是从具有多种特征的复杂高维数据集进行合理有效预测的一种简单方法。SVM 可以拯救更高维度的支持向量,并对它们进行分类。支持向量定义了所谓的超平面。可以利用不同的核来实现这一点,例如多项式或高斯 RBF。理解 SVM 的一个好方法是分析一些真实的数据。在本练习中,我们再次使用 Iris 数据集,并改编来自scikit-learn
[16]的库。
虹膜数据集的 SVM 示例
对鸢尾数据集的快速回顾提醒我们,公开可用的数据集由 150 朵鸢尾花的花瓣和萼片的长度和宽度的测量值组成。有三类不同的鸢尾花 50 个实例,每个都包括在数据集中:海滨鸢尾、杂色鸢尾和刚毛鸢尾[13]。您看到了支持向量分类 (SVC)的用法,这是 SVM 的一种典型分类。SVC 类允许添加几个多项式特征,而不需要添加它们。从计算成本的角度来看,这有助于避免增加特征数量的压力,因为我们没有添加任何特征。
图 2-20
带有虹膜数据集的 SVM(由 scikit-learn 文档提供[16])
图 2-20 (生成图形的代码可在 https://scikit-learn.org/stable/auto_examples/svm/plot_iris_svc.html
获得)显示萼片长度和萼片宽度,具有线性、多项式和高斯 RBF 核。如果我们目测图形,多项式核相对于线性核的灵活性是显而易见的。线性模型具有线性决策边界(相交超平面)。非线性核模型(多项式或高斯 RBF)具有更灵活的非线性决策边界,其形状取决于核的种类及其参数。
使用scikit-learn
创建 SVM 模型不可避免地涉及到指定一些超参数,比如C
(参见下面的代码片段)。低或高的C
会影响图形的边界定义。之前,我们讨论了对于某些数据集,多项式核优于线性核的一些优点,这是因为前者具有更高的自由度,从而提供了灵活性。通过poly
内核实现多项式特性很简单,如下面的代码片段所示。
models = (svm.SVC(kernel='linear', C=C),
svm.LinearSVC(C=C, max_iter=10000),
svm.SVC(kernel='rbf', gamma=0.7, C=C),
svm.SVC(kernel='poly', degree=3, gamma='auto', C=C))
models = (clf.fit(X, y) for clf in models)
多项式核可以与许多 ML 算法一起工作,并且不是特定于 SVM 的。然而,最好记住,低多项式次数的poly
内核在处理高复杂度的数据集时效率会降低。如果使用高多项式次数,则往往会以很高的计算成本创建许多要素(即,它会变得很慢)。注意,LinearSVC
比有kernel =
’linear
的SVC
快很多。
使用多项式核时要注意的一个问题是,如果模型过拟合,降低多项式次数可能会有所帮助。另一方面,如果结果是拟合不足,增加多项式次数可能是前进的方向。代码中的gamma
类似于正则化超参数。
高斯 RBF 核的 SVC 类用不同的C
和gamma.
值定义,如果gamma
增大,则使钟形部分变窄,更小的gamma
使其变宽,给出更平滑的判决边界。在这些情况下,gamma
作为一个正则化超参数。如果模型过拟合,应减小gamma
;如果是欠拟合,应增加gamma
。
其他类型的内核不太常用,比如用于文本或 DNA 序列分类的字符串内核。根据经验,首先尝试线性核来处理大型训练集或大型特征集。对于非常大的数据集,高斯 RBF 核也能很好地工作。
作为 SVM 的一个练习,查看可视化选项和分类可能是有用的。我们利用 Python 的seaborn
库,它构建在matplotlib
之上。seaborn
库提供了一个高级数据可视化接口来创建一个名为热图的矩阵表示,以二维形式表示数据。数据值在图表中用颜色表示。本节后面生成的热图(见图 2-21 )的目的是提供一个彩色的可视化信息摘要。SVM 分类练习代码可以从本书的网站下载,作为svmIris.ipynb
在 Jupyter 笔记本上运行,如清单 2-3(a–d)所示。
#import libraries
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
#Get the data and define col names
colnames=["sepal_length_in_cm", "sepal_width_in_cm","petal_length_in_cm","petal_width_in_cm", "class"]
#Read the dataset
dataset = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data", header = None, names= colnames )
#See the Data
dataset.head()
Listing 2-3aSVM Classification
of Iris Dataset: Importing Libraries and Observing Data
清单 2-3a 导入所需的库,包括seaborn
,下载 Iris 数据,并以下面的表格格式打开数据头定义。
ML 算法对数字比对文本更有效。这意味着,如果数据包含分类数据,我们必须将其编码为数字,然后才能用它们来评估模型。两种流行的技术是整数编码和一键编码。一种更新的技术,叫做学习嵌入 g,在其他两种方法之间提供了一个有用的中间地带。
-
整数编码:每个唯一标签映射到一个整数。
-
一键编码:每个标签映射到一个二进制向量。
-
学习嵌入:学习类别的分布式表示。
查看数据格式,将class
改为数字而不是花的名称可能会有用。清单 2-3b 中的代码片段改变了分类格式。
#Use pandas to encode the categorized columns
dataset = dataset.replace({"class": {"Iris-setosa":1,"Iris-versicolor":2, "Iris-virginica":3}})
#Read the new dataset
dataset.head()
Listing 2-3bSVM Classification of Iris Dataset: Change the Class to Numbers
由于清单 2-3b 中的代码,刚毛鸢尾被更改为class
1,杂色鸢尾被更改为class
2,海滨鸢尾被更改为class
3,如以下示例输出所示。
接下来,让我们使用清单 2-3c 中的代码用 seaborn 绘制热图。
plt.figure(1)
sns.heatmap(dataset.corr(), cmap="YlGnBu")
plt.title('Correlation between iris Classes')
Listing 2-3cSVM Classification of Iris Dataset: Generate Heatmap
列表 2-3c 生成如图 2-21 所示的热图,该图显示了花的种类与其花瓣和萼片的长度和宽度之间的相关性。
图 2-21
带有虹膜数据集的 SVM:热图
在最后一步中,在清单 2-3d 中,数据被分割,SVM 分类器被创建,精确度被计算。
# Split Data
X = dataset.iloc[:,:-1]
y = dataset.iloc[:, -1].values
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 0)
#Create the SVM classifier model
from sklearn.svm import SVC
classifier = SVC(kernel = 'linear', random_state = 0)
#Fit the model for the data
classifier.fit(X_train, y_train)
#Make the prediction
y_pred = classifier.predict(X_test)
#Accuracy of Model
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
print(cm)
from sklearn.model_selection import cross_val_score
accuracies = cross_val_score(estimator = classifier, X = X_train, y = y_train, cv = 10)
print("Accuracy: {:.2f} %".format(accuracies.mean()*100))
print("Standard Deviation: {:.2f} %".format(accuracies.std()*100))
Listing 2-3dSVM Classification of Iris Dataset: SVM Classifier and Accuracy code
以下输出显示 98%的准确性和 3.64%的标准偏差。也说明只有一个分类错误的数据。
k-最近邻
k 最近邻 (KNN)是最容易在 ML 中实现的技术之一。KNN 处理结构化的、有标签的数据,并根据它们之间的相似性将它们分组。书籍的普及就是一个例子。在图 2-22 中,小圆圈代表犯罪小说,而方块代表科幻小说。不知何故,绘图似乎是基于距离。如果出版了流派未知(用三角形表示)的新书,算法会在训练数据中搜索与新例最近的邻居 S ,然后对其进行分类。KNN 不会生成分隔训练数据点的线。
图 2-22
k 近邻
KNN 的优点是易于实现,并且能够很好地处理行为良好的结构化数据。KNN 能够正确实现任意复杂的分割线,也称为超平面。KNN 的一个缺点是数据点中的单个错误可能会导致较差的分类结果。如果一个新的未知点紧挨着另一个类的离群点,则它被分类到错误的类中。这是过度拟合的另一个例子,其中对随机误差进行了拟合。
误差和损失函数
在本章早些时候,我们在方程 2.5 和 2.6 中看到了方差、偏差及其混合关系产生的各种误差。损失函数是计算误差的计算函数。预测误差与用于计算它们的损失函数直接相关(即,不同的损失函数可以为相同的预测计算不同的误差)。
回归的误差和损失函数
为了理解某些损失函数可能如何工作,让我们考虑六个学生在机器学习考试中的成绩。表 2-2a 列出了学生及其成绩。
表 2-2a
等级
|学生#
|
级别
|
| --- | --- |
| one | fifty-six |
| Two | seventy-eight |
| three | eighty-nine |
| four | Sixty-three |
| five | Seventy-three |
| six | Ninety-one |
假设选择用来预测成绩的模型非常简单。它始终预测 75 为等级。现实中,没有一个成绩是 75。实际成绩与预测成绩之差为残差或误差,如表 2-2b 所示。
表 2-2b
等级误差/残差
|学生#
|
级别
|
预报
|
误差或残差
|
| --- | --- | --- | --- |
| one | fifty-six | Seventy-five | 56 – 75 = –19 |
| Two | seventy-eight | Seventy-five | 78 – 75 = 3 |
| three | eighty-nine | Seventy-five | 89 – 75 = 14 |
| four | Sixty-three | Seventy-five | 63 – 75 = –12 |
| five | Seventy-three | Seventy-five | 73 – 75 = –2 |
| six | Eighty-seven | Seventy-five | 91 – 75 = 16 |
表 2-2b 显示误差之和为
这意味着误差可以相互抵消,给人的印象是方差和偏差“很好”,而隐藏在明显的地方。然而,假设我们将这些误差平方,以去除负号并消除误差的抵消,从而更容易检查隐藏在我们“简单”模型中的陷阱。平方误差提供了放大大偏差或“异常值”的额外优势,使它们更容易检测。这导致了误差平方和 (SSE)。
SSE 也被称为残差平方和 (RSS)或残差平方和 (SSR)。在本例中,我们正在处理一个玩具数据集,但实际上,一般数据都附有标签和权重。一般来说,SSE 由下面表达式中的 E 给出。
(2.15)
其中 t 数据集是目标(或标签)。 y 是模型的输出。( n )是标记样本范围内各个数据的指数。因此t(I)是第 i 个训练行向量的目标的索引。
下面是从数学上定义 SSE 的另一种方式。
其中 x 数据集是实际值,是预测值。( n )是标记个体数据的指标。
are the predicted values. The (
SSE 是 ML 中最简单、通用的错误度量之一。
还有均方误差 (MSE),定义如下。
MSE 速度快,计算梯度。但是由于它直接依赖于数据集计数,它对数据集中的偏差可能有些敏感,并且显示与数据有较大差异的预测可能会受到严重惩罚。
回归的最后一个重要误差是平均绝对误差,定义为
MAE 是稳健的,一般不会受到偏差的很大影响。当数据被认为是损坏的时候使用它。选择任何回归误差函数都没有一成不变的规则。在三种常用的方法中,为了获得最佳结果,通常推荐使用试错法。
分类的误差和损失函数
以下是分类任务中常用的一些预测误差损失函数。
二元类熵衡量实际值和预测值之间概率分布的散度,常用于二元分类。这在数学上由下式给出
在分类交叉熵中,只预测了众多标签中的一个。
以下是其他一些损失函数。
-
负对数似然
-
边缘分类器
-
软边界分类器
-
稀疏分类交叉熵
无监督学习
在无监督学习中,目标是在未标记的数据集中找到自然结构。该算法仅被输入数据,并且被期望自己找到有意义的结构,而没有外部监督或输入。这种类型的 ML 的一个例子是在图书馆中不断增长的文本集合中寻找聚类。这可以根据书籍主题随时间的变化、过时的讨论和主题以及作者身份来完成,这些内容对于现代读者而言可能已经变得过于敏感,而不是几个世纪前最初写作时的目标读者。
在无监督学习中,没有训练集和测试集。所有数据点都是训练数据点。聚类是从这些数据点构建的。
解决可视化的算法也是无监督学习的例子。可以向算法提供复杂和非结构化的数据,以获得表示的输出。
聚类是在数据中寻找自然分组的过程。人类的大脑倾向于自然地将我们遇到的数据聚集在一起。我们在头脑中对它们进行分类,并按照一定的类别对它们进行组织,因为我们的大脑通过为它们形成明确定义的组来简化分类。图 2-23a 显示了茶、咖啡、牛奶和果汁的分类方案。这有助于您理解数据,并找到与您所学内容相似的实例。
图 2-23a
聚类示例
无监督学习的一个重要应用是在网络安全和异常检测中,例如,信用卡欺诈,其中已经显示正常交易的系统试图识别任何异常交易模式。图 2-3b 展示了聚类如何用于欺诈或异常检测。
图 2-23b
聚类异常检测
现代生活中另一个无监督学习的伟大例子是谷歌新闻,其中一种算法自动将新闻故事分组到特定的部分。表 2-3 列出了一些最常见的无监督学习算法和相关的示例用例。
表 2-3
无监督学习算法的例子
|无监督学习方法
|
例子
|
算法
|
| --- | --- | --- |
| 使聚集 | 群集病毒数据,会议中的访问者群体 | 层次聚类,k-均值聚类 |
| 降维 | 数据维数的减少 | 主成分分析 |
k 均值聚类
任何聚类算法的主要目标都是将数据点分配给代表它们在一个 N 维空间中的相似性的聚类。 k-means 聚类是一种无监督学习算法。无监督学习是没有标签或目标的学习。k 均值聚类是一种产生数据聚类的算法。聚类包括为所有相似的数据点分配聚类名称。通常,集群被命名为 1、2、3 等等。
k-means 聚类将几个质心作为输入,其中每个质心定义一个聚类。当算法开始时,质心被放置在数据点向量空间中的随机位置。k-means 聚类有一个称为分配、的阶段和另一个称为最小化的阶段。该算法在这两个阶段循环几次。在分配阶段,该算法使用欧几里德距离计算将每个数据点放置在离其最近的质心旁边。在最小化阶段,通过向使质心更靠近数据点的方向移动质心,使质心和指定给它们的所有数据点之间的距离之和最小化。这被称为一个周期。一个周期的结束产生一个就绪超平面。
在一个循环结束后,下一个循环通过将数据点与其质心分离来开始。从位置上看,质心保持不变。有了这些,一个新的关联阶段就开始了,它可能会决定分配不同于前一个周期的任务。当遇到新的数据点时,它被分配给最近的质心,并继承该质心的名称作为标签。k-means 中的聚类是质心周围的区域。
在理论设置中,聚类中不需要标签。但是如果没有标签将它们联系起来,评估指标就变得无关紧要了。如果没有要定义的元素,度量标准将定义什么?没有标签,我们无法计算真阳性、假阳性、真阴性和假阴性。[24]中给出了聚类中分类评估指标用法的详细说明,称为聚类的外部评估。
然而,有时我们根本无法获得标签,被迫在没有标签的情况下工作。在这种情况下,我们可以使用集群的内部评估。在几种可用的评估指标中,Dunn [25]评估指标是最受欢迎的。邓恩系数的重点是测量一个 N 维空间中的团簇密度。通过计算每个聚类的邓恩系数来评估每个聚类的质量。
强化学习
在这种情况下,组成学习系统的算法被称为代理。代理人观察、选择并执行特定的行动以换取奖励或惩罚。强化学习应用的一个例子是如何教会机器人行走或执行任务。他们因做正确的工作而得到“奖励”,因做错工作而受到“惩罚”。另一个例子是有时人们如何学习玩电子游戏。他们尝试新事物,如点击地点、开门、获得弹药或金钱,并最终学会如何玩。类似地,强化学习算法中的代理在继续从基于数据的观察和自动学习中学习时尝试新事物。强化学习的一个非常受欢迎的领域是神经网络,这将在第三章中探讨。
有一些非常吸引人的媒体产品很好地展示了强化学习,包括在 https://openai.com/blog/emergent-tool-use/
。
摘要
机器学习(ML)已经成为人工智能和认知科学研究的一个子领域,自 2014 年以来,已经被企业以惊人的速度采用。第二章讲述了进入由量子力学推动的机器学习世界所需的一些基础知识。下一章在移动到量子信息处理概念之前包括神经网络的本质。
Footnotes 1
这指的是威斯康星大学医院的内科医生 William H. Wolberg 博士创建的威斯康星乳腺癌数据库中的一个公开可用的数据集。该数据集包含 569 个恶性和良性肿瘤细胞样本。沃尔伯格博士使用了从乳腺实性肿块患者身上采集的液体样本,以及一种易于使用的图形计算机程序 Xcyt,该程序可以基于数字扫描进行细胞学特征分析。该程序使用曲线拟合算法来计算样本中每个细胞的十个特征,然后计算图像每个特征的平均值、极值和标准误差。数据集可在 archive 获得。ics。uci。edu/ ml/数据集/乳腺癌+乳腺癌+Wi sconsin+(诊断)
。
三、神经网络
第二章介绍了机器学习(ML ),这是人工智能研究的一个子领域。深度学习(DL)是 ML 的一个子集。它试图解决人工智能领域的具体问题,如推理、规划和知识表示。
深度学习以人工神经网络(ann)为中心,这些网络功能强大,可扩展,用途广泛。谷歌图像使用人工神经网络来大规模分类数十亿张图像。从数学的角度来看,神经网络 (NN)可以看作是一个非线性回归模型,对模型函数有特定的选择。线性模型被输入到非线性函数中,然后表达式被多次嵌套。这些模型来源于生物神经网络[18]。它们代表的图形让人想起由突触连接的神经元。
Note
本章从应用的角度看经典人工神经网络的基础。它还着眼于深度学习技术,如学习、方差、偏差、神经网络,以及通过使用公共可用数据类型的一些动手练习来接触它。代码可以从该书的网站上下载。神经网络本身是一个庞大的领域,不可能在一章中包括该主题的所有方面。我们在阅读这本书时会重温这些概念,并看看它们如何在数据驱动的预测中与量子理论相适应。
人工神经网络的灵感来自于将人脑的逻辑功能映射到计算系统以创造智能机器的愿望。马文·明斯基是人工智能的创始人之一。他在 1954 年提交给普林斯顿大学的博士论文题目是“神经网络和大脑模型问题”1951 年,他建立了一个空军科学研究办公室资助的机器,见证了 SNARC(随机神经模拟强化计算器)的实现。当 A. C. Clarke 的传奇科幻小说《2001:太空漫游》被拍成电影时,他是导演斯坦利·库布里克的顾问。
在分类过程中,算法上只进行一次正向传递。正向传递只是输入通过神经网络时发生的计算的总和。前馈的逆过程被称为反向传播。
建立一个神经网络需要一个结构化的方法,并由以下整体组件组成。
-
关于网络层数的决定
-
输入的大小(通常与输入层中神经元的数量相同)
-
隐藏层中的神经元数量(如果有)
-
输出层中的神经元数量
-
权重的初始值
-
偏差的初始值
感知器
从数学上讲,神经元的学习过程包括通过反向传播在训练过程中修改权重和偏差。其思想是在分类时测量网络误差,然后通过修改权重来最小化该误差。弗兰克·罗森布拉特于 1962 年发明的感知机是神经网络的组成部分。感知器由一个二进制阈值神经元组成,定义如下。
(3.1)
(3.2)
其中,xI为输入, w i 为权重, b 为偏差, z 为 logit 或加权和。输入和输出要么是实数,要么是二进制数。等式 3.2 定义了用非线性得出的决策。可以将等式 3.1 中的偏差吸收为权重,使得可以仅使用更新权重的规则。如图 3-1 所示。
图 3-1
偏置吸收
为了实现这一点,输入x?? 0 被添加到等式 3.1 中,值为 1,偏差作为其权重。
用b=w0x0
在前面的等式中, b 可以是 x 0 而 w 0 = 1 或者 b 可以是 w 0 而 x 0 = 1。
输入永远不会改变,我们要做的是改变偏差。因此,输入被视为权重。这个过程被称为偏置吸收。
下面描述感知器训练规则的基础。
-
选择一个训练场景。
-
如果预测输出与输出标签匹配,则无需采取任何措施。
-
如果感知器在应该预测 1 的时候预测了 0,则输入向量被添加到权重向量。
-
如果感知器在应该预测 0 的时候预测了 1,则从权重向量中减去输入向量。
通常,一个神经网络由 N 个输入组成,比如说IN和 N 权值如图 3-2 所示。
图 3-2
简单神经网络
在图 3-2 所示的简单 NN 中,输入为二进制(开/关)。在该模型中,输入和权重相加,通常为阶跃函数的阈值函数给出输出。以下是这种模式的局限性。
-
输入和输出是二进制的
-
没有自动训练重量的方法;因此,权重的设置是手动完成的
与图 3-2 所示的简单神经网络相比,图 3-3 所示的感知器模型更加通用,因为输入可以是数字,而不必是二进制的。感知器模型是前馈神经网络的最简单形式。
图 3-3
简单感知器
图 3-3 所示的广义感知器模型有输入和权重,然后是方程 3.1 和 3.2 描述的偏置吸收。如果我们重温方程 3.1 ,感知器的计算涉及由
(3.3)给出的模型函数
其中 w T 是权重乘以输入向量 x 的矩阵表示。 ϕ 是依赖于输入和权重的函数。 f 与模型功能 z 相同。这里,输入和输出要么是实数,要么是二进制数。非线性函数 ϕ 被称为激活函数(稍后讨论)。输入馈入后,求和在过程开始时完成。
在过程的末尾,应用阶跃函数。以下是常见的阶跃函数。
,
其中 sgn 是符号函数。当一层中的神经元连接到它之前层中的所有其他神经元(即输入神经元)时,该层是完全连接的。
感知器的一个简单例子是如果一个人要去看板球比赛。去或不去的决定取决于几个因素,或者在这种情况下,输入。
-
天气:如果下雨,板球比赛将不会举行
-
由于没有汽车,场馆靠近公共交通
-
如果有朋友也可以加入提供优质服务的公司
-
如果喜爱的明星玩家正在参与游戏
问题的感知器如图 3-4 所示。
图 3-4
板球比赛的简单感知器示例
通过给每个输入分配权重来计算输出。根据预先确定的决策标准,输出是二进制的(是/否),如果最终得分高于 60,则为“是”,否则为“否”。权重会根据“如果朋友不能加入怎么办”等问题的答案影响决策或者“如果下雨,但只是一个小时呢?”或者“如果明星球员不上场呢?”。再次注意,这里所有的权重操作都是手动完成的。
激活功能
神经网络中的激活函数定义了如何将输入的加权和转换成网络层中一个或多个节点的输出。为了理解激活功能,让我们假设我们有一组狗的图像和另一组不包含狗的图像。假设每个神经元从图像中单个像素的值接收输入。当计算机处理这些图像时,我们希望我们的神经元调整其权重和偏差,使错误识别的图像越来越少。这种方法看起来很直观,但它要求权重或偏差有很小的变化,从而只引起输出有很小的变化。因为,如果我们在输出上有一个大的跳跃,我们就失去了学习曲线中的“平滑度”,并且不能渐进地学习。用人类对儿童学习过程的类比来说,学习是一小步一小步地完成的(或者说,一点一点地)。不幸的是,感知器并没有表现出这种“小步学习”的行为。感知器要么是 0,要么是 1,这是一个巨大的跳跃,对学习没有帮助,如图 3-5 所示。
图 3-5
感知器输出
为了纠正这种渐进式学习的缺乏,需要“某种东西”来平滑图 3-5 中 0 和 1 之间的陡峭步骤。基本上,我们需要一个从 0 到 1 连续变化的函数。从数学上来说,我们需要的是一个连续函数,它允许我们计算导数。在数学中,导数是函数在连续函数的给定点上如何变化。对于输入由实数给出的函数,导数是图上一点切线的斜率。
在图 3-4 的板球比赛的例子中,我们在神经元输出之后的激活函数中定义了一个大于 60 的阈值。这个激活函数用于在我们的板球比赛示例中注入“平滑度”。
没有激活函数,感知器的输出将是线性的,并且线性函数趋于简单。他们很难解决复杂的问题。神经网络(NNs)被视为通用函数逼近器,因为它们可以计算和学习几乎任何函数。因此,需要非线性,以便神经网络可以计算复杂函数。因此,需要激活功能。
以下是一些最常见的激活功能。
图 3-6
线性激活函数
-
线性:感知器的线性输出中,函数的导数为零,因为函数是线性的。线性激活函数常用于线性回归。因此,没有激活函数的神经网络通常被视为线性回归模型。图 3-6 描绘了一个线性激活函数。
-
Sigmoid: The sigmoid function is one of the most widely used nonlinear activation functions that transform the values between the range 0 and 1. Mathematically, the Sigmoid function is continuous, and a typical sigmoid function, represented in Figure 3-7, is given by
对于(∞、∞)之间的输入变化,sigmoid 会在范围(0,1)内产生较小的输出变化。
图 3-7
ReLU、tanh 和 sigmoid 函数(来源[273])
sigmoid 函数始终具有明确定义的非零导数;因此,可以使用梯度下降。从历史上看,乙状结肠函数非常受欢迎。最近,ReLU 函数越来越受欢迎。
-
Tanh: Tanh (see Figure 3-7) is another popular activation function mathematically defined as
Tanh 和乙状结肠密切相关,tanh 被认为是“拉伸”的乙状结肠。像 sigmoid 一样,tanh 是 S 形的、连续的、可微分的。Tanh 围绕零对称,范围从–1 到+1,而 sigmoid 范围从 0 到+1。
-
ReLU: A rectified linear unit is another nonlinear activation function that has gained popularity in deep learning. The main advantage of using the ReLU function over other activation functions is that it does not activate all the neurons simultaneously. ReLU (see Figure 3-7) is mathematically defined as follows.
ReLU 是一个简单的函数,因为它有助于解决使用 sigmoid 观察到的一些优化问题而变得流行起来。该函数对于负值为零,对于正值线性增长,如图 3-7 所示。ReLU 的实现也非常简单,而 sigmoid 的实现要复杂得多。
有关其他激活功能的更多信息,请阅读古德菲勒等人在www.deeplearningbook.org
【274】发表的深度学习。
隐藏层
当我们讨论 SVM 特征和核的类型时,您看到了多项式核提供了更多的灵活性,因为与线性核相比,多项式核的决策边界是曲线。类似地,在神经网络中,通常需要灵活的决策边界。一个隐藏层是实现这一点的一种方式。
图 3-8
具有单个隐藏层的 NN(使用 TensorFlow 操场创建,参考文献[27])
图 3-8 中标记的红色区域显示了用 tensor flow Playground【27】创建的前馈网络中的一个单隐层。多个隐藏层允许更复杂的决策边界。尽管取决于要求,在一个神经网络中可以有几个隐藏层;通常,一个隐层就足以解决大多数非线性问题。最近的研究表明,任何函数都可以用一个具有一个隐层的足够大的神经网络来表示(Lin,Jegelka,2018)[19];然而,训练这个网络可能是一个挑战。随着整个行业对功能集的要求和需求的增长,考虑多个隐藏层已经成为一种常见的做法。
反向传播
反向传播是前馈的逆过程。一个简单的逻辑回归网络,严格来说,不需要任何反向传播。然而,随着层数的增加,这些计算的数量也会增加。这些层不一定会增加计算的复杂性,但会增加计算量。
NN 的经验法则之一是误差的反向传播是梯度下降。梯度下降是前馈网络最常见的训练算法之一,数学上这就是反向传播,定义为
(3.5)
其中,当前权重是更新后的权重,
是朝着最陡梯度方向向下的前一步的权重, η 是学习率, E 是成本函数, C 是以微分形式的 E 的数学等价物,对wij求导以获得梯度。
实验操作:带 TensorFlow 操场的 NN
TensorFlow [20]是 Google 发明的,通过利用张量在机器学习中高效地使用图形模型,并迅速成为非常受欢迎的 ML 库。TensorFlow 是谷歌为快速机器学习任务制作的免费开源软件库。它可以用于一系列任务,但侧重于深度神经网络的训练和推理。TensorFlow 是一个基于数据流和可微分编程的符号数学库。TensorFlow 的文档可在 www.tensorflow.org
获得。由于其利用图形属性的特性,许多 TensorFlow 实现在 GPU(图形处理单元)上运行比在 CPU 上运行更高效。Google 推出了 TPUs(张量处理单元)来优化 TensorFlow 的代码性能。在写这本书的时候,TensorFlow 的版本是 2.x。
Keras 是另一个流行的 ML 工具。Keras 是一个高级 API,它允许我们构建、评估、训练和执行所有类型的神经网络。Keras 的原始版本可以在 https://github.com/keras-team/keras
获得。Keras 的多个其他实现已经发布。三个最受欢迎的开源深度学习库是 TensorFlow、微软认知工具包(CNTK)和 Theano。在本书中,我们使用与 TensorFlow 捆绑在一起的 Keras 实现。
为了体验神经网络及其工作方式,在我们开始详细编码之前,有一个资源可以让我们体验神经网络的性能和架构,并使其可视化。它被称为 TensorFlow 游乐场[27]。
以下步骤模拟神经网络。
第一步:将浏览器指向 http://playground.tensorflow.org
。如图 3-9 所示,这应该会打开我们用来玩一些概念的游戏的 GUI。这个神经网络模拟器帮助用户习惯各种神经网络算法的概念。
图 3-9
tensorflow 游乐场 GUI
对于接下来的步骤,请参考图 3-10 。相应的步骤用深蓝色数字标记。
第二步:选择数据。
第三步:选择特征。
第四步:设计神经网络。
第五步:调整参数。
第六步:运行。
第七步:检查结果。
图 3-10
TensorFlow 游乐场配置
隐藏图层:选择无隐藏图层。这将改变顶部隐藏层标题旁边的 2 为 0,并相应地改变 NN,如图 3-11 所示。
图 3-11
没有隐藏层的 TensorFlow 游乐场配置
通过消除隐藏层来观察输出的变化。输出中的域边界变得线性地更加明确,复杂性降低。
线性回归:
第一步:在右上角点击问题类型下拉菜单,选择回归。
第二步:在左下方选择数据作为数据集。
第三步:在顶部点击下拉菜单,选择学习率的最低设置。学习率是用于梯度下降的“步长”。
第四步 : 激活是添加到输出的功能。选项有线性、Sigmoid、Tanh 和 ReLU。选择直线。
第五步 : 正则化率指的是正则化,减少过拟合。该选项可以用 0、L1 和 L2 之间的值进行试验,以估计如果有任何过度拟合需要多少正则化。
第六步:点击运行/开始/播放按钮。
第七步:观察输出曲线。它似乎在慢慢收敛。
延迟的原因与学习率的值有关。这个模型似乎学得太慢了。目标是使用尽可能少的时期尽可能快地达到收敛。输出中提到的损耗就是误差。在这种情况下,它是均方根误差(RMSE)。
步骤 7 :点击学习率下拉菜单,增加学习率,再次点击运行。算法运行速度有变化吗?
步骤 8 :再次点击学习率下拉菜单,增加学习率到高值,再次点击运行。输出测试损耗显示为 NaN 或而非数字。学习率的大值会导致过冲。
为了找到最佳学习率,我们需要确定学习率的值,该值使用最少的时期使我们最接近零。
分类 :
第一步:模拟分类,选择以下参数。
-
在问题类型下拉菜单中选择分类。
-
在激活下拉菜单中选择 Tanh
-
在学习率下拉菜单中选择 0.01 。
步骤 2 :选择双斑点数据集。
步骤 3 :分离数据集的输出可能如下图所示。
步骤 4 :零损耗可能无法实现,尤其是在模型中引入一些噪声的情况下
第 5 步:和之前的线性回归实验室一样,挑战在于调整学习率以在尽可能少的时期内达到最小损失。
鼓励读者在 TensorFlow 游乐场玩一玩,花一些时间更改和调整隐藏图层、回归和分类的参数,同时在左侧添加新功能。随着顶部隐藏图层的数量发生变化,该工具会添加更多的隐藏图层。同样,单击“特征”下的方框会向 NN 模型添加新特征。
更改数据下的数据集类型,如棘手的螺旋数据集,以熟悉各种 NN 模型随参数变化的行为。
接下来,让我们进入神经网络架构的世界。
神经网络体系结构
我们已经了解了神经网络的基本原理、灵活性和可扩展性,以及感知器是如何构建神经网络的。从体系结构的角度来看,构建神经网络有几种选择。下面是一些现在使用的比较常见的方法。
-
卷积神经网络(CNN)
-
前馈神经网络
-
循环神经网络(RNN)
卷积神经网络(CNN)
1981 年诺贝尔生理学和医学奖授予了大卫·H·哈贝尔和托尔斯滕·魏塞尔,以表彰他们在 1968 年发表的论文“猴子纹状皮层的感受野和功能结构”[20]。他们研究了动物的视觉皮层,发现视野中的小区域的活动与大脑中一个小的、明确的区域的活动相关联。他们表明,识别负责部分视野的神经元是可能的。这导致了感受野的发现。
通常,在图像分析中,使用的技术之一是展平图像,其中各层被组合或堆叠在彼此之上。前面讨论的逻辑回归技术允许我们将图像向量输入到一个完成所有处理工作的单个神经元中。这两种技术(展平和逻辑回归)与感受野的概念相结合,为我们提供了如何构建卷积神经网络(CNN)的指南。为了在 CNN 中有效使用,逻辑回归部分使用不同的激活函数,但结构保持不变。
展平允许将图像合并到一个图层中。这使得我们可以在一个层中拥有所有可见的信息。这是构建神经网络的重要部分,因为全连接层的输入由一维数组组成。展平的概念如图 3-12 所示。
图 3-12
扁平化(medium.com 提供[21])
卷积层获取图像,并对整个图像进行逻辑回归。因此,第一个输入由展平向量的分量组成,第二个输入由接下来的分量组成,依此类推。该过程如图 3-13 所示。
图 3-13
卷积神经网络
CNN 有多层。CNN 是专门为处理图像而设计的。卷积层神经元扫描图像的特定区域,这是它们的视野 (FOV),并拾取图像中的图案,如眼睛、耳朵、鼻子、车轮等等。例如,可以让 CNN 处理一个大小为 10 的图像,其所有三层都有一个 3 × 3 的感受野。假设第一层具有随机分配偏差和权重的特性,则它会获取 10X10 的图像,并生成大小为 8 × 8 的图像。然后将这个大小赋予第二个 CNN 层。第二层可以有自己的感受野,具有随机初始化的偏差和权重,但对于这个例子,让我们假设它也是 3 × 3。这产生 6 × 6 的输出,然后传递到具有第三局部感受野的第三层。第三层 CNN 产生一个 4 × 4 的图像。然后,该图像被展平为 16 维向量,并被馈送到具有一个输出神经元并使用非线性逻辑函数的标准全连接层。逻辑函数给出 0 和 1 之间的输出,并比较输出和图像标签。然后,它计算误差,反向传播误差,并对数据集中经过整个网络训练的每幅图像重复这一过程。
训练 CNN 包括训练局部感受野以及全连接层的权重和偏差。逻辑回归和局部感受野之间的结构差异在于前者使用逻辑函数。但是,在后者中,可以使用任何激活功能。广泛使用的激活功能之一是整流线性单元或 ReLU。输入 x 的 ReLU 由 x 和 0 之间的最大值给出(即,如果输入为负,则返回 0,否则返回原始输入)。CNN 广泛应用于计算机视觉领域。
前馈神经网络
如前所述,单层神经网络可以解决简单的线性问题,但难以解决复杂性。为了解决更复杂的问题,引入了非线性。前馈神经网络 (FFNN)是一种实现解决复杂性所需的非线性的方法。它也被称为多层感知器 (MLP)和深度前馈神经网络 (DFNN)。
图 3-11 所示的前馈神经网络具有以下形式
(3.6)
其中,1, ϕ 2 等为非线性激活函数。 w i 是定义为权重矩阵的参数。模型函数由级联的线性模型和函数形成。这种连接可以重复几次。这是神经网络威力的一个例子:它们利用了线性代数的数据处理能力与非线性动力学的灵活性的结合。
*
图 3-14
单隐层简单前馈神经网络
图 3-14 显示了一个具有两个隐藏层的前馈神经网络。前馈神经网络是通过连接多层感知器构成的,使得每层的每个单元都连接到下一层的单元。第一层由输入xI组成,下一层是由 h i 单元组成的隐藏层,最后一层有输出 y i 。有一个激活函数来更新每个神经元,每一层都在前一层之后更新,从而形成一个前馈神经网络。以下来自方程 3.6 ,图 3-11 的单隐层前馈神经网络模型。
前馈 NN 可以与许多可能的激活函数 ( ϕ )组合,例如 tanh 、 sigmoid 和 ReLU 。关于激活函数的详细讨论可以在参考文献[15]中找到,我们将在接下来的章节中根据需要对其进行扩展。
以下是前馈神经网络的典型特征。
-
它由多层组成。
-
每一层都有几个神经元。
-
每个神经元都与前一层的神经元相连。
-
信息只通过一种方式流动;因此前馈。
-
它由输入、输出、和隐藏层组成。如果需要,可以有多个隐藏层。
以下是设计 FFNN 时一些基本的尺寸指南。
-
输入层
-
大小等于输入维度的数量。
-
它可能需要一个额外的额外神经元作为偏置项。
-
对于许多稀疏维,通常考虑宽而深的神经网络(具有许多层)。
-
-
隐藏层
-
隐藏层的大小和数量取决于训练样本、输入特征、输出和问题的复杂性。
-
深度学习使用多个隐藏层。
-
-
输出层
-
对于回归,只需要单个神经元。
-
对于二进制分类,只有一个神经元作为输出是二进制的(0/1,真/假…)。
-
对于多类分类,softmax 图层在其他图层中使用。
-
大小建议是每个类标签一个节点。
-
实验操作:使用 MNIST 数据集进行影像分析
本实验练习着眼于图像分类。我们创建并训练一个神经网络模型,在训练之后,该模型可以以很高的准确度从手写图像中预测数字。您应该对神经网络如何工作以及 TensorFlow 如何与 Keras 一起工作有一个基本的了解。
本实验是使用 MNIST 数据集完成的。MNIST 是由高中生和美国人口普查局员工手写的 7 万个数字小图像组成的集合。每个图像都标有它所代表的数字。这个集合已经被研究了很多,所以它经常被称为机器学习的“你好,世界”。每当人们开发一种新的分类算法时,他们都很好奇它在 MNIST 上的表现如何,任何学习机器学习的人迟早都会处理这个数据集。
图 3-15 描述了该任务:创建并训练一个模型,该模型将一个手写数字的图像作为输入,并预测该数字的类别;也就是说,它预测输入图像的数字或类别。
图 3-15
图像分类任务
打开名为TF_Keras_imageClassifiaction.ipynb
的 Jupyter 笔记本文件,可从该书的网站下载。
第一步:导入 TensorFlow,验证版本。
import tensorflow as tf
tf.logging.set_verbosity(tf.logging.ERROR)
print('Using TensorFlow version', tf.__version__)
第二步:导入 MNIST 数据。
mnist=tf.keras.datasets.mnist
(x_train, y_train),(x_test, y_test)= mnist.load_data()
第三步:塑造数据。
print('x_train:', x_train.shape)
print('y_train:', y_train.shape)
print('x_test:', x_test.shape)
print('y_test:', y_test.shape)
下面显示了输出。
第四步:看一张图片。
from matplotlib import pyplot as plt
%matplotlib inline
plt.imshow(x_train[0], cmap='binary')
plt.show()
下面显示了输出。
第五步:显示标签。
y_train[0]
步骤 6 :在这一步中,我们将利用热编码。每个标签被转换成具有 10 个元素的列表,并且对应类的索引元素被设置为 1,其余的都被设置为 0,例如
from tensorflow.keras.utils import to_categorical
y_train_encoded = to_categorical(y_train)
y_test_encoded = to_categorical(y_test)
第七步:验证形状。
print('y_train_encoded:', y_train_encoded.shape)
print('y_test_encoded:', y_test_encoded.shape)
下面显示了输出。
步骤 8 :显示编码后的标签。
y_train_encoded[1]
下面显示了输出。
步骤 9 :参见图 3-16 ,显示了神经网络架构。正如在关于感知器和偏差吸收的讨论中所解释的那样,该图表示了以下等式。
其中 w 1、 w 2、 w 3 为权重。 b 是截距项,也叫偏差。
图 3-16
神经网络架构。测试意味着转置。这给出了我们想要的结果的点积
第十步:建立神经网络。
我们有一个有 784 个特征的单个神经元。这就构成了一个具有两个隐层的神经网络,如图 3-17 所示。
图 3-17
具有两个隐层的神经网络
步骤 11 :对实例进行预处理。展开 N 维数组为向量。
import numpy as np
x_train_reshaped = np.reshape(x_train,(60000, 784))
x_test_reshaped = np.reshape(x_test, (10000, 784))
print('x_train_reshaped:', x_train_reshaped.shape)
print('x_test_reshaped:', x_test_reshaped.shape)
下面显示了输出。
第十二步:创建模型。
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
model = Sequential([
Dense(128, activation='relu', input_shape=(784,)),
Dense(128, activation='relu'),
Dense(10, activation='softmax')
])
步骤 13 :激活功能:ReLU(整流器线性单元)。为了在节点中施加激活函数,第一步是定义输入的线性和。
第二步是定义激活函数输出。
图 3-18 显示了该功能。
图 3-18
具有两个隐层的神经网络
编译模型。
model.compile(
optimizer='sgd',
loss='categorical_crossentropy', metrics=['accuracy']
)
model.summary()
下面显示了输出。
第 14 步:训练模型。
model.fit(x_train_norm, y_train_encoded, epochs=3)
下面显示了输出。
第十五步:评估模型。
loss, accuracy = model.evaluate(x_test_norm, y_test_encoded)
print('Test Set Accuracy %', accuracy*100)
下面显示了输出。
第十六步:预测。
preds = model.predict(x_test_norm)
print ('Shape of predictions:', preds.shape)
下面显示了输出。
第 17 步:绘制结果。
plt.figure(figsize=(12, 12))
start_index = 0
for i in range(25):
plt.subplot(5, 5, i+1)
plt.grid(False)
plt.xticks([])
plt.yticks([])
pred = np.argmax(preds[start_index+i])
gt = y_test[start_index+i]
col = 'b'
if pred != gt:
col = 'r'
plt.xlabel('i={},pred={}, gt={}'.format(start_index+i, pred, gt), color = col)
plt.imshow(x_test[start_index+i], cmap= 'binary')
plt.show()
下面显示了输出。
第 18 步:绘制结果。
plt.plot(preds[8])
plt.show()
下面显示了输出。
实验操作:使用 Iris 数据集的深度神经网络分类器
本实验室主要使用 Iris 数据集进行深度神经网络分类。对于这个实验室,我们利用 Google Colab 云计算环境。
Google Colaboratory 是由 Google 提供的完全托管的免费服务,允许我们加载和运行用于数据科学、机器学习和深度学习的笔记本。除了 CPU,该环境还提供了利用 GPU 和 TPU 的选项。
这个实验室使用 TensorBoard,这是 TensorFlow 的可视化工具包[23]。它提供了机器学习实验所需的可视化和工具,如下所示。
-
跟踪和可视化损失和准确性等指标
-
可视化模型图(操作和层)
-
查看权重、偏差或其他张量随时间变化的直方图
-
将嵌入投影到低维空间
-
显示图像、文本和音频数据
-
剖析张量流程序
第一步:在 https://colab.research.google.com
访问谷歌合作实验室。
该链接应打开以下页面。
步骤 2 :点击欢迎来到合作实验室链接,访问更广阔的环境。观看介绍视频,熟悉 Google Colab 环境。
第三步:到左上角点击文件➤上传笔记本。您会看到以下屏幕。
第四步:上传 DNNIris.ipynb 笔记本文件:Chrome 调出一个你的操作系统特有的文件请求器:Finder (macOS)和 Windows Explorer (Windows)。导航到您保存的位置(例如,您的桌面)。从您的中选择下载并解压缩的实验室文件夹。zip 文件(不是。zip 文件本身)。然后使用 run 按钮或每个代码单元格左侧的箭头按钮运行它。
接下来,我们通过运行代码继续 hnads-on 练习:
步骤 1 :第一段代码测试环境并将必要的库导入到 Google Colab 环境中。
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
try:
# %tensorflow_version only exists in Colab.
%tensorflow_version 2.x
except Exception:
pass
import tensorflow as tf
from tensorflow import keras
第二步:读取数据。
import os
data = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
data_local = keras.utils.get_file(fname=os.path.basename(data),
origin=data)
iris = pd.read_csv(data_local)
iris.columns = ['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm','Species']
iris
输出列出了 Iris 数据集的一个示例。
第三步:塑造数据。
input_columns = ['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm']
x = iris [input_columns]
y = iris[['Species']]
print (x.head())
print('-----')
print (y.head())
输出显示了选定的列。
步骤 4 :对标签进行编码。输出标签是类似 Iris-setosa 或 Iris-virginica 的字符串。这些被称为分类变量。它们需要被转换成数字,就像我们对 SVM 所做的那样。这叫做编码。
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
y1 = encoder.fit_transform(y.values) ## need y.values which is an array
print(y1)
第五步:将数据分成训练/测试:80%用于训练,20%用于测试。
from sklearn.model_selection import train_test_split
# 'y1' (encoded labels)
x_train,x_test, y_train,y_test = train_test_split(x,y1,test_size=0.2,random_state=0)
print ("x_train.shape : ", x_train.shape)
print ("y_train.shape : ", y_train.shape)
print ("x_test.shape : ", x_test.shape)
print ("y_test.shape : ", y_test.shape)
下面显示了输出。
第六步:建立深度 NN 模型。由于这是一个分类器,神经网络将看起来如下。
输出层中的神经元=输出类(此处为 3)输出激活是“softmax”
-
输入层中的神经元=输入维度(此处为 4)
-
输出层中的神经元=输出类(此处为 3)
-
输出激活为“
softmax
”。 -
使用 Adam optimizer,这是一种优化算法,可用来代替经典的随机梯度下降过程,根据训练数据迭代更新网络权重。
input_dim = len(input_columns)
output_clases = 3
print ("input_dim : ", input_dim, ", output classes : ", output_clases)
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=64, activation=tf.nn.relu, input_dim=input_dim),
tf.keras.layers.Dense(units=32, activation=tf.nn.relu),
tf.keras.layers.Dense(units=output_clases, activation=tf.nn.softmax)
])
# loss = 'sparse_categorical_crossentropy'
model.compile(loss='sparse_categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(),
metrics=['accuracy'])
print (model.summary())
tf.keras.utils.plot_model(model, to_file='model.png', show_shapes=True)
下面的 NN 模型是代码片段的输出。
第 7 步:tensor board GUI 可能会在第一次出现 HTML 错误。使用 TensorBoard GUI 右上角的刷新图标刷新页面。
import datetime
import os
import shutil
app_name = 'classification-iris'
tb_top_level_dir= '/tmp/tensorboard-logs'
tb_app_dir = os.path.join (tb_top_level_dir, app_name)
tb_logs_dir = os.path.join (tb_app_dir, datetime.datetime.now().strftime("%H-%M-%S"))
print ("Saving TB logs to : " , tb_logs_dir)
#clear out old logs
shutil.rmtree ( tb_app_dir, ignore_errors=True )
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=tb_logs_dir, histogram_freq=1)
## This will embed Tensorboard right here in jupyter
%load_ext tensorboard
%tensorboard --logdir $tb_logs_dir
下面显示了 TensorBoard 视图中的输出。
步骤 8 :训练数据(这可能需要一段时间,取决于纪元值)。
%%time
epochs = 100 ## experiment 100, 500, 1000
print ("training starting ...")
history = model.fit(
x_train, y_train,
epochs=epochs, validation_split = 0.2, verbose=1,
callbacks=[tensorboard_callback])
print ("training done.")
下面显示了输出。
第九步:绘制历史。
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(history.history['accuracy'], label='train_accuracy')
plt.plot(history.history['val_accuracy'], label='val_accuracy')
plt.legend()
plt.show()
下面显示了输出。
将此图与 TensorBoard 的图进行比较,以确定训练和验证的准确性。
第十步:获取预测。
np.set_printoptions(formatter={'float': '{: 0.3f}'.format})
predictions = model.predict(x_test)
predictions
在步骤 10 的输出中,对于每个测试输入,softmax 层产生三个数字。这些数字是概率。如果把它们加起来,总数是 1.0。我们希望选择概率最高的输出。
例如,( 0.03086184,0.33362046,0.6355177)表示
-
1 类有 0.03 或 3%的概率。
-
2 类有 0.33 或 33%的概率。
-
3 类有 0.63 或 63%的概率。
因此,我们选择概率最高的类别作为预测:类别 3
步骤 11 :评估模型。
metric_names = mo
del.metrics_names
print ("model metrics : " , metric_names)
metrics = model.evaluate(x_test, y_test, verbose=0)
for idx, metric in enumerate(metric_names):
print ("Metric : {} = {:,.2f}".format (metric_names[idx], metrics[idx]))
下面显示了输出。
准确度显示非常接近 1.0,因为损耗仅为 0.12。
步骤 12 :由于这是一个分类问题,混淆矩阵是评估模型的有效方法。我们再次利用seaborn
库进行可视化,就像我们在 SVM 做的一样。
from sklearn.metrics import confusion_matrix
import seaborn as sns
cm = confusion_matrix(y_test, y_pred, labels = [0,1,2])
cm
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize = (8,5))
sns.heatmap(cm, annot=True, cmap="YlGnBu", fmt='d').plot()
from sklearn.metrics import classification_report
from pprint import pprint
pprint(classification_report(y_test, y_pred, output_dict=True))
以下是热图。
以下是混淆矩阵中的指标。
回到第二章中关于混淆矩阵的讨论,你能从这个输出中得出什么结论?
摘要
第三章着眼于人工神经网络,它将人脑的逻辑功能映射到计算系统,以创建智能机器。基于神经网络,深度学习解决人工智能中的特定问题,如推理、规划和知识表示。下一章涵盖量子信息处理概念的本质。*
四、量子信息科学
云彩飘进了我的生活,不再带来雨水或风暴,而是给我落日的天空增添色彩。
—罗宾德拉纳特·泰戈尔
量子信息涉及利用量子力学的特性来处理和传输信息。量子信息是指可以物理存储在量子系统中的数据。量子信息理论是研究这种信息如何被编码、测量和操纵的。量子计算是量子信息的一个子领域。它经常被用作量子信息理论的同义词,量子信息理论研究使用量子系统执行计算的协议和算法。
引用加州理工学院量子计算大师约翰·普雷斯基尔教授的话,“信息是以物理系统的状态编码的东西。”传统上,计算是在物理上可实现的设备上进行的。因此,一个不可回避的事实是,对计算信息过程的研究应该与对潜在的物理过程的研究内在地联系起来。
Note
本章重点介绍量子信息科学的基础知识,如量子并行性、Deutsch 算法、Qiskit 和 Google 的 Cirq 实践练习以及相关理论。本章以介绍量子计算系统作为我们处理的各种平台的先驱而结束。这应该为你在本书的未来章节中更深入地钻研量子算法和机器学习的应用做好准备。
物理学的发展与信息的使用和操作有显著的关系。1961 年提出的兰道尔原理指出,信息的擦除本质上是一个耗散过程。例如,我们可以考虑一个假设的“盒子里的原子”的情况,其中一个原子被放置在一个中间有水平隔板的充满气体的盒子里。如果原子被移动到分区的下半部分,它将被擦除,不管它是从顶部还是底部开始。分开上下两半的隔板突然移开,活塞压缩单原子气体,直到原子被限制在下半部分。压缩气体的行为导致气体熵的减少。单原子理想气体的熵 S 的变化给出如下【28】。
其中 N 为原子数, k 为玻尔兹曼常数, V f 为压缩后的最终体积, V i 为初始体积。随着熵的变化,从“盒子”到环境的热量也随之变化。如果我们认为系统是等温的(即温度保持恒定在 T 的系统),则在盒子上做功。如果用来擦除信息,就必须付出代价,也许是电费或煤气费。
根据朗道原理,如果电池供应有限,那么计算时间就应该有一个理论极限。然而,随着我们对信息物理学的理解不断发展,查尔斯·贝内特提出了这个理论。他在 1973 年指出,计算可以只用可逆的步骤来完成。原则上不需要耗散,不需要电力支出;于是,可逆计算。
根据理论,不需要付费来执行计算。然而,在实践中,今天使用的“不可逆”计算机消耗了大量的能量,数量级高于估计值。随着计算组件不断变得越来越小,击败兰道尔原理变得越来越重要,这样组件就不会在产生的热量中腐蚀或熔化;因此,可逆计算可能是留给工程的唯一选择。因此,量子信息演变为今天物理学和计算机科学的接口。
量子信息
经典信息论源于“信息是物理的”这一基本原则,本能地,它对我们思考信息的物理解释具有指导意义。在很大程度上征服了经典信息的大部分细节之后,我们必须考虑量子力学的法则从根本上支配着宇宙。
量子物理学是真正的随机性所在,与其经典对应物相反,经典对应物很大程度上是确定性的。在量子理论中,不可交换的可观察量不能同时具有由海森堡测不准原理描述的精确定义的值(第一章)。此外,如果对变量 x 进行测量,那么如果 x 和 y 不互换,则该测量行为会影响可观察变量 y 的后续测量结果。这意味着获取关于物理系统的信息的行为扰乱了物理系统;这不是经典物理学所受的限制。
信息由物质和能量的配置来表示;因此,信息存储、传输和处理的方式是由物理系统的法则决定的。在人类可以理解的尺度上,相关的物理定律是量子力学的定律。因此,量子信息是研究量子理论如何影响我们概念化和处理信息的能力。图 4-1 是量子信息处理的图示。
这导致了对如何理解和管理复杂的量子系统的信息携带特性的研究。对量子领域信息科学的日益了解为传统“经典”信息理论不可能实现的新应用打开了大门,例如完美安全通信、量子系统的高效模拟和超快量子计算机。近年来,在将量子信息带入现实世界方面,人们的兴趣和进展出现了爆炸式增长。它还提供了对物理、计算和信息的基本性质的见解。在实验室之外,第一批商用量子设备已经出现在市场上。
图 4-1
量子信息处理的概念
在物理系统中制造扰动以获取信息之间的权衡是由于量子系统的随机性。从一个量子系统中获取信息也会引起一个与不可克隆定理 ,相关的扰动,该定理指出量子信息不能被完美保真地复制。如果有可能完美地复制量子信息,这将使我们能够在不干扰原件的情况下测量副本的可观测属性,从而使我们能够绕过“测量时被干扰”的属性。但是,不可克隆定理禁止这种行为。正如我们所知,没有什么能完美地阻止经典信息的复制。几十年来,当任何人试图备份数据库或硬盘,甚至试图复制粘贴简单的文本时,这一特性都帮助了计算用户及其更大的生态系统。
量子电路和布洛赫球
量子计算电路是量子逻辑门的网络,其中每个门对一个或多个量子位执行某种特定的酉变换。与经典计算类似,量子电路是使用不同种类的运算选项构建的。这一部分详细阐述了第一章中提到的量子门的基础知识。它使用量子电路进行了一些实验,作为使用 Python 中的量子计算库进行编码的热身。这种电路是用量子门构建的,量子门一次对一个或两个量子位起酉算子的作用。这些电路可以使用本章中称为qCircuitCirq.ipynb
的 Python 笔记本来运行。这段代码运行在谷歌 Cirq 量子模拟器上,包括一个量子隐形传态实验。
量子态空间由称为希尔伯特空间的复向量空间构成(在第一章中讨论)。在量子信息科学中,总是假设希尔伯特空间是有限维的。由于
是有限维的,可以选择一个基将这个基中的向量表示为有限列向量,用有限矩阵表示算子。量子计算感兴趣的希尔伯特空间通常具有维度 d = 2 * n * ,对于某些正整数 n 。一个量子位状态可以被表示为 u,而没有任何一般性损失,如下所示。
(4.1)
其中,通常,kets ∣0⟩和∣1⟩是正交基,0 ≤ θ ≤ π 和 0 ≤ ϕ ≤ 2 π 和 i 表示状态向量的虚部。这通常被称为计算基础,而不具体说明该基础的物理实现。在量子信息科学中,计算可视化有助于将这种状态映射到布洛赫球,如图 4-2 所示。
图 4-2
布洛赫球
布洛赫球是一个抽象的三维表示,用球上的一个点来表示量子位的状态。就布洛赫球而言,基态∣0⟩和∣1⟩分别是北极和南极。X 轴与球面相交的对跖点对应于以下标准正交态
(4.2)
(4.3)
方程式 4.2 和 4.3 类似于方程式 1。19 和 1。20 。换句话说,参照第一章, H ∣0⟩ = ∣ + ⟩,h∣1⟩=∣⟩.这些状态被称为哈达玛基,因为它们可以通过应用称为哈达玛变换、 H 的 2 × 2 酉矩阵从计算基中获得。
(4.4)
哈达玛变换与泡利矩阵有关。参考等式 1。13 ,其给出了泡利矩阵的数学表示,我们看到 Y 轴与球体表面相交的对跖点对应于以下正交正态。
(4.5)
(4.6)
图 4-3 显示了布洛赫球上的一些量子位状态。
图 4-3
具有单量子位状态的布洛赫球(来源[31])
布洛赫球面上的叠加
叠加在第一章中定义。由量子位构建的状态空间比由经典的二进制位表示的对应状态空间携带更多的信息,因为量子位状态是根据两个连续的实参数 θ 和 ϕ 来指定的。换句话说,经典描述只告诉我们是在北半球还是南半球,而量子位状态向量区分的是布洛赫球表面的每一点。
量子位状态通常被表示为∣0⟩和∣1⟩.基态的叠加如果对大量 N 个相同的单量子位状态进行测量,那么大约次输出为 0,大约
次输出为 1。概率对量子世界的影响与经典世界有着显著的不同。
有可能在量子计算机上开始一个物理过程——无论是门还是退火过程——以∣0⟩为初始状态,然后让状态演化。这种状态的演变也可以通过使用哈达玛算符 H 来完成,类似于我们之前实验的 GHZ 电路。如果这是在一个经典系统上尝试,第一步,经典推理,说我们有 50%的机会在∣0⟩,50%的机会转到∣1⟩.现在假设该过程的第二步通过 Hadamard 算子再次进行进化。在这里,经典推理说,如果我们在第一步后仍在∣0⟩,有 50%的机会,我们会在第二步后留在∣0⟩;此外,如果我们碰巧在第一步后翻转到∣1⟩州,有 50%的可能性在第二步该州再次翻转,最终回到∣0⟩.因此,经典推理说,在应用h2 之后,处于状态∣0⟩的总概率由下式给出,即 50%。
然而,如果我们现在考虑这样一个事实,即h2 是一个恒等运算符(即等于 1),那么我们认识到这个物理过程在 100%的时间里都将∣0⟩作为输出。这里的区别在于,量子测量产生的概率计算可以考虑干涉效应。用经典的波动行为来经典地模拟干涉是可能的,但这是量子物理已经内置于其中的固有属性。
在这个例子中暴露出的经典推理的局限性表明,我们在思考量子叠加态时应该小心。这是因为量子位状态在∣0⟩和∣1⟩同时是而不是。它不在任何一个州。取而代之的是一种不同的物理状态,叫做∣− ⟩状态。在量子位元的某些物理实现中,阿达玛基底和计算基底一样是测量状态的好基底。如果用来测量的基被交换,那么|−⟩态就不是叠加态。对于希尔伯特空间中的任何状态,总是有测量基的选择,其中该状态是基状态之一,因此不是叠加态。因此,叠加是没有意义的,除非量子系统指出某些测量基础优于其他测量基础。
具有 Qiskit 的量子电路
2017 年 3 月,IBM 宣布发布 IBM Quantum Experience,这是一个连接到用超导材料获得的真实量子处理器的平台。有可能通过云接入使用这个量子计算平台,在量子硬件系统上执行程序。Qiskit 允许管理真实和模拟的量子电路。编程可以通过图形界面或 CLI(命令行界面)来完成。量子计算环境还通过 API(应用编程接口)提供可编程性:一组用于与设备和模拟器接口以及运行实验的类、函数和数据结构。根据他们的 API 文档[275],Qiskit 的框架有以下主要方面。
-
奇斯基特
-
Qiskit 模拟器(Aer)
-
齐斯基特实验(伊格尼丝)
-
Qiskit 应用模块(Aqua)
-
Qiskit IBM Quantum(提供商)
用 Qiskit 编写的程序遵循基于三个高级步骤的固定工作流。
-
建立一个电路。
-
执行程序。
-
分析结果。
Qiskit 管理三个主要对象[275]来执行工作流:provider
、backend,
和job
。provider
提供了一组不同的backend
来选择适合我们特定算法的。AER provider
允许访问不同的模拟器,而 IBM provider
允许通过 IBMQ 模块访问真实的量子位环境。
backend
负责运行量子电路并返回结果。它们将一个qobj
作为输入,并返回一个BaseJob
对象。每个执行都由一个惟一的地址标识,可由Job
对象访问,该对象找出给定时间点的执行状态(例如,如果作业正在排队、正在运行或已经失败)。Qiskit 工作流程如图 4-4 所示。
图 4-4
Qiskit 工作流
Qiskit 提供了用 Bloch 球模拟量子态空间的选项。要实现正确的可视化并在 Jupyter notebook 上正确操作,需要 Qiskit Terra 0.16 . x 版以及 Python 3.6 或更高版本。这可以在 Linux 环境中通过以下命令进行安装。
$ pip install qiskit[visualization]
如果您已经安装了 Qiskit,并在没有 Qiskit Terra 0.16.x 提供的可视化更新的情况下尝试该代码,您可能会遇到以下错误。
VisualizationError – input is not a valid N-qubit state.
如果您已经安装了 Qiskit 和较旧版本的 Terra,并且遇到了这个错误,请使用-U
选项更新qiskit[visualization]
。
如果您在 Windows 上有一个 Anaconda 环境,请在命令行窗口(cmd.exe
)中打开一个 Anaconda 提示符,并键入以下内容。
conda install qiskit[visualization] -U
这将启动图 4-5 所示的所有相关文件的更新、下载和安装。
图 4-5
Qiskit Terra 更新并安装在 Windows 上的 Anaconda 中
一旦 Qiskit 包成功安装,我们就可以使用 Bloch 球体尝试一些量子态的可视化练习。这解释了三维布洛赫表面上的矢量的解释。我们从导入Qiskit
库开始,并使用清单 4-1a 中所示的plot_bloch_vector()
函数为 Jupyter 笔记本qiskitBloch.ipynb
文件可视化一个样本 Bloch 球体。qiskit.__qiskit_version__
显示所有 Qiskit 组件和 API 的工作版本。
## import the libraries
import numpy as np
from qiskit import *
qiskit.__qiskit_version__
from qiskit.visualization import plot_bloch_vector
%matplotlib inline
plot_bloch_vector([0,1,0], title="Bloch Sphere")
Listing 4-1aBloch Sphere Simulation in qiskitBloch.ipynb
这段代码生成版本号和我们的示例 Bloch sphere 作为输出,如图 4-6 所示。
图 4-6
样本 Bloch 球体和版本号
Note
不要混淆量子位的状态向量和它的布洛赫向量。状态向量是保存量子位可能处于的两种状态的振幅的向量。Bloch vector 是一个可视化工具,它将二维的复杂状态向量映射到真实的三维空间。布洛赫球是纯态的几何表示。提供绘制斑点球的 Qiskit 函数是 plot_bloch_vector()。值得注意的是,每个布洛赫球代表一个量子位取向(即,两个量子位由两个布洛赫球代表;三个量子位需要三个布洛赫球,依此类推)。
了解 Qiskit 如何处理门定义是很有帮助的。我们在本章前面的 Qiskit 中遇到了 GHZ 态。为此,我们首先导入所有必要的库,如清单 4-1b 所示,并尝试一个 X gate。当我们看泡利门(方程式 1 时,x 门的定义在第一章中有所涉及。13 。在这个例子中,使用了plot_bloch_multivector()
函数,它接受一个量子位的状态向量,而不是 Bloch 向量。
from math import pi
from qiskit.visualization import plot_bloch_multivector
#X-gate on a |0> qubit
qc = QuantumCircuit(1)
qc.x(0)
qc.draw()
Listing 4-1bGate Programming in qiskitBloch.ipynb
清单 4-1b 给出以下电路作为输出。
这里,我们在状态对一个量子位执行了 x 或非门操作,并将其翻转到∣1⟩.状态让我们在一个布洛赫球表示上验证 X-gate 操作的结果,如清单 4-1c 所示。
# Verify The result
backend = Aer.get_backend('statevector_simulator') # Simulate
out = execute(qc,backend).result().get_statevector() # Do the simulation, returning the statevector
plot_bloch_multivector(out) # Display the output state vector
Listing 4-1cBloch Representation of the X-operation qiskitBloch.ipynb
清单 4-1c 给出了下面的 Bloch 球表示作为输出。
输出证实了量子位的状态是预期的∣1⟩。这是绕布洛赫球的 X 轴旋转了 π 弧度。
Qiskit 库允许在电路中添加门。例如,如果我们要将 Pauli Y 和 Z gate 添加到我们之前创建的 X gate 中,我们需要清单 4-1d 中的代码片段。
qc.y(0) # Do Y-gate on qubit 0
qc.z(0) # Do Z-gate on qubit 0
qc.draw()
Listing 4-1dY and Z gate Addition to X Gate qiskitBloch.ipynb
这个代码片段给出了下面的电路作为输出。
Qiskit 仅允许测量 Z 基准。当进行测量时,并不总是要求以任何固定的计算基础(即 Z 基础)进行测量。量子位的测量可以在我们选择的任何基础上进行。例如,我们可以计算在 x 轴上测量∣+ ⟩或∣− ⟩的概率。
p(|+⟩)= |⟨+|q⟩|2,p(|−⟩)= |⟨−|q⟩|2
一旦测量完成,量子位就保证处于这两种状态之一。由于 Qiskit 只允许在 Z 基础上进行测量,因此需要我们使用 Hadamard 门创建自己的测量(参见清单 4-1e )。
# Create Hadamard gate for the X-measurement function:
def x_measurement(qc,qubit,cbit):
"""Measure 'qubit' in the X-basis, and store the result in 'cbit'"""
qc.h(qubit)
qc.measure(qubit, cbit)
qc.h(qubit)
return qc
initial_state = [0,1]
# Initialise our qubit and measure it
qc = QuantumCircuit(1,1)
qc.initialize(initial_state, 0)
x_measurement(qc, 0, 0) # measure qubit 0 to classical bit 0
qc.draw()
Listing 4-1eHadamard qiskitBloch.ipynb
该代码片段给出了以下电路,其中 H 门和 M 门用于测量作为输出。
这些练习演示了通过将 Z 门夹在两个 H 门之间来创建 X 门是可能的。
计算从 Z 开始。然后 H 门将量子位切换到 X 基,之后 Z 门在 X 基中执行 NOT,最后另一个 H 门将量子位返回到 Z 基。接下来,我们使用与清单 4-1c 相同的语法在 Bloch 球体上执行验证,并获得图 4-7 中的以下输出。
图 4-7
X gate 基础转移的验证
如果 Jupyter 笔记本单元格再次运行,您可能会看到不同的结果;然而,量子位的最终状态总是∣+ ⟩或∣− ⟩.量子位在|1⟩.状态下被初始化测量的结果是,∣+ ⟩和∣− ⟩.崩溃了
Qiskit 允许在真实设备或qasm_simulator
上运行的量子电路的数据可视化。为了方便起见,有一个plot_histogram(data)
函数。作为一个例子,看看如何用 Qiskit 创建钟形状态。两个量子位系统的计算基可以转换成由四个贝尔态定义的标准正交基。
带 Qiskit 的贝尔州
当一个系统纠缠在一起时,各个独立的系统组成一个整体。任何测量系统的一部分——在我们的例子中是第一个粒子——的测量都是对整个系统的测量。然后系统的波函数坍缩,两个粒子都呈现确定的状态。两党制基础的一个流行例子是贝尔基础或贝尔态。两个量子位的贝尔态通常由下式给出。
(4.7)
(4.8)
(4.9)
(4.10)
∣β??⟩态被称为三重态。有三种三重态。另外两个是∣00⟩和|11⟩.∣β11⟩被称为单态。清单 4-1f 显示了一个构建铃态的量子电路,它打印铃测量计数,然后生成一个直方图。
# quantum circuit to create a Bell state
bell = QuantumCircuit(2, 2)
bell.h(0)
bell.cx(0, 1)
meas = QuantumCircuit(2, 2)
meas.measure([0,1], [0,1])
# execute the quantum circuit
backend = BasicAer.get_backend('qasm_simulator') # the device to run on
circ = bell + meas
result = execute(circ, backend, shots=1000).result()
counts = result.get_counts(circ)
print(counts)
from qiskit.visualization import plot_histogram
plot_histogram(counts)
Listing 4-1fBell State qiskitBloch.ipynb
这将产生以下输出,作为对响铃状态的测量计数。
图 4-8 中的直方图是从qiskit.visualization.
调用的plot_histogram()
函数的输出
图 4-8
贝尔状态概率直方图
本节是一个热身练习,让我们深入了解 Qiskit 在接下来的章节中的操作,在接下来的章节中,我们将专注于定义更复杂的算法。
具有 Cirq 的量子电路
量子计算机在基于门的量子计算机中,基于对量子位的酉门操作,作为量子电路执行程序。量子计算电路是量子逻辑门的网络,其中每个门对一个或多个量子位执行某种酉变换。在上一节中,您已经使用 Qiskit 看到了一些这样的门的例子。本节使用 Cirq [30]探讨类似的见解。
Cirq 是 Google 为量子计算机编程而创建的开源框架。它是“一个 Python 软件库,用于编写、操纵和优化量子电路,然后在量子计算机和量子模拟器上运行它们。”Cirq 为处理当今嘈杂的中等规模量子计算机提供了有用的抽象,其中硬件的细节对于实现最先进的结果至关重要。Cirq 文档位于 https://quantumai.google/cirq
。GitHub 直播在 https://github.com/quantumlib/Cirq
。
Cirq 在 Python 3.6.x(本书中首选的 Python 版本)中通过以下命令安装。
图 4-9
LTS Ubuntu 18.04 上的 Cirq 安装。(qml
)是虚拟环境名
$ pip3 install cirq
图 4-9 显示了一个安装过程的例子,其中软件包被安装在一个名为qml
的虚拟环境中。第一章描述了创建虚拟环境的方法。
一旦安装了 Cirq,就从同一个虚拟环境中打开一个 Jupyter 笔记本会话,并通过打印 Google 的cirq.google.Bristlecone
和Cirq.ipynb
中的代码来运行清单 4-2a 中的快速验证测试。Bristlecone 是一台谷歌量子计算机,他们用它实现了量子优势。每个刚毛设计芯片都有 72 个量子位。
import cirq
import numpy as np
print(cirq.google.Bristlecone)
Listing 4-2aBloch Sphere Simulation in Cirq.ipynb
该代码产生图 4-10 中的输出,确认 Cirq 安装成功。
图 4-10
Cirq 中的谷歌刺果酮
该电路由最初在∣0⟩态制备的单个量子位组成,用酉 x 门操作处理,然后在计算基础上再次测量量子位。
清单 4-2b 显示了定义 X 门的步骤。
# Get a qubit and a circuit
qbit = cirq.LineQubit(0)
circuit = cirq.Circuit()
# Add an X gate: acts like the Pauli Matrix sigma_x
circuit.append(cirq.X(qbit))
Listing 4-2bGenerate a Qubit and a Circuit Cirq.ipynb
在清单 4-2c 中,下一步,我们用cirq.Simulator()
函数运行模拟。
# Simulation that extracts the wavefunction
sim = cirq.Simulator()
result = sim.simulate(circuit)
print("\nBloch Sphere of the qubit in the final state:")
state = cirq.bloch_vector_from_state_vector(result.final_state,0)
print("x: ", np.around(state[0], 4), " y: ", np.around(state[1], 4)," z: ", np.around(state[2], 4))
Listing 4-2cSimulation of Wave Function Cirq.ipynb
该代码生成量子位在其最终状态下的以下 Bloch 定义作为输出。
下一步,列出 4-2d ,为电路添加一个测量门。
# Add a measurement gate at the end of the circuit:
circuit.append(cirq.measure(qbit, key="Final state"))
# Display the circuit:
print("\nCircuit:")
print(circuit)
Listing 4-2dAdd Measurement on X Gate Cirq.ipynb
该代码产生以下电路作为输出,显示测量门为 M 。
这个实验的下一步(见清单 4-2e )使用模拟器并运行十次试验模拟来确定量子位的最终状态。
# Invoke the Cirq quantum simulator to execute the circuit
simulator = cirq.Simulator()
# Simulate the circuit several times:
result = simulator.run(circuit, repetitions=10)
# Print the results:
print("\nResults of 10 trials:")
print(result)
Listing 4-2eRepeated Simulations Cirq.ipynb
此代码的输出给出了以下最终状态。
这个例子使用 Cirq 模拟器的一个用户友好的特性,提取量子最终态波函数。这在真正的量子计算机上通常是不可能的,在量子计算机上你必须多次运行相同的电路才能到达最终状态。在本例中,最后一个州是∣1⟩.
用 Cirq 测量响铃状态
在本练习的前面,您已经在 Qiskit 中遇到了贝尔状态及其定义。您应该熟悉 Cirq 中响铃状态的产生和测量。有可能在计算基础上采用两个量子位的状态,并通过在第一个量子位上使用哈达玛门,然后在一对量子位上使用 CNOT 门,将它们转换成贝尔状态,如下所示。
(4.11)
(4.12)
(4.13)
(4.14)
在两个量子位的希尔伯特空间中,方程 4.11–4.14 中所示的幺正变换是从两个量子位计算基到贝尔态基的变换。如果以相反的顺序执行酉运算,则有可能从贝尔基旋转回到计算基。这个逆操作,接着测量量子位,被称为贝尔态测量。净效应是使用 EPR 对将两个量子比特的状态投射到四个贝尔态中的一个。电路如图 4-11 所示。清单 4-2f 是启动铃状态测量练习的代码。
图 4-11
纠缠 EPR 对上的门操作
# Get two qubits and a circuit
qubit = [cirq.LineQubit(x) for x in range(2)]
circuit = cirq.Circuit()
# Add a Hadamard gate to qubit 0, then a CNOT gate from qubit 0 to qubit 1:
circuit.append([cirq.H(qubit[0]),
cirq.CNOT(qubit[0], qubit[1])])
# Run a simple simulation that extracts the actual final states
sim = cirq.Simulator()
result = sim.simulate(circuit)
print("\nBloch Sphere of the qubit 0 in the final state:")
state = cirq.bloch_vector_from_state_vector(result.final_state,0)
print("x: ", np.around(state[0], 4), " y: ", np.around(state[1], 4), " z: ", np.around(state[2], 4))
print("\nBloch Sphere of the qubit 1 in the final state:")
state = cirq.bloch_vector_from_state_vector(result.final_state,1)
print("x: ", np.around(state[0], 4), " y: ", np.around(state[1], 4), " z: ", np.around(state[2], 4))
Listing 4-2fMeasurement on X Gate Cirq.ipynb
这个代码片段给出了以下输出。
然后,我们在电路中添加一个测量门,与 X 门中的一样。这显示在清单 4-2g 中。
# Add a measurement at the end of the circuit:
circuit.append(cirq.measure(*qubit, key="Final state"))
# Display the circuit:
print("\nCircuit:")
print(circuit)
Listing 4-2gMeasurement on X Gate Cirq.ipynb
以下电路作为输出打印出来,显示测量门为 M ,哈达玛门为 H 。
对于 Bell states 练习中的最后一步,我们运行模拟十次,与上一个练习相同。
# Run the Cirq quantum simulator to execute the circuit:
simulator = cirq.Simulator()
# Simulate the circuit several times:
result = simulator.run(circuit, repetitions=10)
# Print the results:
print("\nResults:")
print(result)
Listing 4-2hMeasurement on X Gate Cirq.ipynb
输出如下。
如果清单 4-4h 运行几次,每个量子位的结果随机变化,但是它们在两个量子位之间是 100%相关的。量子模拟器的结果来自最终态的计算基础中的 10 次测量,∣β00⟩,这是与爱丽丝和鲍勃相同的 EPR 对态。请注意,Cirq 报告说,两个量子位的最终状态都在布洛赫球的中心,而不是在其表面。
总之,关于 EPR 对,有一些事情需要记住。
-
量子随机性发生在窃听者(比如伊芙)和爱丽丝之间以及伊芙和鲍勃之间,但不发生在爱丽丝和鲍勃之间。
-
当 Alice 和 Bob 接收到相同的二进制位串时,Eve 当时不可能拥有他们的位串。
-
虽然是随机生成的,但它们共享的位串最终会产生很大的因果后果。
这种量子怪异被爱因斯坦称为“超距幽灵行动”
熵:经典与量子
熵被宽泛地定义为量化信号中信息的一种方式。简而言之,熵可以被解释为我们对给定系统状态的不确定性**或测量系统后我们获得的信息量。
香农熵
经典信息的关键概念是香农熵。克劳德·香农熵试图提供与给定状态∣ ψ i ⟩, i ∈ {1… n }相关联的信号中的信息的统计表示。香农的理论是基于发现看到给定信息的概率。这使得科学家们能够表征从信号中获得的信息量。
Shannon 通过对给定消息的概率取以 2 为底的对数来量化所获得的信息量。如果消息中包含的信息用ι表示,其出现的概率用 p 表示,那么
??
其中,负号确保消息的信息内容保持为正。比如今天股市不暴跌 5%以下的概率是 0.9,那么新闻的信息量就是ι= log20.9 = 0.152。
形式上,如果 x ∈ { x 1 ,x2…xn}是概率分布为p∈{p1,p2…
因此,如果给定的 x i 的概率为 0,则香农熵为 0∫log 0 = 0。如果状态是纯的,香农熵估计其最小值为 0,如果是随机的,则取其最大值。状态的混合增加了熵。一般来说,下面的经验法则估计香农熵。
-
如果信息或消息的内容是确定的,那么香农熵为零。
-
下一条信息内容的不确定性越高,香农熵就越高。
换句话说,熵量化了我们测量 x 时获得的信息量。被称为二元熵函数 (BEF)的熵函数示例如图 4-12 所示。在信息论中,BEF 被定义为成功概率为 p 的伯努利试验的熵。在数学上,伯努利试验被建模为一个随机变量 x ,它只能取两个值:0 和 1。事件 x = 1 被认为是成功的,而事件 x = 0 被认为是失败的,其中两个事件是互斥且穷尽的。
如果 x = 1 的概率由Pr(x= 1)=p给出,那么 x = 0 的概率由Pr(x= 0)=(1-??)p 给出。在他的例子中, x 的熵由
(4.16)给出
其中对于二元运算,对数通常以 2 为底。
图 4-12
香农熵的二元熵函数
如图 4-12 所示,熵在时达到最大值。最大熵出现在具有最少知识量的实例中。当每个可能的结果都是同样可能的时,那么离散概率 p * i * 反映了关于测量结果的最少量的知识。因此,有了 n 个可能的结果,每个概率由
(4.17)给出
其中的情况是无偏位的情况,无偏位是信息熵最常见的单位。清单 4-3 显示了用于生成图 4-12 中的情节的简单 Python 代码
BinaryEntropyFunction.ipynb
的片段。定义了概率和熵,并基于对数函数生成值以给出熵图。
# Import Libraries
import matplotlib.pyplot as plt
import math
# Define Probabilities and Entropy Functions
px0 = []
px1 = []
Sx0=[]
Sx1=[]
A=0.99
B=0.01
px0.append(1)
Sx0.append(0)
for i in range(99):
V = math.log(A,2)
J = math.log(B,2)
Sx0.append((-A*V)+(-B*J))
px0.append(A)
px1.append(B)
# Sx1.append(-A*(math.log(A,2)) -B*(math.log(B,2)))
A -= 0.01
B += 0.01
px0.append(0)
Sx0.append(0)
# Print the values and the graph
for i in range(20):
print()
print("p(x): ",end="")
for j in range(5):
print(str(px0[j*i+i])+",",end="")
print()
for i in range(20):
print()
print("S(x): ",end="")
for j in range(5):
print(str(Sx0[j*i+i])+",",end="")
plt.plot(px0, Sx0, color='blue')
plt.xlabel('P(X)')
plt.ylabel('S(X)')
plt.title('Binary entropy function')
plt.show()
Listing 4-3Libraries and Functions in BinaryEntropyFunction.ipynb
从数学上讲,如果 p = 0.3,那么找到替代方案的概率就是 1p= 0.7。
这表明在测量之前已经知道了状态,因为一个可能的值比另一个更有可能。在这种情况下,参考方程 4.2 ,我们有
另一方面,如果我们有 if p = 0.05,备选项的概率为 95%,那么我们得到
结果的完全不确定性意味着所有可能的结果都是同样可能的。一般规律是熵越大,测量前结果的不确定性越大。
冯·诺依曼熵
一个量子态的熵值是由香农熵的一个类似物决定的。这是通过使用密度算子而不是方程 4.1 中的概率分布元素来实现的。量子信息理论与经典理论有些相似,因为信息是由量子系统携带的。因此,这是有区别的,因为量子位在不止一种意义上携带信息。
-
经典比特可以被编码成量子比特。
-
由于不可克隆定理或可分辨性的限制,未知量子位可以携带隐藏和保护的信息。
如果我们回忆一下等式 1。29 在第一章中,混合量子系统的密度算符如下。
(4.18)
其中∣ψI⟩代表混合量子系统中一个系综中的 n 个可能态, p i 是一个成员处于相应态的概率∣ψI⟩.
回想一下,密度算符是一种描述量子系统可能状态的方式,或者等效地说,是一种描述可能测量结果的方式,与概率分布非常相似。具有密度算符 ρ 的量子态的熵称为冯诺依曼熵,由
(4.19)给出
其中 Tr 描绘了密度算子的轨迹。
在具有密度态 ρ 和 ϵ 的混合系统中,相对冯诺依曼熵由
给出(4.20)
一般情况下,s(ρ|ϵ)≥0。只有当 ρ = ϵ 时才相等。
如果密度算符的特征值由λI给出,那么冯诺依曼熵由
给出(4.21)
一般来说,在 n 维中,量子态的熵遵循不等式。
(4.22)
量子系统中的复合态通常是由量子位态的张量积形成的态。如果一个复合态是可分的,那么它就形成了一个形式为 ρ ⊗ ϵ 的乘积态。在这种情况下,熵是可加的,由
(4.23)给出
一般来说,熵是次可加的。换句话说,复合系统的简化密度矩阵由不等式
(4.24)给出
方程 4.10 表明,要获得关于一个纠缠系统的最多信息,我们需要考虑整个系统;也就是说, S ( ρ )小于简化密度矩阵的组合熵,因为当考虑整个系统时知识增加了。拥有简化密度矩阵ρ1 和ρ22的用户在仅考虑系统的部分时对状态的了解较少。
状态的演变
由于它们固有的性质,在量子物理中,系统的状态通常随时间演化。在量子计算的电路和门模型中,状态按照酉矩阵运算演化(参见 1 章)。状态向量的演化相当于执行线性代数。在量子退火平台上,使用哈密顿量来模拟状态的演化(参见第一章)。有两种重要的状态:混合态和纯态。纯态具有这样的性质:它们总是可以被表示为一个状态向量与其自身的外积。混合状态一般表示为正交状态向量的和。在纯态下,冯·诺依曼熵永远为零,类似于确定性的香农熵。在混合态中,熵可以用一系列值来表示。
冯·诺依曼熵的性质可以总结如下。
-
S ( ρ ) = 0 当且仅当 ρ 为纯态。
-
对于
(希尔伯特空间的维数),S(ρ)= logN给出了 S ( ρ )对于最大混合态的最大值。
-
S ( ρ )在基变化下不变(即S(ρ)=S(UρU)对于任何酉矩阵 U )。
-
For a set of numbers {λi} such that and λi > 0, and for a corresponding collection of density matrices {ρi} we have
-
For a set of numbers, S(ρ) satisfies
-
s(ρm⊗ρn)=s(ρm)+s(ρ**n)为独立
-
s(【123】)+()≤**
**** s()≤??(+***
***一个系统从纯状态发展到混合状态,然后又恢复到纯状态的实例可能有助于理解这个过程。在这个过程中,冯·诺依曼熵先增大,然后逐渐减小回到零。
第一步,我们定义自旋向上和自旋向下的状态向量以及由外积给出的纯态。这显示在清单 4-4a 中。这些库可以在qiskitStateEvo.ipynb,
Jupyter 笔记本代码示例中找到,其中提供了完整的代码和额外的示例。我们用 Qiskit 来探索态的量子演化。
为了开始一些编码,我们调用qiskit
库来展示 GHZ 状态。Qiskit
是一个 Python 库,它创建量子电路,并在模拟器或 IBM 的量子设备上运行它们。
import numpy as np
from qiskit import *
import math as m
from scipy import linalg as la
%matplotlib inline
# Spin-up
u = np.matrix([[1],
[0]])
# Spin-down
d = np.matrix([[0],
[1]])
# Pure state |0><0|
P11 = np.dot(u, u.H)
# Pure state |1><1|
P22 = np.dot(d, d.H)
Listing 4-4aSpin-up, Spin-down Definition at qiskitStateEvo.ipynb
使用qiskitStateEvo.ipynb.
中的清单 4-4b 绘制状态演变图
import matplotlib.pyplot as plt
p = np.arange(0.001, 1., 0.01)
# create list of von Neumann entropies
vn_y = list()
for value in p:
rho_p = value*P11 + (1-value)*(P22)
vn_y.append(von_neumann_entropy(rho_p))
# convert list of matrices to list of nos. for plotting
y = list()
for value in vn_y:
y.append(value.tolist()[0][0])
# plot p vs. S(rho_p)
plt.xlabel('p')
plt.ylabel('von Neumann Entropy')
plt.title('S(rho_p)')
plt.plot(p, y, color='tab:red')
plt.show()
Listing 4-4bvon Neumann Definiton in qiskitStateEvo.ipynb
清单 4-4b 的输出如图 4-13 所示。
图 4-13
冯·诺依曼熵
图 4-13 的冯诺依曼图和图 4-12 的经典香农熵之间的比较表明,它们非常相似。
冯诺依曼熵的单参数密度矩阵族如清单 4-4c 所示。
# Define spin-up
u = np.matrix([[1],
[0]])
# Define spin-down
d = np.matrix([[0],
[1]])
# Define the pure state |0><0|
P11 = np.dot(u, u.H)
# Define the pure state |0><1|
P12 = np.dot(u, d.H)
# Define the pure state |1><0|
P21 = np.dot(d, u.H)
# Define the pure state |1><1|
P22 = np.dot(d, d.H)
# Define the mixed state |0><0| + |1><1|
I = (P11+P22)/2
# Define the pure state |0><0|+|0><1|+|1><0|+|1><1|
D = (P11+P12+P21+P22)/2
p = np.arange(0.001, 1., 0.01)
# Create list of von Neumann entropies
vn_y = list()
for value in p:
rho = value*I + (1-value)*(D)
vn_y.append(von_neumann_entropy(rho))
# list of matrices to list of numbers for plotting
y = list()
for value in vn_y:
y.append(value.tolist()[0][0])
# plot p vs. S(rho_p)
plt.xlabel('p')
plt.ylabel('von Neumann Entropy')
plt.title('S(rho_p)')
plt.plot(p, y, color='tab:blue')
plt.show()
Listing 4-4cOne-Parameter Family in qiskitStateEvo.ipynb
清单 4-4c 产生如图 4-14 所示的输出。
图 4-14
单参数密度矩阵的冯·诺依曼熵
GHZ 状态
在量子信息理论中,GHZ 态代表 green Berger-Horne-zei linger 态,由 Daniel Greenberger、Michael Horne 和 Anton Zeilinger 于 1989 年首次研究[29]。它是一种特定类型的纠缠量子态,涉及两个以上的子系统(例如,粒子态或量子位)。GHZ 态是最大纠缠量子态。对于由 n 个子系统组成的系统,每个子系统都是二维的(即量子位),GHZ 状态由
(4.25)给出
三量子比特 GHZ 态是最简单的一种。它表现出非平凡的多体纠缠。
GHZ 状态是所有处于状态 0 的子系统的量子叠加,所有子系统都处于状态 1,其中单个子系统的状态 0 和 1 是完全可区分的。
使用量子电路可以制备 1 GHZ。清单 4-4d 是 Jupyter 笔记本qiskitStateEvo.ipynb.
中的 Qiskit 代码片段
from qiskit import *
import numpy as np
%matplotlib inline
qr = QuantumRegister(3)
cr = ClassicalRegister(3)
GHZ = QuantumCircuit(qr, cr)
GHZ.h(0)
GHZ.cx(0,1)
GHZ.cx(1,2)
GHZ.draw(output='mpl')
Listing 4-4dGHZ in qiskitStateEvo.ipynb
清单 4-4d 给出了 GHZ 输出的量子电路,如图 4-15 所示。
图 4-15
GHZ 量子电路
清单 4-4e 中 Qiskit 的Statevector()
函数打印状态向量。状态向量用于使用 Qiskit 中的entropy()
函数获得相应密度矩阵的冯诺依曼熵。Qiskit 中的DensityMatrix()
函数被传递给GHZ_state
ket 向量。
backend = Aer.get_backend('statevector_simulator')
GHZ_state = execute(GHZ,backend).result().get_statevector()
print(np.matrix(GHZ_state).H)
from qiskit.quantum_info import Statevector
psi = Statevector(GHZ_state)
print(psi)
Listing 4-4eStatevector in qiskitStateEvo.ipynb
现在可以使用 Qiskit entropy()
函数计算冯诺依曼熵。这可以通过Statevector
函数或DensityMatrix
函数传递。在后一种情况下,输出实际上是零熵,而在第一种情况下,它正好是零。这是有意义的,因为态是纯态,密度矩阵计算为d=∣ψ⟩⟨ψ|。
值得注意的是在达到最终混合状态之前的中间时间点的最大值。一般来说,熵会随着时间的推移而增加。然而,在可以行使实质性控制的有效“封闭”量子系统中,熵可以降低到更低的水平(见清单 4-4f )。
from qiskit.quantum_info import entropy
vn_entropy1 = entropy(psi, base=2)
vn_entropy2 = entropy(D, base=2)
print(vn_entropy1)
Listing 4-4fEntropy in qiskitStateEvo.ipynb
下面显示清单 4-4f 的输出为 0。
从 GHZ 态的密度矩阵 D 给出的态演化到密度矩阵 ρ 描述的系统的熵可以通过列出 4-4g 来计算。
from qiskit.quantum_info import random_density_matrix
rho = random_density_matrix(8, rank=None, method='Hilbert-Schmidt', seed=None)
print(rho)
time = np.arange(0.001, 1., 0.01)
vn_entropy = list()
for t in time:
vn_entropy.append(entropy(D, base=2)*t + entropy(rho, base=2)*(1-t))
# Create list of von Neumann entropies
vn_y = list()
for value in p:
M = value*rho + (1-value)*(D)
vn_y.append(entropy(M))
# plot p vs. S(rho_p)
plt.xlabel('time')
plt.ylabel('von Neumann Entropy')
plt.title('S(rho(t))')
plt.plot(p, vn_y, color='tab:blue')
plt.show()
Listing 4-4gEntropy Calculation of Evolved State in qiskitStateEvo.ipynb
输出曲线如图 4-16 所示。
图 4-16
演化 GHZ 系统的熵
在图 4-16 中,最大值出现在中间时间点,就在达到最终混合状态之前。一般来说,熵会随着时间的推移而增加。然而,在有效封闭的量子系统中,可以进行实质性的控制,熵可以降低到较低的水平。
再论不克隆定理
第章 1 讨论了量子力学的不可克隆定理,该定理指出量子态不能通过门操作等幺正变换直接复制或克隆。这意味着如果∣ ψ ⟩是一个量子态,而 U 是某种幺正变换,使得u∣ψ0⟩=∣ψψ⟩,那么这个性质不可能适用于任意态∣ ψ ⟩.该理论源于两个正交态(如单量子位情况下的∣0⟩和∣1⟩)和一个 U 的线性量子叠加的可能性,使得u∣ψ0⟩=∣ψ♀⟩和u∣ϕ0÷=∣9 如果我们考虑叠加,那么
(4.26)
(4.27)
从方程 4.26 和 4.27 我们看到
(4.28)
本质上,不可克隆定理规定我们不能复制一个未知的量子态。然而,这并没有对复制一个已知的量子态施加任何限制。的确,这样做应该是可能的;实际上,它说我们可以准备同一个已知状态的许多相同的副本。不可复制定理对量子通讯有重大的影响,因为它暗示了要建构一个保存任意量子资讯的放大器是不可能的。不可克隆定理也使黑客无法复制信息和违反安全。
量子隐形传送
量子隐形传态是一个过程,通过这个过程,一个量子比特状态可以通过只发送两个经典比特的信息来传输。这个选项的工作原理是分发纠缠的量子粒子。这些纠缠在一起的粒子,一旦以可控的方式分布在两端,就产生了虚拟通道。
如图 4-17 所示,量子隐形传态是一种利用 EPR(爱因斯坦-波多尔斯基-罗森)源的纠缠贝尔对的现象[32]。
图 4-17
带测量电路的量子隐形传态
图 4-17 所示的电路是带测量的量子隐形传态,初始状态为∣000⟩;通过应用 X 和 Y 门的随机幂,消息量子位被转换成非平凡状态。Alice 和 Bob 量子比特纠缠在一起成为 EPR 对。对消息和 Alice 量子位执行 Bell 测量。来自这个测量的经典信息然后控制 Bob 量子位上的两个单量子位操作。过程如下。
-
发送者爱丽丝将一对纠缠粒子中的一个粒子发送到目的地,同时保留另一个粒子作为源。
-
对于一个窃听者 Eve 来说,不可克隆定理认为在不破坏纠缠粒子状态的情况下观察和测量它是不可能的。一旦她测量了一个特定的状态,测量的行为就会导致这个状态崩溃。换句话说,Eve 没有办法破坏安全。量子纠缠的这个特性使它成为一个安全的 ?? 通道。
-
理论上,不仅纠缠对的安全性很高,而且一对粒子也可以不受距离的影响而保持纠缠,甚至在宇宙尺度上。在实验中,量子纠缠已经被证明在空间和地球之间的距离达到大约 1200 公里,在地面实验中达到 50 公里[33]。
-
接收器 Bob 需要一个经典的开放信道来有效地解码量子数据,为此提出了 Eckert91 [34]类型的纠缠以确保严格的安全性。
-
爱丽丝首先通过量子通道将纠缠的量子比特∣b1⟩传送给鲍勃。
图 4-15 中的量子位 2 和 3 是 Bell 态的纠缠 EPR 对。
(4.29)
-
方程 4.25 中的∣b00⟩有下标 00,表示按照惯例,所有量子位都在∣0⟩.状态初始化
-
Figure 4-15 shows the three-qubit state in five characteristic points of a quantum circuit. The input three-qubit state at point A is given by
(4.30)
-
The first qubit is used as a control qubit, and the second qubit is the target qubit for the CNOT (Control-X) gate. Therefore, the state at point B becomes,
(4.31)
-
The Hadamard gate (H) performs mapping on the first qubit.
(4.32)
-
The state at point C is given by
(4.33)
-
The second qubit is used as a control qubit. The third is a target qubit in the CNOT gate. The quantum state at point D is given by
(4.34)
-
Finally, the state at point E is given by the following. (The first qubit is used for control and the third as the target for the controlled-Z gate.)
(4.35)
(4.36)
-
作为最后一步,对前两个量子位进行测量,这两个量子位被销毁,第三个量子位被传送到接收器。
-
目的地和源量子位之间的比较提供了正确的量子态被传送的结论。这种分析没有考虑量子通道引入的任何误差。
注意,传送状态是而不是叠加状态。因此,任何任意态的∣b1⟩都可以通过图 4-15 方案进行隐形传送。Alice 测量她的侧信道数据,并通过经典信道将其发送给 Bob。鲍勃使用图 4-15 中经典控制的泡利 X(或 CNOT)和 Z 门重建量子数据。这种情况本质上是安全的,因为
-
测量改变了纠缠粒子的状态。
-
攻击者需要访问量子和经典通道才能成功解码。
这部分是关于 Cirq 的实践课程,看看传送是如何工作的。编码练习表明,鲍勃量子位的最终状态保证是消息量子位最初所处的任何状态。这只有在 Alice 和 Bob 之间预先共享纠缠态的情况下才是可能的。
在下面的练习中,通过应用 X 和 Y 门,在随机状态下准备消息(量子位 0)。Alice 拥有消息量子位和量子位 1,量子位 1 是带有 Bob 的量子位 2 的 EPR 对的一部分。爱丽丝现在对她的一对量子位元进行贝尔态测量,得到四种可能的结果之一。然后,她将相当于两个经典比特的结果传输给 Bob。Bob 对他的量子位执行酉运算,这取决于他从 Alice 收到的信息。
在清单 4-5a 中,继续我们之前的 Cirq 练习,三个量子位、Hadamard 门和测量被定义为形成隐形传态电路,如代码体中所评论的。
import random
# Define three qubits: msg = qubit[0], qalice = qubit[1], qbob = qubit[2]
qubit=[0]*(3)
qubit[0] = cirq.NamedQubit('msg')
qubit[1] = cirq.NamedQubit('qalice')
qubit[2] = cirq.NamedQubit('qbob')
circuit = cirq.Circuit()
# Create a Bell state entangled pair to be shared between Alice and Bob.
circuit.append([cirq.H(qubit[1]), cirq.CNOT(qubit[1], qubit[2])])
# Creates a random state for the Message.
ranX = random.random()
ranY = random.random()
circuit.append([cirq.X(qubit[0])**ranX, cirq.Y(qubit[0])**ranY])
# Unitary operator rotating the two-qubit basis of the Message and Alice's entangled qubit;
# rotates the Bell state basis to the computational basis:
circuit.append([cirq.CNOT(qubit[0], qubit[1]), cirq.H(qubit[0])])
# Combining now with a measurement in the computational basis,
# we effectively have projected this two-qubit state onto one of the four states of
# the Bell state basis:
circuit.append(cirq.measure(qubit[0], qubit[1]))
Listing 4-5aTeleporation Circuit Definition Cirq.ipynb
下面使用来自贝尔测量的两个经典比特来恢复。
# Use the two classical bits from the Bell measurement to recover the
# original quantum Message on Bob's entangled qubit.
circuit.append([cirq.CNOT(qubit[1], qubit[2]), cirq.CZ(qubit[0], qubit[2])])
print("Circuit:")
print(circuit)
Listing 4-5bRecover Original Message in Bob’s Entangled Qubit Cirq.ipynb
这就给出了下面的隐形传态电路作为输出,类似于图 4-17 。
下一步类似于上一个关于贝尔状态的练习。我们管理 cirq。Simulator()来定义创建消息并输出 Bloch 球体位置的门(参见清单 4-5c )。
sim = cirq.Simulator()
# Simulation that applies the random X and Y gates to
# create the message.
q0 = cirq.LineQubit(0)
message = sim.simulate(cirq.Circuit([cirq.X(q0)**ranX, cirq.Y(q0)**ranY]))
print("\nBloch Sphere of the Message qubit in the initial state:")
expected = cirq.bloch_vector_from_state_vector(message.final_state,0)
print("x: ", np.around(expected[0], 4), " y: ", np.around(expected[1], 4), " z: ", np.around(expected[2], 4))
Listing 4-5cBloch Sphere Output Cirq.ipynb
例如,如果代码运行多次,输出结果可能会发生变化。
这种行为是量子力学概率性质的直接结果。
最后一步是找到最终状态的布洛赫球,如清单 4-5d 所示。
# Records the final state of the simulation.
final_results = sim.simulate(circuit)
print("\nBloch Sphere of Bob's qubit in the final state:")
teleported = cirq.bloch_vector_from_state_vector(
final_results.final_state, 2)
print("x: ", np.around(teleported[0], 4), " y: ",
np.around(teleported[1], 4), " z: ", np.around(teleported[2], 4))
print("\nBloch Sphere of the Message qubit in the final state:")
message_final = cirq.bloch_vector_from_state_vector(
final_results.final_state, 0)
print("x: ", np.around(message_final[0], 4), " y: ", np.around(message_final[1], 4), " z: ", np.around(message_final[2], 4))
Listing 4-5dBloch Sphere of the Final state Cirq.ipynb
最终输出给出了如下的布洛赫状态。
如果程式码执行几次,就很清楚讯息量子位元的最终状态永远不是∣0⟩就是∣1⟩,这是微不足道的,也是不可复制定理的表现。《星际迷航》的粉丝可能还记得,这就是为什么麦考伊博士反对在星舰企业号上使用传送装置,因为传送过程似乎会破坏原始信息,然后在其他地方瞬间重新创建!
我们进行测量的量子隐形传态电路的变体是相同的电路,但是没有测量。如清单 4-5e 所示,计算基础中省略了量子位 0 和 1 的测量。
# Unitary operator rotating the two- qubit basis of the Message and Alice's entangled qubit;
# rotates the Bell state basis to the computational basis:
circuit.append([cirq.CNOT(qubit[0], qubit[1]), cirq.H(qubit[0])])
# This time skip the measurement
# circuit.append(cirq.measure(qubit[0], qubit[1]))
# Use the same operations as before to recover the
# original quantum Message on Bob's entangled qubit.
circuit.append([cirq.CNOT(qubit[1], qubit[2]), cirq.CZ(qubit[0], qubit[2])])
Listing 4-5eTeleportation Without Measurement
没有测量的传送和有测量的一样有效。这是延迟测量的原理的体现,它意味着测量一个量子位的操作与使用它作为受控门操作的控制的操作互换。
隐形传态的基本工作方式包括用一个经典的通信通道来代替部分交换,这使得鲍勃的量子位可以任意远离爱丽丝的量子位。目前,传送的速度只受到一个事实的限制,即经典信息的传输速度不能超过光速。鲍勃可以选择在接收到来自爱丽丝的经典传输之前测量他的量子位,因为有 25%的时间,他已经有了正确的量子状态,而无需执行任何“校正”当爱丽丝的信息最终出现时,鲍勃知道他传送的信息是否有效。
远距离量子隐形传态不再是实验室里的思想实验。费米实验室与加州理工学院和美国电话电报公司合作,正在调试一个高保真、高速率的量子隐形传态系统,该系统使用近红外光子在标准电信光纤上移动,将两个时间仓叠加作为量子位。其他国家实验室正在开发类似的系统(见 Joe Lykken 课堂笔记[35])。
闸门调度
在我们深入第五章的量子算法的复杂性之前,让我们先解决一些大多数量子算法所基于的基础知识。本节介绍门调度和相关主题的指令级优化。对逻辑量子位的一系列门操作被称为时间表。逻辑量子位由一个或多个物理量子位组成,可以叠加,被认为比物理量子位有更多的相干时间。物理量子位是量子位的实际量子实现物理实现如电子或原子。就今天的技术水平而言,物理量子位面临着不完美和一致性的挑战。当前物理构建的多量子位系统的局限性可以通过从几个不完美的物理量子位构建一个逻辑量子位来克服。逻辑量子位可以用于编程,并可以由运行在台式机或笔记本电脑上的普通 CPU 上的模拟器来实现,以允许量子算法的开发、测试和调试。
量子电路的门之间有数据依赖。门控序列排序定义了门控之间数据相关性。对于图 4-18 中具有量子位 q1、q2 和 q3 的电路,如果它们共享一个逻辑量子位,门 G2 依赖于门 G1。
图 4-18
门控序列
一个量子位一次只能参与一个量子门。由于量子电路从左到右执行,数据相关性决定了量子电路中门的顺序和并行执行的顺序。背对背的两个顺序门通常具有明确定义的排序约束,换句话说,
如果门 A 和 B 都是任意的酉运算符,那么交换它们出现的顺序通常会产生不同的结果。在一些特殊情况下,酉矩阵有时可以排序,即使不总是等价的。在这些情况下,他们被认为是相互交换。
一般两个并排的平行浇口没有排序约束。在基于门的量子电路中,门调度的影响可能非常显著。许多算法的实现依赖于并行执行门来实现非平凡的加速。
量子算法中的门调度不同于它们的经典对应物,因为门调度为用户提供了额外的自由度。与经典指令调度相比,量子门调度的研究相对较少,提出的系统方法较少,因此,量子门调度是当前活跃研究的主题,试图找到更新的约束。
量子并行性和函数评估
量子算法的基本原理始于量子并行。量子并行性是许多量子算法的基本特征。在许多使用函数的情况下,重点是找到函数的结果。然而,在函数的特征或性质比函数评估更重要的情况下,量子算法比它们的经典部分更有优势。量子并行性允许量子计算机同时对 x 的许多不同值评估一个函数 f ( x )。换句话说,量子计算机可以在叠加态下对 f ( x )的各种值进行求值。
如果 f ( x )是一个以单比特为输入,单比特为输出的函数,那么 f ( x )就称为一个二元函数。因此,该函数只对 0 和 1 进行运算,其结果也是 0 或 1。
要定义函数,让,
比如恒等函数 f ( x ) = 0 当 x = 0 和 f ( x ) = 1 当 x = 1 和常数函数 f ( x ) = 0 和 f ( x ) = 1。位翻转函数也属于同一类: x = 0 时f(x)= 1x= 1 时 f ( x ) = 0。
身份和位翻转功能也被称为平衡,因为它们的输出在一半输入中是相反的。当 f (0) = f (1)时,该函数称为常数,而当f(0)-1=f(1)时,该函数称为平衡。注意,陈述x→f(x)的运算通常不是酉运算,因此不适合量子计算。
一般情况下,给定一个函数的输出 f ( x ),并不总是可以反相 f ( x )得到输入 x 。换句话说, f ( x )的计算方式必须保证计算可以撤销。为了解决这个问题,第一个任务是将这些功能建模为量子电路。然而,我们不能简单地将任何门应用于一个量子位,因为根据量子力学的假设,所有的量子操作必须是酉和可逆(参见第一章)。
可逆幺正变换如图 4-19 所示。
图 4-19
酉变换(来源[35])
图 4-19 显示了酉变换,其中一个假想的酉变换Uf作用于两个量子位,使得
(4.37)
对方程 4.37 的解释表明,第一量子位保持不受Uf作用的影响。而第二量子位经受异或运算(由⊕算子给出)。
对于初始值 y = 0,我们从方程 4.37 得到如下。
我们可以证明Uf是可逆的。如果我们再次对其输出应用 U f ,我们得到
这里我们使用了模 2 特性,即f(x)⊕f(x)= 0(注意:模 2 运算状态:将相同的位相加两次并除以二,余数为零)。
请注意,我们将 U f 视为“黑盒”或“神谕”(即 U f 的内部细节与我们无关。一位先知描述了一个“量子黑盒”,我们假设我们可以实现和运行它,但不能“检查内部”来查看它的实现细节。在内部, U f 由一个或多个量子门组成,甚至可能是一个电路,但我们通常不知道是哪些门或哪种电路。通过查询甲骨文(例如,通过发送输入和测量输出),我们可以了解更多关于甲骨文的属性。因为预言是由量子门组成的,所以预言本身也需要是可逆的。
现在我们已经建立了算法的基础,可以解释量子并行性的基本原理了。
图 4-20
量子并行电路
-
Starting with two qubits at initial state |0⟩, as shown in Figure 4-20, we apply a Hadamard gate to the first qubit. This gives us
-
The second qubit, also at initial state ∣0⟩, after the unitary transformation gives the final state ∣ψf⟩.
从检查结果可以清楚看出,图 4-19 的电路同时包含了 f (0)和 f (1)的信息;换句话说,电路已经产生了一个叠加状态,该状态在一个单一步骤中具有关于 f (0)和 f (1)的信息。我们有所谓的量子并行性——在一次操作中同时获得两种状态的信息。
量子并行的例子表面上看起来很酷。但是,如果我们停下来想一想我们是如何获得任何信息的,比如这个系统的测量值,我们会看到一个迫在眉睫的问题:如果我们测量状态,那么我们只获得一个值 x 和 f ( x )作为计算基础。在我们执行测量之后,我们获得的函数值是随机值 x 。因此,这个操作本身并不能提供非常有用的结果,因为我们甚至不能选择我们希望显示哪个值: f (0)或 f (1)。这就是 Deutsch 算法变得重要的地方。
多伊奇算法
平衡函数和常数函数已在上一节中描述。然而,找出一个函数是否确实是常数或平衡的往往是一个挑战!为了回答这个问题,大卫·多伊奇在 1985 年提供了一个很好的概念证明:在某些情况下,量子计算机比经典计算机更强大。Deutsch 算法[37]可以简单地用下面的框架来表述。
-
确定 f (0) ⊕ f (1)的奇偶性值,其中⊕表示模 2 加法或异或运算;也就是说,1 ⊕ 1 = 0 ⊕ 0 = 0,1 ⊕ 0 = 0 ⊕ 1 = 1。
-
证明如果 f ( x )为常数那么奇偶性为 0,如果 f ( x )为平衡,那么奇偶性为 1。
Deutsch 算法试图解决哪个/哪些给定函数是常数或平衡的。平衡和常数函数的属性是全局属性,因为为了比较行为,需要计算 f (0)和 f (1)函数(见图 4-21 )。
图 4-21
Deutsch 算法的电路 37
Deutsch 算法的主要目标是通过获得关于全局状态的信息来找到最终状态∣ψf⟩。该算法通过使用叠加态来实现这一点,该叠加态是系统由于量子并行性的性质而实现的。最终状态计算如下。
(4.38)
其中系统的初始状态是∣ψI⟩=∣01⟩,⊗照常表示状态的张量积。
以下是 Deutsch 算法的步骤。
-
Evaluate ∣ψi⟩ by applying Hadamard gates to the input states. By the definition of Hadamard gates, this action produces a product state of superposition. To calculate ∣ψi + 1⟩, we have the following.
该操作创建一个叠加状态,包含组合的所有可能值( x , f ( x ))。
-
In step 2, we apply Uf to ∣ψi + 1⟩ as follows.
-
在这一步,我们把我们的分析分成两种情况:当 f ( x )平衡时和当它恒定时。
Case 1: f (x) is constant ⇒ f (0) = f (1). Therefore, substituting f (0) for f (1) in ∣ψi + 2⟩, we have
老地方,老地方。这意味着量子位现在处于∣+ ⟩态。因此,
这意味着量子位 1 处于∣0⟩.状态因此,如果现在在标准基础上对量子位 1 进行测量,结果是完全确定的 0。
情况二: f ( x )平衡f(0)≦f(1)和 f (0) ⊕ 1 = f (1)和 f (1) ⊕ 1 = f (0)。
因此,
老地方,老地方。这意味着量子位现在处于∣− ⟩态。因此,
这意味着量子位 1 处于∣1⟩.状态因此,如果现在在标准基础上对量子位 1 进行测量,结果是完全确定的 1。
总之,如果 f 恒定,Deutsch 算法给出 0 作为输出,如果 f 平衡,给出 1 作为输出。因此,该算法仅使用单个查询来确定 f 是平衡的还是恒定的。通过量子并行,无需显式评估同一函数的值即可计算该函数的全局属性。
带 Cirq 的 Deutsch 算法
现在你已经理解了 Deutsch 的算法,是时候用代码DeutschCirq
.ipynb
做一个练习了。清单 4-6a 中的程序随机选择函数 f ( x ) = 1 进行求值,并测量第一个量子位的最终状态。首先,我们导入库并构造一个函数来定义类似于图 4-20 的电路。清单 4-6a 定义了以下三个函数。
-
main()
:生成一个函数(0,1) → (0,1)-
调用
moracle
将生成的函数映射到相应的 oracle -
用生成的神谕构建量子电路
-
-
moracle()
:将函数映射到相应的 oracle -
deutsch_circuit()
:创建量子电路-
初始化两个量子位
-
将 X 门应用于量子位 2
-
对每个量子位应用哈达玛门以产生叠加
-
应用神谕
-
将哈达玛门应用于第一个量子位
-
执行测量
-
import cirq
from cirq import H, X, CNOT, measure
import numpy as np
import random
def main():
# Choose qubits to use.
q0, q1 = cirq.LineQubit.range(2)
# Pick a secret 2-bit function and create a circuit to query the oracle.
secret_function = [random.randint(0, 1) for _ in range(2)]
oracle = moracle(q0, q1, secret_function)
print('Secret function:\nf(x) = <{}>'.format(
', '.join(str(e) for e in secret_function)))
# Embed the oracle into a quantum circuit querying it exactly once.
circuit = deutsch_circuit(q0, q1, oracle)
print('Circuit:')
print(circuit)
# Simulate the circuit.
simulator = cirq.Simulator()
result = simulator.run(circuit)
print('Result of f(0)⊕f(1):')
print(result)
def moracle(q0, q1, secret_function):
""" Gates implementing the secret function f(x)."""
# coverage: ignore
if secret_function[0]:
yield [CNOT(q0, q1), X(q1)]
if secret_function[1]:
yield CNOT(q0, q1)
def deutsch_circuit(q0, q1, oracle):
c = cirq.Circuit()
# Initialize qubits.
c.append([X(q1), H(q1), H(q0)])
# Query oracle.
c.append(oracle)
# Measure in X basis.
c.append([H(q0), measure(q0, key='result')])
return c
Listing 4-6aDeutsch’s Algorithm First Step DeutschCirq.ipynb
接下来,在清单 4-6b 中应用 main 方法。这是运行程序并生成最终输出的方法。
if __name__ == '__main__':
main()
Listing 4-6bGenerate Output DeutschCirq.ipynb
该代码在运行时会给出最终输出。
量子计算系统
本节旨在给出量子计算(QC)系统和相关关键组件的高级概述。今天的质量控制系统,不管种类如何(基于门控或退火),都由所有平台通用的三个主要组件组成:硬件层、软件层和应用层。在门模型 QC 中,出于信息抽象的原因,软件层与硬件层耦合,并且可以进一步分类为虚拟层、用于量子纠错的层和用于寻址基于门的通用 QC 的编程底层的逻辑层。如图 4-22 所示,引用自琼斯、范·米特等人【39】。
图 4-22
量子计算系统的分层架构(来源[39])
今天的 QC 空间有各种平台,每个平台都支持某些领域的效率。应用程序可以从量子计算中受益。我们现在需要找到合适的设备。量子计算领域是一个广阔的领域,因此,不同的制造 QC 系统的公司已经取得了许多不同的进展。因此,许多不同的量子器件被开发出来,每一种都有自己的优点和局限性。开发应用程序时,了解哪种设备最适合解决特定问题非常重要。
一些最受欢迎的量子设备是基于门的量子计算机,其中使用量子逻辑门对量子位进行操作。你学习了编程和两种基于 gate 的属性,比如本章中的计算机,即 IBM Q(用于 Qiskit)和 Google Cirq。这种 QCs 使用的逻辑门类似于经典计算机中的逻辑门,但是更加复杂多样。你看到了盖茨的例子,包括哈达玛,泡利,CNOT 和旋转。
基于门的量子计算有许多不同的实现方式。
-
超导量子器件:最流行的使用噪声量子电路的硬件实现。它们需要用低温技术冷却到接近绝对零度(–273°C)。在这些类型的平台上工作的组织的例子有 IBM、Google 和 Amazon。
-
囚禁离子设备:这些平台使用囚禁离子作为量子位。这些设备往往具有非常高保真度的量子位,具有高得多的相干时间,但目前,与超导设备相比,量子位计数较低。专注于这类技术的公司的一个例子是 IonQ。
-
基于光子的设备:这些设备使用光子作为量子位。这些设备往往具有高保真度和快速门控操作,并且不需要制冷。致力于这些技术并取得重大进展的公司是 Xanadu 和 PsiQuantum。
另一种量子计算机使用退火技术。量子退火器,如 D-Wave 建造的量子退火器,在解决优化问题时非常有效。经典的背包问题、旅行推销员问题和最大割问题都可以通过这样的平台非常有效地解决。这是在量子退火机上完成的,首先将量子位初始化为叠加态。在这之后,量子位和它们之间的连接被慢慢调整。在运行结束时,配置对应于感兴趣的最佳解决方案。D-Wave 计算机的工作方式可以总结如下。
-
参数被转换成电压、电流和磁场。这个问题被编程到 D-Wave QPU(量子处理单元)上。
-
量子位自旋从它们的叠加态开始。
-
量子位自旋进化并探索问题空间。
-
当退火过程结束时,系统到达所提交问题的基态或低激发态。
-
读取自旋的状态,应用任何所需的预处理,并将结果返回给用户。
-
每秒钟可以做几百次。
量子控制中一些主要的挑战和国际研究兴趣的主题是量子纠错(QEC)相干性和量子存储器。一些量子计算机,如超导量子设备,容易受到噪声的影响,从而导致误差。这些误差分为三种主要类型:位翻转、相位翻转和读出误差。这些误差可以使用量子误差校正/减轻方法来校正;然而,这可能需要量子电路中额外的量子位和门。
开源软件在量子算法的设计和测试中变得至关重要[38]。许多工具由主要的商业供应商支持,目的是使开发 quantum 软件更容易。这反映了资金充足的开放机器学习框架如何使复杂模型的开发及其在同样复杂的硬件上的执行成为可能。现在有各种各样的量子计算开源软件,涵盖了量子工具链的所有阶段,从量子硬件接口到量子编译器,再到量子算法的实现,以及所有的量子计算范式,包括量子退火和离散及连续可变门模型量子计算。
门模型量子计算机通常具有如图 4-23 所示的工作流程。
图 4-23
门控模型 QC 中的工作流程(来源[38])
在门模型中,问题是在高层次上定义的。基于问题的性质选择合适的量子算法。接下来,量子算法被表达为一个量子电路,需要被编译成一个特定的量子门集合。最后,量子电路要么在量子处理器上执行,要么用量子计算机模拟器模拟。
图 4-24 显示了使用量子退火时的典型工作流程。
图 4-24
绝热 QC 中的工作流程(来源[38])
在量子退火过程中,作为第一步,问题被定义,然后被编码成 Ising 型哈密顿量,该哈密顿量被可视化为图形。第二步,通过小图嵌入将哈密顿问题嵌入到量子硬件图中。最后,量子退火器或经典解算器被用于采样对应于原始问题的(近)最优解的低能态。
图 4-23 和 4-24 中的过程从高层次的问题定义开始(例如,解决给定图上的旅行商问题或背包问题)。解决这样一个问题的第一步是决定一个合适的量子算法。量子算法被定义为解决一个问题的有限步骤序列,其中每个步骤都可以在量子计算机上执行。作为一个例子,在旅行推销员问题中,我们面临一个离散的最优化问题。因此,用户可以考虑一个适当的算法(例如,量子近似优化算法(QAOA) [40],设计用于噪声离散门模型量子计算机或量子退火,以找到最佳解决方案)。
摘要
量子信息是指可以物理存储在量子系统中的数据。量子信息理论是研究这种信息如何被编码、测量和操纵的。本章介绍了 Qiskit 和 Cirq 中的基本算法、量子并行性、隐形传态和相关编程。下一章涵盖了量子机器学习基础的要点,如 Deutsch-Jozsa 算法,优化理论,信息编码和量子复杂性。***
五、QML 算法 1
你不能仅仅站着盯着水看就穿过大海。
—罗宾德拉纳特·泰戈尔
第一台量子计算机是几年前建造的。目前,QC 技术有多种平台可供选择,每种平台都在某些领域表现出效率。应用程序可以从量子计算中受益。你只需要找到合适的设备。开发应用程序时,了解哪种设备最适合特定问题的解决方案,以及在同一平台上哪种算法最受支持非常重要。
用量子计算推动经典机器学习的想法已经存在好几年了。这些想法几乎不像有些人认为的那样新颖或激进。事实上,D-Wave quantum annealer 的机器学习演示可以追溯到 2009 年[60]。
Note
在之前的章节中,我们进行了与 gates 和基本算法相关的动手编程,例如 Deutsch with Qiskit 和 Google 的 Cirq。在这一章中,我们用 Rigetti 的 Forest SDK 做了同样的事情。在接下来的章节中,我们将深入研究 D-Wave 的量子退火解决方案和 Xanadu 基于光子的量子机器学习库。
通过处理编码在所有可能输入的叠加中的量子信息,量子计算机可以同时计算每个可能输入的每个输出值。这叫做量子并行。量子计算和相关算法领域是通过 Deutsch 在 1985 年[37]基于 Feynman [41]的早期思想对通用量子计算的研究而开创的。该领域可分为与补充研究工作相关的不同部分,如。
-
开发用于计算和通信的量子算法
-
开发用于计算和通信的硬件
-
寻求鲁棒容错的解决方案
-
为机器学习开发量子算法
-
提高可扩展性
-
寻找普遍性的证据
彼得·肖尔(Peter Shor)在 1994 年提出了一种将数字因式分解为素数的量子算法。他的算法能够以比经典计算更快的速度完成任务。于是,实现量子计算机的可能性就成了安全问题。诸如 RSA 加密这样的代码,基于数学上未证实的复杂性假设被认为是有效安全的, 1 突然变得易受攻击;不再是因为不存在数学证明,而是因为一种新型的计算机,它的存在是物理定律所允许的。然而,矛盾的是,量子密钥分发(QKD)中的量子理论也提供了无条件安全问题的解决方案;即使是量子计算机也不能让量子密码变得不安全。
今天的量子计算机是嘈杂的(即,它们的量子位在物理层面上容易出错),因此,它们的实际状态是不稳定的(即,状态在短时间内衰减)。此外,用于操纵量子位的门的实现容易出错(即,门不精确地操纵它所操作的量子位),导致与预期结果的小偏差,并且这种错误在算法执行期间传播。量子位出错的现象被称为退相干。门是错误的现象被称为门不忠。
除了退相干、错误和不忠,当前构建物理量子计算机的技术在设备上的量子位数量方面具有有限的扩展能力。单个设备上超过一定数量的量子位以及控制和连接它们的工程方法会引入量子位和周围系统的干扰。因此,今天的量子技术的可扩展性仅限于(充其量)中等规模。嘈杂和中等规模的特性促使质量控制大师约翰·普雷斯基尔创造了术语嘈杂的中等规模量子 (NISQ)计算机【68】。
根据量子并行性和叠加态的定义,量子计算机在普适量子计算中的强大之处在于量子算法应该利用大量(尽可能多的)量子比特;否则,这些算法可以在经典计算机上模拟。然而,很大程度上由于工程和实际实现的限制,大多数 NISQ 时代的量子算法都以“低深度”告终。
深度是基于电路的量子计算的三个主要复杂性之一。计算复杂度可以根据机器用来完成所述计算的时间或空间量来指定。对于计算的电路模型,复杂性的一个自然量度是电路中使用的门的数量。第二个度量是电路的深度。电路复杂性的测量如图 5-1 所示。
图 5-1
一种深度为 3,空间为 4,宽度为 4,共有 5 个门的电路
如果我们将电路想象成被分成一系列离散时间片的,其中单个门的应用需要单个时间片,则电路的深度是其时间片的总数。这不一定与电路中门的总数相同,因为作用于不相交位的门通常可以并行应用;例如,在同一时间片期间,一对门可以应用于两条不同线上的位。电路复杂性的第三个度量类似于图灵机的空间(或宽度)。这是电路中位或“线”的总数,有时称为电路的宽度或空间。**
低深度算法也称为浅算法。按照现在的情况,如果一个算法需要很高的深度(深度算法),它可以只利用几个量子位,那么它就可以被模拟。这意味着量子优势必须基于浅层算法(即仅使用几层并行门的算法)来显示。
今天的 NISQ 机器的物理量子位限制所强加的浅算法的低深度自动要求实现混合算法(即,被分成经典部分和浅量子部分的算法)。混合算法的经典部分和量子部分在一个循环中执行,结果在迭代之间得到优化[56] [69]。优化行为可能会影响混合算法的量子部分和经典部分[70]。
图 5-2 显示了混合算法的一般结构。它的量子部分使状态准备好被恰当地表示算法的酉变换操纵。酉变换产生的结果被测量并传递到工作流的经典部分。如果测量结果被认为是可接受的,则作为结果交付;否则,再次处理测量结果。输出作为输入传递给预处理步骤,该步骤相应地控制状态准备。
图 5-2
量子算法的一般结构(来源[48])
混合算法的结构遵循大多数量子算法的一般结构(即,由算法处理的量子态,如酉变换),必须准备好,这通常需要经典的预处理。通过测量算法本身的结果产生的输出需要被再次处理(后处理)(例如,通过评估或改进其质量)。在许多情况下,后处理步骤不会启动另一个迭代(即,它不会将输入传递给预处理步骤)。
实现算法的电路应该在其上运行的目标 QC 平台影响整个算法,因为它可能支持与算法所假设的不同的门集,或者因为目标机器具有某些硬件限制。例如,以基于退火的平台作为目标量子机器的基于门的算法将不会是成功的实现。
在我们深入研究量子算法和机器学习的本质细节之前,最好了解更多关于量子计算复杂性的信息。
量子复杂性
你在第一章已经初步了解了计算复杂性。问题的复杂性指的是从算法、计算时间等角度来看,涉及占用资源的问题类别。为了估计总的计算成本,需要对资源进行分析。这是通过运行解决问题所需的算法来完成的。
计算机运行一个算法的时间就是该算法在特定计算平台上的运行时间。根据经典计算的基本原理,通过验证数据库中的项目直到找到一个期望的项目,可以获得数据库搜索目标的解决方案。这个练习需要时间复杂度为 O ( n )的最坏情况场景。
算法的计算复杂度是算法的时间、规模和相关资源需求如何随着数据集或问题规模的增长而发展的定量表达。算法旨在应用于未知函数或一组数据,以确定函数的属性(如周期或最小值)、因数或分类数据。
该函数的输入数量(即数据的大小)可以是从一位数到数万亿或更多。有很多算法可以选择。尝试它们,直到你找到似乎能完成这项工作的算法。一旦我们选择了一个我们认为适合我们的目的或目标的算法,我们需要决定对以下问题的响应:随着算法所操作的输入数量的增加,算法的运行时间会如何表现?这被称为算法对大小的敏感度。
随着算法问题规模的增长,它的运行时间也在增长。这被称为时间复杂度。以下是在下一章中讨论的各种时间复杂性。
-
恒定时间复杂度
-
多项式时间复杂度
-
非多项式时间复杂度
如果硬件电路可以随着数据集的增长而增长(或者利用大量现有服务器中的大量处理器),那么计算所需的时间可能不会很长,并且可以用时间复杂度换取空间复杂度。
当谈到量子超越经典方法时,当前的兴趣是量子计算和通信领域的相对加速。为了实现这一点,通常,硬件黑盒类型的方法找出量子算法提供的时间优势(如果有的话)。
如果考虑到空间复杂度,那么算法中的电路在最坏的情况下是线性增长的 ??,而在大多数情况下是对数增长的 ??。任务是采用经典的昂贵的指数算法,并使用量子计算找到多项式算法。因此,估计硬件的线性或对数增长被有利的时间成本所克服,因此可以忽略。
量子复杂性理论的领域已经发展成为经典复杂性理论的扩展[44] [45]。它基于量子计算机是否在原则上能够更快地解决与运行时间复杂性相关的计算问题。
为了比较算法,习惯上使用度量或工具。一个这样的度量是渐近符号,有时被称为“大 ??”O 符号。这种符号表示执行给定计算任务所需的资源的估计值,以及当问题的规模变化时相同资源的变化特征。它没有给出需要多少资源的定性指示,而是一种渐进趋势。例如,考虑某个需要(25n2+n+21)个时间步长的特定算法,其中 n 是定义问题所需的位数。在这种情况下,它表示该问题具有由O(n2给出的二次时间复杂度,因为 25 n 2 是到目前为止支配大 n 的那些步骤的最大因子。在将复杂度估计表述为O(n2 时,常数 25 被忽略,因为对于大的 n ,当将该算法与另一个算法的时间复杂度进行比较时,常数的重要性是微不足道的。
渐近符号允许我们比较足够大的 n 的算法,当涉及到分类决策问题的理论时,它是一个重要的工具。这被称为计算复杂性理论,并根据他们最著名的解决方案的资源效率将计算问题分组在一起。这些组被称为复杂性类、,并且有很多这样的组。在本书的上下文中,只考虑了少数几个。当涉及到空间资源时,这些类都是有效的,空间资源在这里被定义为具有空间复杂度≤O(np)的问题类。随着问题的增长,不需要比多项式增加更多的内存。这个类被称为 PSPACE。时间效率以同样的方式定义:一个时间效率的解决方案需要几个与 n 中的多项式成比例的时间步长。当一个解决方案被称为高效时,这通常意味着该解决方案表现出时间效率和空间效率。
在这种情况下,运行时间优势被称为量子增强、量子优势,或者简称为量子加速。证明一个指数级加速被有争议地称为量子优势。
虽然量子计算的圣杯仍然是找到一个可证明的指数加速,但在渐近复杂性方面量子优势的更广泛定义为现实研究开辟了更多的途径,例如:
-
量子算法经常必须与经典采样进行比较,经典采样同样是非确定性的,并且与量子计算有密切关系。
-
定义明确的计算任务
-
这个问题的一个合理的量子算法
-
给任何古典主义竞争者的时间/空间
-
复杂性理论假设,并且可选地
-
一种验证方法,可以使用允许的资源有效地将量子算法与任何经典竞争对手区分开来
这里的似是而非的指的是近期硬件上的理想状态下的,可能包括处理噪音和实验缺陷的需求。
一个复杂性类是一组在某种意义上具有相似复杂性的决策问题,例如,可以用多项式时间或多项式空间解决的问题。
下面是一些主要的经典复杂性类。
-
P :利用多项式时间,经典确定性计算机可以解决的一类问题。
-
BPP :可以被经典随机化计算机使用多项式时间解决的问题,每个输入的错误概率
。
-
NP :如果某个证明者提供一个多项式长度的“证人”,Yes 实例可以在多项式时间内被验证的问题类这一类中的一些问题是 NP 难问题,其中我们知道算法仍然以指数时间运行,但比暴力搜索快得多。一个例子是著名的旅行推销员问题(TSP),我们在第八章中亲自解决了这个问题。还有 NP 完全问题,也就是说 NP 中的任何其他问题都可以在多项式时间内化简为它。因此 NP 完全问题是 NP 中最难的问题。一个例子是可满足性问题:如果证明者给我们一个满意的赋值,我们可以验证一个给定的 n 变量布尔公式是可满足的。因此它是 NP 完全的,可以证明它是 NP 完全的。其他例子有整数线性规划、旅行销售人员(在第七章中有一个真实的实现)、给图表着色的能力等等。
-
PSPACE :经典确定性计算机利用多项式空间可以解决的问题。
所有类别的量子类似物也可以被定义,这是由 Bernstein 和 Vazirani [44]开始的努力。
-
EQP :量子计算机利用多项式时间可以精确解决的一类问题。这个类依赖于计算中允许的一组基本门。
-
BQP :量子计算机可以使用多项式时间解决的问题,每个输入都有错误概率
。这个类被认为是可以被量子计算机有效解决的。
-
量子 NP :一类问题,其中如果某个证明者提供了多项式数量的量子位的“量子见证”,则 Yes 实例可以被有效地验证。对于每个 Yes 实例,应该有一个量子见证以概率 1 通过验证,而对于 No 实例,应该以概率 1 拒绝每个量子见证。这个类也依赖于允许的基本门,并且利用每个输入的错误概率
,得到一个被称为量子梅林-亚瑟(QMA)的类。
-
QPSPACE :量子计算机利用多项式空间可以解决的问题。它和经典的 PSPACE 一样。
量子特征图
经典的机器学习方法需要在不同的空间中处理它们的输入数据,以使其更容易处理,或者因为新的空间提供了便于相关模型分析的属性。支持向量机(SVM)就是一个例子。支持向量机使用线性超平面对数据进行分类。当数据在原始空间中已经是线性可分的时,线性超平面工作得很好;然而,对于许多数据集来说,这不太可能是真的。一种解决方法是将数据转换到一个新的空间,在该空间中,数据通过要素地图呈线性。
设 φ 为一组输入数据, ϑ 为特征空间。那么特征图ω被定义为
输出图上的输出数据点 φ ( x )称为特征向量。ϑ 通常是一个向量空间。转换关系如图 5-3a 所示。虽然在训练输入的原始空间中,来自两个类(红色正方形和绿色圆圈)的数据不能通过简单的线性模型来分离(左),但是我们可以将它们映射到更高维度的特征空间,其中线性模型确实足以定义作为决策边界的分离超平面(右)。有关更多信息,请参见舒尔德和基洛兰[52]。
图 5-3a
量子特征空间变换
在量子特征图的上下文中,特征向量是量子状态。 ϑ 是希尔伯特空间的成员。映射ω:φ→ϑ应用酉变换 U 和变换x→∣φ(x)⟩.通常,在这种情况下, U 是一个变分电路,其转换如图 5-3b 所示。
图 5-3b
具有变分电路的量子特征空间变换
量子嵌入
通常,量子算法被输入产生结果所需的输入数据。这种输入数据必须表示为量子态,才能被量子计算机理解和操作。今天,量子机器学习的大多数应用程序使用量子特征映射来将经典数据映射到希尔伯特空间中的量子状态。这是设计量子算法的一个非常重要的方面,直接影响它们的计算成本。这个过程被称为量子 嵌入,涉及将经典 x 数据点转化为量子电路中的一组门参数,创建量子态∣ψx⟩.更多细节可以在[5]和[47]中找到。
图 5-4
从经典到量子嵌入
如图 5-4 所示,如果我们考虑经典输入数据由 P 个数据点组成,每个数据点具有 R 个特征,那么,对于数据集 D ,
其中, x p 为一个R-维向量, p = 1,2,…, P 。该数据可以嵌入或编码到 n 量子子系统中。这些子系统对于离散变量(DV)量子计算可以是 n 个量子比特,对于连续变量(CV)量子计算可以是 n 个量子比特。
信息编码
信息可以被编码成一个n-量子位系统,由一个状态以各种方式描述。通常,编码方法随着数据集的性质和要解决的问题而变化。对于量子机器学习和数据挖掘,编码的重要性是至关重要的。有相当多的编码方法。这本书主要关注以下内容:基本编码、振幅编码、张量积编码和哈密顿编码。本章着眼于这些编码方法的基本属性。它在未来的章节中对它们进行了扩展,即在章节 6 、 7 和 8 中,我们将探索它们与量子机器学习算法的关系。
根据目前的实践,输入准备有一个经典的部分,称为预处理,它创建了一个可以在量子计算机上处理的电路,以准备量子态。制备量子态的后一部分被称为态制备。在这种情况下,经典部分期间的 p 再处理的过程可以构成由人执行的手动任务或者由程序执行的自动任务。
为了将量子算法的输入准备为量子状态,定义了一个量子电路,它准备相应的状态。该电路可以在传统的预处理步骤中生成,如图 5-5 所示。
图 5-5
量子算法经典输入的准备(改编自[55])
生成的电路被预先添加到算法的电路中,发送到量子设备并执行。生成的电路用目标器件的量子指令语言表示,例如 Cirq、QaSM 或 Quil。因此,要评估给定算法在特定设备上的可执行性,必须考虑正确准备算法输入所需的额外门和量子位的工作量和复杂性。
参考文献[50]讨论了从经典数据生成制备任意量子态所需的门数。在这种情况下,在将经典数据编码成适于由量子算法处理的量子叠加态时,时间和空间复杂度的效率是至关重要的。
图 5-6 显示了经典数据驱动量子计算过程的三个一般执行阶段。
图 5-6
量子计算机执行的三个阶段
用于将经典数据加载到量子态以供量子计算机处理的量子电路是当前研究的活跃焦点。由于不同的量子算法对如何加载经典输入数据并将其格式化为相应的量子态有不同的限制,因此目前在该领域中使用了几种数据加载电路。
采用了各种编码技术,下面将解释其中的一些技术。
基本编码
基础编码是将二进制字符串形式的经典输入数据与量子子系统的计算基础状态相关联的过程。二进制或数字编码是将数据表示为量子位串,而模拟编码以状态的幅度来表示数据。如果数据必须通过算术计算来处理,数字编码是更可取的。另一方面,模拟编码是将数据映射到量子设备的大型希尔伯特空间的首选,这在机器学习算法中经常需要。在[52]中可以找到几种编码方案的简要概述,如基本编码、幅度编码或乘积编码,而[51]讨论了它们在量子机器学习中的使用。关于初始化任意量子态的一般机制的细节在参考文献[51]中给出。
基本编码主要用于在量子算法中必须对实数进行算术运算的时候。这种编码将实数表示为二进制数,然后在计算基础上将它们转换为量子态。
在基本编码中,实数 x ∈ ℝ由 k 个小数位近似,并转换成该近似的二进制表示。
其中 a i ,a—I∈0,1,实数的符号通过添加前导二进制数进行编码,如“0”代表“+”,1 代表 a。因此,实数近似为( n + k + 2)比特和一个( n + k + 2)维量子态。图 5-7 显示了基态的输入编码程序。
图 5-7
基本编码的输入准备(改编自[55])
以下是基本编码的步骤。
-
第一步,对经典数据的预处理计算出二进制近似值asan…, a 0 ,a—1,a—k实数,其中 a
-
通过在量子位 i 上应用门
来产生相应的电路。这个电路创造了代表实数 x 的量子态。
-
所生成的电路被预先加到算法本身的电路上(由图中的酉变换表示),并在诸如来自 IBM 或 Rigetti 的量子计算机之类的量子设备上执行。
每个基本状态的振幅值的唯一目的是以足够高的被测量概率来标记或标示计算结果;他们没有携带其他信息。基本编码方法的量子算法的目标是增加对应于对解进行编码的基本状态的振幅的概率或绝对平方。
任何向量 x = x 1 , x 2 ,…xn∈ℝn都可以通过计算其每个分量 x i 的基编码映射成一个基编码作为一个例子,让我们尝试二进制分数表示,其中区间[0,1]中的每个数由一个 T 位串表示,根据
在这种情况下,要在基本编码中对向量(0.7,0.1,1.0) T 进行编码,首先需要将其转换为二进制序列,其中选择精度为 T = 4 的二进制小数表示,第一位对符号进行编码,如下所示:0 表示 a +, 1 表示 a–。
因此,向量(0.7,0.1,1.0) T 转化为二进制序列 11011 01001 01111,并在基本编码中编码为∣ x ⟩ = ∣ 11011 01001 01111⟩。
当一个数据集 D = { x 1 , x 2 ,…,xp}为二进制嵌入时, D 在二进制编码中的表现为 D 元素的二进制编码状态的均匀叠加。
关于创建这种叠加的时间复杂度为 O ( mn )的算法,请参见参考文献【56】。二进制编码状态的数据集的状态表示的单个元素 D = { x 1 , x 2 ,…,xp}⊆ℝn可以通过下面的量子随机存取存储器(QRAM)表示来访问。
例如,对于一个包含两个例子x1= 10 和x2= 01 的经典数据集,对应的基编码用两个量子位表示∣ x 1 ⟩ = ∣ 10⟩和∣ x 1 ⟩ = ∣ 01⟩,给出
参考文献[57]提出了一种实现这种时间复杂度为O(logp)的 QRAM 的架构。来自ℝ n 的数据可以以复杂度编码在其存储单元中。
振幅编码
振幅编码技术涉及将数据编码成量子态的振幅。虽然量子算法对数据的算术操作不是最重要的,但更紧凑的数据表示是有用的。具体来说,量子器件的大希尔伯特空间在这种编码中得到了恰当的利用。在这个方案中,归一化的经典 N 维 x 数据点由一个 n 量子比特量子态|ψx⟩的振幅表示为,
其中 x i 是 x 的第 i 个元素,| i ⟩是第 i 个计算基态,n= 2n。
这种编码需要 log2T2n 个量子位来表示一个 n 维数据点。
例如,如果我们希望使用幅度编码对四维浮点数组 x = 1.5,0.0,5.0,0.0 进行编码,那么第一步是以下列方式对其进行归一化。
那么对应的幅度编码用两个量子位来表示x范数 为
如果我们考虑前面的经典数据集 D = { x 1 , x 2 ,…,xp},那么如果我们把所有的输入实例 x i 串联在一起成为一个向量,就可以完成它的幅度编码。
其中, c 范数 为归一化常数,归一化准则为| α | 2 = 1。输入数据集在计算基础上表示为
其中, α i 为振幅向量 α 的元素。∣是计算的基态。要编码的振幅数量由 N × P 给出,并且由于一个 n 量子位的系统与 2 个 n 振幅相关联,振幅编码需要N≥log2NP数量的量子位。
在幅度编码期间,可以通过酉变换u=u1⊗u2⊗…⊗uk来创建状态,其中每个 U i 或者是一个单量子比特门或者是一个 CNOT,并且 k 是在这种情况下, x i 可以有不同的数值数据类型(如整数或浮点)。
如果要从| 0⟩基态(即| x ⟩ = U | 0⟩)准备好 x ,那么 2 个 n 门就足够了,如申德和马尔科夫所示[50]。对于满足某些约束的 x ,这种复杂性可以进一步降低。例如,Soklakov 和 Schack [58]给出了单位长度状态的多项式算法,这些状态是特定有界的(即,如果应该避免制备量子态的指数复杂性,则只能制备有限的一组状态)。Schuld 等人[59]提出了一种不一定是单位长度向量的幅度编码,它特别显示了如何通过填充来消除经常做出的假设 n 是 2 的幂。
即使振幅编码仅需要( log 2 n )个量子位来编码x∈Rn),但是这种状态的准备通常是指数级昂贵的。
张量积编码
与振幅编码不同,张量积编码需要 n 个量子位来表示 n 维数据,但就复杂性而言,准备起来更便宜,因为它需要每个量子位旋转一次。这种编码对于在量子神经网络中处理数据是直接有用的,并且在本文中被称为参考文献[5]中的角度编码。图 5-8 显示了张量积编码的过程。
图 5-8
张量积或角度编码的输入准备(改编自[55])
图 5-8 中的过程如下。
设 x = x 1 , x 2 ,…,xn∈ℝn。每个分量 x i 上的张量积编码由下式给出
这给出了以下完整的矢量表示
(5A)
第一章讨论了泡利矩阵和旋转算子。当对泡利 X、Y 和 Z 矩阵求幂时,产生旋转算子,其将布洛赫绕 X、Y 和 Z 轴旋转给定的角度 θ 。
将酉ry(2x)应用于图 5-6 中的矢量∣ x ⟩。
它意味着以下内容。
反过来,前面的等式意味着
(5B)
这里我们从方程 5a中得到原始向量∣ x ⟩。在方程 5 B ,是ry(2xI)与状态∣0⟩在整个 i 范围内的张量积。
预处理步骤可以生成图 5-6 的电路,使得状态准备步骤准备 x 的量子表示。然后,电路可以作为代码生成,预先添加到算法本身,发送到量子计算机,然后在那里执行。
哈密尔顿编码
量子多体系统(将在本章后面讨论)展示了极其多样的相位和物理现象,这构成了物理学及其他许多领域的中心研究对象。哈密顿量 编码通过对量子系统演化中的信息进行编码,使用一种隐含的技术。后面章节中的量子机器学习算法使用哈密尔顿编码和一些其他的量子程序。在本书的剩余部分,我们将通过一个例子驱动的方法来更严格地研究它们。
第四章介绍了一些著名的量子算法,比如 Deutsch 的算法。我们在这一章中介绍一些更多的量子程序。
Deutsch-Jozsa 算法
1992 年的Deutsch–Jozsa 算法[41]启发了 Shor 和 Grover 的工作,可能是最著名的量子算法,并且基于 Deutsch 的算法[37],David Deutsch 和 Richard Jozsa 将其扩展为更令人信服的算法分离,成为现在所谓的 Deutsch-Jozsa 算法。格罗弗 1996 年的算法是用于搜索数据库 42 章和本章后面讨论)。这些想法的共同点是,它们说明了量子信息处理为纯经典术语定义的问题提供解决方案的潜力,这些问题被认为无法通过经典信息处理有效解决。与量子密码术为经典通信所实现的类似,量子算法提供了执行某些经典计算的潜在更好的方法,即使在中间阶段,通信和计算都将依赖于量子资源和处理。
基本上,量子算法有两个主要类别:基于量子傅立叶变换 (QFT)的算法,对应于隐藏子群问题和量子搜索算法的一般实现。Shor 和 Deutsch–Jozsa 算法属于前一类,而后者由 Grover 算法的变体组成。不属于这两类算法的一个例子是量子模拟。在这种情况下,量子计算模拟了一个量子系统,正如费曼最初设想的那样[41]。
模拟哈密顿量的概念是定义量子计算的最方便的起点。量子化谐振子俗称 qumodes 。量子信息有两种常见的编码。通常所知的是基于离散的二能级系统——因此,被称为量子比特。另一种方法依赖于无限维量子系统,如量子化谐振子(也称为 qumodes ),这些更让人想起经典的模拟编码。基于量子位编码的方案通常被称为离散变量(DV)方法。相比之下,那些利用无限维系统以及根据具有连续光谱的变量制备和测量量子信息的可能性的方案被称为连续变量 (CV)方案。
我们在第 1 和 4 章中研究了量子并行性、纠缠和多伊奇算法,以及一些相关的编码示例。一个态中的纠缠量子位| ψ ent ⟩,根据定义,不再是可分的,计算基础由下式给出
(5.1)
其中,λI∈ℂ,对于I= 1…2n和。基底{| 0…00⟩…| 1…11⟩}定义了第 n 个量子位的计算基础。
在方程 5.1 中,使用了以下表示张量积的常用约定:∣x⟩⊗∣y⟩=∣xy⟩.下面在计算基础上的狄拉克矢量表示也非常有用。
(5.2)
我们从纯粹基于量子电路的角度来看 Deutsch 的算法。如果你更熟悉量子力学的基本原理,通过图 5-9a 所示的费曼图中的路径,对同一问题进行另一种可视化可能是有用的。
图 5-9a
多伊奇算法:费曼路径图
为简单起见,让我们使用图 5-9b 中电路所示的简化相位甲骨文模型。
图 5-9b
多伊奇算法:图 4-20 的简化阶段甲骨文模型
以下步骤根据图 5-2a 总结了图 5-2b 的电路的每一步的量子态。
-
输入是∣0⟩
-
-
-
在表达式(1) f (0) 中,是一个称为量子位的全局相位的常数因子。从测量的角度来看,全局相位可以忽略,因为量子态的全局相位是不可检测的。在量子力学中,只有能量差,而不是物理系统动力学的绝对值,才是重要的。一个经典的类比是电子在导线中的运动,在导线中只测量电压差,而不是绝对值。这说明如果 f (1) = f (0)最终测量的结果总是 0,如果f(1)≦f(0)最终测量的结果总是 1。
Deutsch 的算法可以用所谓的相位反冲来很好地解释。相位反冲方案考虑输入| x ⟩|−⟩,for x ∈ {0,1},并将 Oracleuf应用于该输入。对于∣ ψ ⟩州来说,这给
(5.3)
等式 5.3 可以被认为是针对单输入的多伊奇算法的一般情况(参见第四章)。对于方程 5.3 ,可以有两种不同的情况: f ( x ) = 1 或者 f ( x ) = 0。如果 f ( x ) = 0,等式 5.3 给出
这表明输入| x ⟩|−⟩在 U f 的作用下保持不变。相反,如果 f ( x ) = 1,则等式 5.3 给出
这表示输入| x ⟩|−⟩.增加了一个相位(1)这两种情况可以用下面的表达式来概括。
(5.4)
方程 5.4 是相位反冲方程。
Deutsch 算法的解决方案是精确的,因为它产生错误概率为零的正确答案,并且它只需要一个 oracle 查询,因此它的时间复杂度为常数 O (1)。该算法采用了 n + 1 个量子位,给出了线性内存消耗 O ( n )。
当 f : {0,1} → {0,1}作用于一个不太有趣的单输入位时,Deutsch 的算法工作得很好。感兴趣的是更一般的场景,其涉及用于确定函数 f : {0,1} n → {0,1}的性质的量子算法的设计和分析,该函数作用于多个输入值。这有可能提供超越任何经典确定性解决方案的指数级加速。
Deutsch-Jozsa 算法是 Deutsch 算法的 n 位推广。这个算法和 Deutsch 的算法一样,确定一个函数 f ( x )对于多个输入值是平衡的还是常数。如果 f ( x )不变,则 x 的所有输入值的输出都相同(即 f ( x )始终为 0,或者 f ( x )始终为 1)。如果 f ( x )平衡,则对于一半的输入, f ( x ) = 0,对于另一半的输入, f ( x ) = 1。
在经典计算期间,通常在最坏的情况下,需要查询(2n—1+1)次,需要超过一半的域{0,1} n 的输入,以确定 f ( x )是平衡的还是恒定的。当使用随机化算法时,该练习可能会在个查询的结果上实现有界误差 ε 。
对于一个量子解决方案,图 5-10 中显示了一个费曼图,便于跟踪量子态。
图 5-10
Deutsch-Jozsa 算法:费曼路径图
下面的步骤总结了图 5-3 中每一步的量子态,这类似于 Deutsch 算法的费曼图中的路径。
-
输入状态是∣ψ0⟩=∣0⟩⊗n
-
-
步骤 3 的扩展给出了步骤 4。
其中, H 照常是哈达玛变换。
类似于图 5-11 的电路用于一般量子解的 Deutsch-Jozsa 算法。
图 5-11
Deutsch-Jozsa 算法的量子电路
在图 5-11 中,一般的 Deutsch-Jozsa 算法是通过以下步骤推导出来的。
-
输入状态为∣ψ0⟩=∣0⟩⊗n⊗∣1⟩
-
Then, the Hadamard gates are applied, giving
-
The state from step 2, after analysis, gives
-
After applying Hadamard transformation to all the n qubits, we have
(5.5)
前面的步骤给出了以下内容。
最后,测量状态∣0⟩⊗n的概率由下式给出
如果f(I)=常数,那么我们得到相长干涉,这就得到p(|0⟩⊗n)= 1。如果 f ( i )是平衡的,那么相消干涉给我们的概率是 0。
总之,Deutsch-Jozsa 算法之所以有效,是因为以下原因。
在案例 1 中,神谕是常数。在这种情况下,就全局相位而言,它不会影响输入量子位。H 门是它自己的反向门,因此
在第二种情况下,甲骨文是平衡的。在这种情况下,在步骤 2 之后,输入寄存器是计算基础中所有状态的相等叠加,并且相位反冲将负相位添加到这些状态的一半。
(5.7)
这表明查询 oracle 后的量程状态与查询 oracle 前的量程状态正交。同样地,应用 h 门给出了与全零∣000…0⟩态正交的量子态,这意味着 al-零态不应该被测量。
Deutsch-Jozsa 算法的量子查询复杂度。求解多伊奇问题时最小化的代价函数是应用于 U f 的量子查询的数量。这是量子查询复杂性模型的一个例子,许多量子算法都是用它开发的。在量子查询复杂度的研究中,给一个黑盒 U f 实现函数 f ,询问对 U f 的最小查询次数是多少,以确定 f 的一个期望性质。注意,计算该属性的量子算法可以包括例如 999999999 个量子门;如果它只包含对 U f 的两个查询,那么我们认为算法的代价为 2(即所有“非查询”操作都被认为是免费的)。
有 Cirq 的 Deutsch-Jozsa
第四章包括对谷歌开源量子计算库 Cirq 的实际介绍,其中大部分内容都局限于构建电路、门,最后是 Deustch 的算法。本章尝试用 Cirq 构造一个两比特 Deutsch-Jozsa 算法。Deutsch-Jozsa 算法可以使用对 oracle 的单个查询来区分常数和平衡函数。这个练习的目标是写一个可以区分这些的量子电路。
我们首先导入所需的库,如清单 5-1a 所示,用于可以从该书网站下载的Deutsch-Jozsa_cirq.ipynb
Jupyter 笔记本。
import cirq
import numpy as np
import matplotlib.pyplot as plt
Listing 5-1aLibraries for Deutsch-Jozsa_cirq.ipynb
在关于 Deutsch 算法的讨论中,您看到了一个输入位的布尔函数要么是常数,要么是平衡的。然而,我们也从 Deutsch-Jozsa 算法部分看到,对于两个输入位的布尔函数,不是所有的函数都是常数或平衡的。有两个常量函数( x 1 、 x 2 ) = 0、 f ( x 1 、 x 2 ) = 1、平衡函数。下面的代码给出了这些函数的操作,其中我们取两个输入量子位并计算第三个量子位中的函数。
# Define three qubits to use.
q0, q1, q2 = cirq.LineQubit.range(3)
# Define the operations to query each of the two constant functions.
constant = (
[],
[cirq.X(q2)]
)
# Define the operations to query each of the six balanced functions.
balanced = (
[cirq.CNOT(q0, q2)],
[cirq.CNOT(q1, q2)],
[cirq.CNOT(q0, q2), cirq.CNOT(q1, q2)],
[cirq.CNOT(q0, q2), cirq.X(q2)],
[cirq.CNOT(q1, q2), cirq.X(q2)],
[cirq.CNOT(q0, q2), cirq.CNOT(q1, q2), cirq.X(q2)]
)
Listing 5-1bInput States for Deutsch-Jozsa_cirq.ipynb
接下来,我们为量子电路定义一个函数,它可以在两个比特上区分常数和平衡函数。
# Define a function
def deJo_circuit(oracle):
# Phase kickback trick.
yield cirq.X(q2), cirq.H(q2)
# Get an equal superposition over input bits.
yield cirq.H(q0), cirq.H(q1)
# Query the function.
yield oracle
# Use interference to get result, put last qubit into |1>.
yield cirq.H(q0), cirq.H(q1), cirq.H(q2)
# Use a final OR gate to put result in final qubit.
yield cirq.X(q0), cirq.X(q1), cirq.CCX(q0, q1, q2)
yield cirq.measure(q2)
Listing 5-1cFunction Definition for Deutsch-Jozsa_cirq.ipynb
然后,我们通过运行以下单元来验证我们的 Deutsch-Jozsa 电路,该单元模拟所有 oracles 的电路。
simulator = cirq.Simulator()
print("\nResult on constant functions:")
for oracle in constant:
result = simulator.run(cirq.Circuit(deJo_circuit(oracle)), repetitions=10)
print(result)
print("\nResult on balanced functions:")
for oracle in balanced:
result = simulator.run(cirq.Circuit(deJo_circuit(oracle)), repetitions=10)
print(result)
Listing 5-1dRun Cirq Simulator to Verify Deutsch-Jozsa_cirq.ipynb
下面的输出显示,对于不同的 oracles,该电路按预期工作。
正如 Deutsch 的算法使用一位的情况一样,对于常数函数,我们总是测量 0,对于平衡函数,我们总是测量 1。
量子相位估计
相位估计是一个量子例程,帮助找到酉矩阵的特征值 U 应用于作为受控门的量子寄存器。相位估计使用 QFT 来写入以振幅的相位编码的信息。通常,量子机器学习 (QML)算法使用这种技术来评估包含 QML 训练集信息的算子的特征值。
上一节快结束时,我们注意到 Deutsch 算法和 Deutsch–Jozsa 算法中的最后一个 Hadamard 门用于获取状态相对相位中的编码信息。哈达玛门是自反的(参考方程 5.6 和 5.7 ),因此反其道而行之;也就是说,它可以将信息编码到相位中。
让我们来看看我们对方程 5.5 的哈达马状态的推导,然后考虑一个 h 门作用于基态∣ x ⟩,对于 x ∈ {0,1},那么,对于 n = 1,从方程 5.5 ,
(5.8)
哈达玛门可以被认为是保存了关于基态∣0⟩和∣1⟩.之间的相对相位的值的编码信息由于哈达玛门是自反的,将其应用于等式 5.8 右侧的状态,我们又回到了状态∣ x ⟩,
(5.9)
因此,在方程 5.9 中,哈达玛门可以被认为是解码关于相位中编码的 x 值的信息。同样,如果我们考虑h⊗n作用于一个 n 量子比特基态∣ x ⟩,那么我们得到等式 5.5 的等价式,即
(5.10)
因此,n-量子比特哈达玛变换可以被解释为将关于∣ x ⟩的值的编码信息处理成相位(1)x。y∣y⟩.注意(1) x 。 y 是一种非常特殊形式的阶段。一般来说,相位是一个形式为e2πIω的复数,其中 ω ∈ {0,1}为任意实数 ω 。这允许在相位为 1 时。一般来说,n-量子位哈达玛变换不可能完全访问以比相位更一般的方式编码的信息。然而,可以编写一个特殊的程序,允许哈达玛门确定相位编码的信息。
设∣ ψ n ⟩, n = 1,2,…, n 为酉算子 U 的特征向量。 U 定义在∣ψn⟩构成正交基的希尔伯特空间中。受控 U 对特征向量的酉运算给出,
(5.11)
其中 ω ∈ {0,1}为任意实数 ω 。等式 5.12 成立,因为酉算子的 e 特征值是相位。
为了形象化方程 5.12 ,我们可以考虑由下式给出的初始状态
(5.12)
为了进一步分析表达式 5.12,我们需要考虑基本编码。
考虑到 j 位串为 0 到(2j1)的整数,∣ y ⟩参考∣ y ⟩标注的基态,其中 y 为整数 y 的二进制编码。查看等式 5.12 ,确定值,或者至少是相位参数 ω 的适当估计,必然会有兴趣找到 ψ 。这就是相位估计问题【43】。为了解决这个问题,相位估计例程允许以下变换
(5.13)
其中是对 ω 的估计。等式 5.13 暗示正交∣ψn⟩的特征值对于 ω * j * 如下。
(5.14)
我们需要记住,既然是 U 酉,λj必然有 1 的量级。我们从二进制定义 ω 开始,
同样, ω 的二次方倍数可以写成
(5.16)
对于方程 5.12 的相位部分,我们也知道 e 2 πik = 1 对于任意整数 k ,我们有
(5.17)
现在,如果我们有一个给定的输入状态,并考虑一个量子电路来确定对 ω 的估计,那么,对于一个一量子位的输入状态,其中 j = 1,我们有 ω = 0。p1 及以下由等式 5.5 得出。
(5.18)
求解相位估计的电路如图 5-12 所示。
图 5-12
相位估计电路
在图 5-12 中,经过受控的 U 变换后,特征向量保持不变,特征值 λ 包含在第一个量子位的相位中。在第一量子位上的哈达玛变换将信息转换成可以测量的振幅。换句话说,参考等式 5.9 和 5.18 ,确定p1 的值并估算 ω ,我们有
(5.19)
既然你已经完成了一个单量子比特输入的相位估计练习,让我们来看看一个两量子比特的状态。
(5.20)
等式 5.20 表明p2 可以通过以与等式 5.19 中相同的方式对第一个量子位应用哈达玛门来确定。但是还需要确定 p 1 ,在那个过程中涉及到第二个量子位。如果 p 2 = 0,那么第二个量子位处于状态,由此可以确定 p 1 。然而,如果 p 2 = 1,那么就有一个挑战,因为前面的直接方法将不起作用。为了实现它,我们需要应用相位旋转算子(参考等式 1。15 。
其中指数中的 0.01 以 2 为基数。换句话说,0.01 = 2—2。Rθ的倒数由下式给出
(5.21)
因此,对于 p 2 = 1,我们考虑应用一个Rθ—1的效果。
(5.22)
现在,如果我们将阿达玛门应用于等式 5.22 的结果,那么我们可以确定 p 1 。如果 p 2 = 1 或 p 2 = 0 是决定我们是在对第二个量子位应用Rθ-1变换之后还是之前应用哈达玛门的因素。在我们将阿达玛门应用于第一个量子位之后,第一个量子位的状态是∣p2⟩.
可以推广相位估计的方法。对于一个和两个量子位输入所采取的相同步骤可以用于 p 3 、 p 4 …并且有条件地旋转 p 3 、 p 4 …对于 n 量子位上的模拟电路,估计形式为 ω = 0 的相位。p1p2p3…,电路的输出由∣pn…p2p1⟩.给出添加一些门来颠倒量子位的顺序给了我们一个有效的电路,它实现了
(5.23)
如果我们以相反的顺序在逻辑上标记方程 5.23 中的量子位,那么我们得到
(5.24)
等式 5.24 是通过反向应用相位估计电路实现的酉变换。“反向”应用电路意味着用它的反向门替换每个门,并以相反的顺序运行电路。方程 5.24 类似于科学和工程中广泛使用的经典离散傅立叶变换 (DFT)(见附录 A)。DFT 将向量 X 作为大小为 N 的输入,并输出向量 Y = WX ,其中 W 是傅立叶矩阵。QFT 被定义为使用 DFT 值确定的两个量子态之间的变换。如果X= {XI}和Y= {YI}是向量使得 Y = WX ,那么 QFT 被定义为变换。
相位估计程序使用 QFT。QFT 可以被解释为相位估计操作的逆操作,并且向后应用相位估计电路给出了用于执行 QFT 的有效电路。
一个经典的 DFT 过程通过下面的变换将一个实向量映射到另一个向量
在O(n2n)步骤中,其中
是跨越{1…2 * n * 的一组实数。
其中 k = 1,2,3…2n。
QFT 将振幅对φk编码的量子态映射到振幅对 y k 编码的量子态。
(5.25)
其中,在 O (2 * n * 步骤中。
方程 5.25 中的 j 上的和由于量子傅立叶变换应用于仅处于一个计算基态的状态而消失。基态∣ j ⟩对应经典情况,其中一个 φ j 不为零,其余为零。
图 5-13 显示了用 Quirk [6]生产的八量子位 QFT 电路的电路表示。
图 5-13
八量子位量子傅里叶变换电路(用 Quirk [6]制作)
等式 5.25 的运算要求量子位获得二进制串的第一个 b 位,以概率 1ε编码本征态。在量子相位估计过程中使用 QFT 的逆过程。
为了获得 ω 的估计,经由相位估计技术,使用酉 QFT 的逆,其中 U * f 是量子傅立叶变换。基于状态∣0⟩、∣ 1⟩、…∣m*1⟩应用的逆 QFT 状态由下式给出
(5.26)
综上所述,给定一个酉门 U ,则 U 的一个特征向量∣ψ??n⟩由u|ψ|n⟩=λ|ψn⟩.给出目的是找到特征值 λ 的近似值(或估计值)。由于 U 是酉的,所以 λ 的大小一定是 1,我们可以设λ=e2πIω,其中 ω ∈ {0,1}和 ω = 0。p1p2p3…高达 n 位的精度。目的是找到相位 ω 的估计值。
然后,通过以下步骤给出相位估计算法。
-
用| 0n⟩|ψ⟩.发起
-
对第一个 n 个量子位应用h⊗n??【⊗】I 得到n= 2n从而得到
。
-
根据第一个寄存器给定的次数,将 U 应用于第二个寄存器。换句话说,套用 map |k⟩|ψ⟩→|k⟩uk|ψ⟩=e2πIωk|k⟩|ψ⟩.经过这一步,第一个 n 个量子位处于
状态,其中 U * f 为傅里叶变换。因此,傅立叶逆变换以概率 1 提供了∣2nω⟩=∣p1…p*2⟩。
-
对第一个寄存器应用傅里叶逆变换
并测量结果。
如果 ψ 不能精确地以 n 位的精度写入,则可以表明该过程仍然能够以高概率提供对 ψ 的良好的 n 位近似。
用 Rigetti 森林进行量子编程
ri getti Computing2是一家总部位于加州伯克利的量子计算机制造商,由他们自己的超导量子处理器提供动力。该公司还开发了一个名为量子云服务(QCS)的云平台,通过该平台,他们的机器可以集成到任何公共、私有或混合云。Rigetti 的计算环境由一个名为 Forest 的 SDK 提供支持,这是一个用于量子/经典计算的全栈编程和执行环境。
森林可以开发量子/经典混合计算的算法,并了解量子计算机和算法的工作原理。可以使用运行在云中的量子虚拟机或 QVM 在量子位上模拟这些算法。还可以使用执行活动量子系统的简单函数调用与真实量子芯片进行交互。
以下是一些你应该知道的术语(也参见 Rigetti [61]的文档)。
-
pyQuil :帮助编写和运行量子程序的开源 Python 库。源代码托管在 GitHub 的
http://github.com/rigetti/pyquil
。 -
Quil :量子指令语言标准。用 Quil 编写的指令可以在量子抽象机(QAM)的任何实现上执行,如量子虚拟机(QVM)或真实的量子处理单元(QPU)。关于 Quil 的更多细节可以在白皮书“实用量子指令集架构”[71]中找到。
-
QVM :量子虚拟机是量子抽象机在经典硬件上的开源实现。QVM 可以让你用一台普通的计算机模拟一台小型量子计算机,并执行 Quil 程序。QVM 可以在 GitHub 的
https://github.com/rigetti/qvm
找到,可以在标准笔记本电脑上运行。我们用 QVM 做下一个练习。 -
QPU : 量子处理器。这是指可以运行量子程序的物理硬件芯片。
-
Quil 编译器:编译器 quilc 将为一个 QAM 编写的 Quil 编译成另一个 QAM。根据其支持的指令集体系结构,我们的开源编译器采用任意的 Quil 并为给定的 QAM 编译它。在
https://github.com/rigetti/quilc
的 GitHub 上找到 quilc。 -
Forest SDK : Rigetti 的软件开发套件,针对作为协处理器运行的近期量子计算机进行了优化,与传统处理器协同工作,运行混合量子经典算法。关于近期量子计算机可解决问题的参考,参见“NISQ 时代及以后的量子计算”[68]。
Forest SDK 是一个全面的语言套件,允许定义电路的能力,提供模拟器,收集量子算法,以及其他重要的组件。有关在各种操作系统上设置它的信息,请参考位于https://pyquil-docs.rigetti.com/en/stable/
【61】的森林文档。下面是 Ubuntu Linux 18.04 LTS 版的设置概要。建议 Linux 环境中的所有工作都在虚拟环境中完成。
安装 QVM
为了充分利用 Rigetti Forest SDK,我们需要 pyQuil、QVM 和 Quil 编译器。在写这本书的时候,pyQuil 2.0 是 Rigetti 的库,用于在 Rigetti Forest 平台上生成和执行 Quil 程序。在安装之前,建议激活 Python 3.6+虚拟环境。然后,使用pip
安装 pyQuil(对于 Ubuntu,您可能需要sudo
命令)。
$ pip install pyquil
或者
$ sudo pip install pyquil
对于任何现有的 pyQuil 环境,运行升级总是好的。
pip install --upgrade pyquil
在下一步中,需要如下下载 QVM 和 Quil 编译器。
Forest 2.0 可下载 SDK 预览版包含以下内容。
-
Rigetti 量子虚拟机(
qvm
)允许 Quil 程序的高性能模拟 -
Rigetti Quil 编译器(
quilc
)允许将 Quil 程序编译和优化到本机门集
QVM 和编译器打包成程序二进制文件,可以通过命令行访问。两者都支持直接的命令行交互,以及一个服务器模式。使用 pyQuil 时,服务器模式是必需的。
森林 SDK 可以在 https://qcs.rigetti.com/sdk-downloads
下载。同一个下载站点提供了 Windows、macOS、Linux(.deb)、Linux(。rpm)和 Linux(裸机)。
在 Linux 上安装 QVM 和编译器
-
通过点击 SDK 下载页面上适当的链接来下载发行版(对于 Ubuntu,下载 Debian 的包)。
https://qcs.rigetti.com/sdk-downloads
-
解压缩
tarball
并切换到该目录。tar -xf forest-sdk-linux-deb.tar.bz2 cd forest-sdk-2.0rc2-linux-deb
-
从同一个目录中,运行以下命令。
图 5-14
在虚拟环境中启动 QVM 服务器
-
成功安装后,您应该能够运行以下两个命令。
qvm --version quilc --version
-
SDK 安装成功后,打开一个终端窗口,切换到安装 SDK 的同一个虚拟环境,用
qvm -S
命令.
在服务器模式下启动 QVM,这应该会启动 QVM 服务器,如图 5-14 所示,这里的虚拟环境称为qml
。
sudo ./forest-sdk-2.0rc2-linux-deb.run
图 5-15
在虚拟环境中启动 Quilc 服务器
-
保持 QVM 的终端运行,打开一个新的终端,切换到同一个虚拟环境,用
quilc -S
命令在服务器模式下启动 Quilc。quilc -S
运行在qml
虚拟环境中如图 5-15 所示。 -
若要卸载林 SDK,请输入以下内容。
sudo apt remove forest-sdk
此时,你应该至少有两个终端窗口在后台打开并运行:一个用于qvm
,一个用于quilc
。
如果在同一个虚拟环境中没有安装 Jupyter notebook 或其他 Python 库,请使用下面的命令。
$ python3 -m pip install -U jupyter matplotlib numpy pandas scipy scikit-learn
下一步是启动 Jupyter 笔记本。打开一个新的第三终端窗口,切换到同一个虚拟环境,通过键入以下命令启动 Jupyter notebook。
$ jupyter notebook
这将在您的浏览器中打开一个 Jupyter 笔记本会话。保持此终端窗口打开。所以,在这个过程的最后,三个不同的终端窗口从同一个虚拟环境中运行:一个用于qvm
,一个用于quilc,
,一个用于 Jupyter notebook
。
图 5-16
QVM、Quilc 和 Jupyter 笔记本电脑在同一个虚拟环境中运行
QVM、Quilc 和 Jupyter 笔记本终端的最终状态应该类似于图 5-16 所示的屏幕截图。
pyQuil [72]提供了一个函数来确保本地qvm
和quilc
当前正在环境中运行。为了确保两者都可用,我们需要执行from pyquil.api import local_forest_runtime
,然后使用local_forest_runtime()
。这将使用子流程启动qvm
和quilc
实例,如果它们还没有启动的话,如清单 5-2 所示。
from pyquil import get_qc, Program
from pyquil.gates import CNOT, Z
from pyquil.api import local_forest_runtime
prog = Program(Z(0), CNOT(0, 1))
with local_forest_runtime():
qvm = get_qc('9q-square-qvm')
results = qvm.run_and_measure(prog, trials=10)
Listing 5-2pyQuil Code to Verify qvm and quilc Are Available
对象允许我们构建一个 Quil 程序。get_qc()
将我们连接到一个QuantumComputer
对象,它指定了我们的程序应该在什么对象上运行(参见 https://pyquil-docs.rigetti.com/en/stable/qvm.html#qvm
)。()从pyquil.gates
模块导入所有*门,这允许我们向程序添加操作。
清单 5-3a 给出了使用 QVM 在 pyQuil 中引入一些操作的代码,并构建了一个三量子位量子傅立叶变换 (QFT)的描述。最初,我们导入一些库,并验证从 Jupyter 笔记本可以访问 QVM 和 Quilc 服务器。如果这一步没有出现任何错误,那么我们就可以开始了。
from pyquil import Program, get_qc
from pyquil.gates import *
import cmath
import matplotlib.pyplot as plt
import numpy as np
from pyquil.api import ForestConnection
from pyquil.api import WavefunctionSimulator
from pyquil.api import QVMConnection
from qutip import Bloch
from tempfile import mkdtemp
qvm = QVMConnection()
# Verify QVM and Quilc are available
from pyquil import get_qc, Program
from pyquil.gates import CNOT, Z
from pyquil.api import local_forest_runtime
prog = Program(Z(0), CNOT(0, 1))
with local_forest_runtime():
qvm = get_qc('9q-square-qvm')
results = qvm.run_and_measure(prog, trials=10)
Listing 5-3aLibraries for Quantum Fourier Transform (QFT) qft_forest.ipynb
对于第一个测试,让我们生成一个状态。
# Test
qvm = QVMConnection()
hello_qubit = Program()
print(qvm.wavefunction(hello_qubit))
Listing 5-3bLibraries for Quantum Fourier Transform (QFT) qft_forest.ipynb
这给出了以下输出。
作为第二个测试,让我们首先构建一个响铃状态并运行程序。量子位 0 被初始化为具有哈达玛 H 门的叠加态。然后用 CNOT 门在量子位 0 和 1 之间产生一个纠缠态。然后运行程序。
# construct a Bell State program
p = Program(H(0), CNOT(0, 1))
# run the program on a QVM
qc = get_qc('9q-square-qvm')
result = qc.run_and_measure(p, trials=10)
print(result[0])
print(result[1])
Listing 5-3cTest with Bell State qft_forest.ipynb
贝尔状态的代码给出了以下输出。
QC
是模拟量子计算机。run_and_measure
告诉 QVM 运行程序,执行一个测量来压缩状态,并返回结果。trials
是指程序运行的次数。
对run_and_measure
的调用向已经启动的两个服务器(qvm
和quilc
)发出请求。调用 Quilc 服务器实例将 Quil 程序编译成本机 Quil,调用 QVM 服务器实例模拟并返回程序十次测量结果。如果您打开运行您的服务器的终端窗口,您应该看到输出打印到控制台关于我们提出的请求。
下一步,做量子傅立叶变换。任务是将 QFT 应用于对应于我们想要计算 DFT(离散傅立叶变换)的序列的状态的幅度。为此,我们需要三个量子位来转换一个 8 位序列。
需要计算的序列是 01000000,所以初始状态是|001⟩.对于具有多于一个 1 的位串,需要所有选定状态的相等叠加;例如,01100000 是|001⟩和|010⟩.的等量叠加一个 x 门应用于第零个量子位建立了|001⟩态。可以通过用Wavefunction Simulator
计算其波函数来验证这一点。我们需要添加一些“虚拟”量子位,否则,波函数将只为量子位 0 返回一个二元向量。这显示在清单 5-3d 中。
# Quantum Fourier Transform
state_prep = Program(X(0))
qft = Program()
qft += H(0)
qft += CPHASE(π/2, 1, 0)
qft += H(1)
qft += CPHASE(π/4, 2, 0)
qft += CPHASE(π/2, 2, 1)
qft += H(2);
# Add dummy qubits
from pyquil.api import WavefunctionSimulator
add_dummy_qubits = Program(I(1), I(2)) # The identity gate I has no affect
wf_sim = WavefunctionSimulator()
wavefunction = wf_sim.wavefunction(state_prep + add_dummy_qubits)
print(wavefunction)
Listing 5-3dState Preparation for Quantum Fourier Transform (QFT) qft_forest.ipynb
这给出了以下输出。
接下来,它被定义为一个函数 qft1,来制作一个三量子比特的 qft 量子程序。该算法在本章前面已有描述。该实现由 Hadamard 和 CPHASE 门组成,并带有一个用于位反转校正的交换门。qft1
函数不计算 QFT,而是制作一个量子程序来计算量子位q0, q1,
和q2
的 QFT。
# 3 qubit QFT Program: DFT of [0, 1, 0, 0, 0, 0, 0, 0], using pyQuil:
from math import pi
def qft1(q0, q1, q2):
p = Program()
p += [SWAP(q0, q2),
H(q0),
CPHASE(-pi / 2.0, q0, q1),
H(q1),
CPHASE(-pi / 4.0, q0, q2),
CPHASE(-pi / 2.0, q1, q2),
H(q2)]
return p
print(qft1(0, 1, 2))
Listing 5-3eState Preparation for QFT qft_forest.ipynb
代码片段将以下内容作为输出返回。
接下来,我们运行 QFT。
compute_qft_prog = state_prep + qft1(0, 1, 2)
wavefunction = wf_sim.wavefunction(compute_qft_prog)
print(wavefunction.amplitudes)
Listing 5-3fExecute Quantum Fourier Transform (QFT) qft_forest.ipynb
这将返回以下输出。
在最后一步中,我们运行清单 5-3g 来验证使用快速傅立叶逆变换(FFT)的 QFT 运行。
# Verify qft by inverse FFT
from numpy.fft import ifft
ifft(wavefunction.amplitudes, norm="ortho")
Listing 5-3gVerify QFT with Inverse FFT qft_forest.ipynb
如果我们忽略 1e-17 级的项,就会产生下面的数组作为输出,给出[0,1,0,0,0,0,0,0],这是我们的输入。
展望未来,我们将使用更多来自 Rigetti Forest 的示例,尤其是当我们在未来章节中查看变分算法(如 Max-Cut)时。
测量和混合状态
测量在第一章中进行了说明。本节从动手编程的角度来看这个问题。测量是量子力学中的一个核心概念。考虑它的一种方式是作为一个概率分布的样本。作为一个有很多结果的随机变量,每个结果都是以一定的概率产生的。除非对系统进行测量,否则它会保持叠加态,因为一般来说,测量行为会破坏量子态。
测量是量子系统和我们现有的经典世界之间的核心联系。自然界中的量子态不能被直接观察到——只有在对它们的状态进行测量后,才能记录下关于它的统计数据。除了量子世界和经典世界之间明显的界限之外,还有一个微妙的现实:一个量子系统与其周围的环境相互作用,除非它完全和完美地与之隔离。这种相互作用导致混合态的存在。在一定限度内,混合态恢复经典概率,给出量子态的解释。量子测量是通过让一个封闭的量子系统以一种受控的方式与一个外部系统相互作用来完成的,从该外部系统可以恢复量子系统的测量状态。
在量子力学中,测量状态的基本原理包括 bra 和 ket 。作为一个提醒,一个胸罩被⟨ψ|命名为某种量子态∣ ψ ⟩.他们一起形成了 bra-ket 或狄拉克符号。一个胸罩是一个胸罩的共轭转置,反之亦然。这也意味着胸罩是一个行向量。Qiskit 中的代码如本书代码库中的清单 5-4a 所示。
import numpy as np
zero_ket = np.array([[1], [0]])
print("|0> ket:\n", zero_ket)
print("<0| bra:\n", zero_ket.T.conj())
Listing 5-4aBra and Ket in Qiskit MeasMixedSt_qiskit.ipynb
这给出了以下输出。
我们也可以尝试胸罩和胸衣,这是一个矩阵;本质上,两个向量的外积:|0⟩⟨0|,如代码清单 5-4b 所示。
zero_ket.dot(zero_ket.T.conj())
Listing 5-4bBra and Ket in qiskit MeasMixedSt_qiskit.ipynb
这进而给出了一个矩阵数组作为输出。
这个输出看起来很熟悉,因为它是规范基的第一个元素的投影(见第一章)。总的来说,|𝜓⟩⟨𝜓|将成为|𝜓⟩.的投影仪如果我们取一些其他的量子态|𝜙⟩,并对其应用|𝜓⟩⟨𝜓|矩阵,我们得到|𝜓⟩⟨𝜓|𝜙⟩.最右边的两个术语是 bra 和 ket,这表明它是点积,是|𝜙⟩和|𝜓⟩.之间的重叠由于这是一个标量,它缩放最左边的项,即 ket |𝜓⟩,所以实际上,|𝜙⟩投影到了这个向量上。
量子力学中的测量通常会产生一个由算符驱动的随机变量。测量理论是一个丰富而活跃的研究领域,这意味着仍有许多未知和问题有待回答。然而,我们今天拥有的大多数量子计算机只实现了一个非常特定的测量,这使得事情简单了很多。这种测量是在规范的基础上进行的。换句话说,测量包含两个投影,|0⟩⟨0|和|1⟩⟨1|,这种测量可以应用于量子计算机的任何量子位。
第一章解释了如何在矢量上应用投影。为了得到标量值,我们需要在左边添加一个胸罩。例如,对于|𝜓⟩,我们得到⟨𝜓|0⟩⟨0|𝜓⟩.的标量这被称为操作者|0⟩⟨0|.的期望值
为了将理论放在上下文中,可以在叠加态上进行投影|0⟩⟨0|,即哈达玛变换,其可以表示为列向量
。这显示在清单 5-4c 中。
ψ = np.array([[1], [1]])/np.sqrt(2)
Π_0 = zero_ket.dot(zero_ket.T.conj())
ψ.T.conj().dot(Π_0.dot(ψ))
Listing 5-4cProjection MeasMixedSt_qiskit.ipynb
它给出了以下输出
那正好是叠加态|0⟩对应的概率振幅的绝对值的平方的一半。下面是第一章中一个索赔的数学形式:给定一个状态|ψ⟩=α0|0⟩+α1|1⟩,我们以概率|αI|2, 这是天生法则的一种体现。玻恩规则提供了量子理论的数学形式和实验之间的联系。因此,它是与几乎所有量子物理预言相关的最重要的理论之一。在科学史上,与海森堡的测不准关系一样,玻恩法则通常被视为非决定论进入基础物理学的转折点。这正是量子模拟器中实现的内容。这里描述的是模拟器中的测量。
对于与哈达玛门的相等叠加(使用 Jupyter 笔记本中的量子电路章节 4 ,我们需要应用测量并观察统计,如清单 5-4d 所示。
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit import execute
from qiskit import BasicAer
from qiskit.tools.visualization import plot_histogram
backend = BasicAer.get_backend('qasm_simulator')
q = QuantumRegister(1)
c = ClassicalRegister(1)
circuit = QuantumCircuit(q, c)
circuit.h(q[0])
circuit.measure(q, c)
job = execute(circuit, backend, shots=100)
plot_histogram(job.result().get_counts(circuit))
Listing 5-4dMeasurment Statistics MeasMixedSt_qiskit.ipynb
输出显示在图 5-17a 的柱状图中。如果是运行几次,那就是一个随机输出。图 5-17b 是清单 5-4d 第二次运行的示例。
图 5-17b
测量统计数据输出的随机性
图 5-17a
测量统计的输出
输出显示,大约一半的结果约为 0。然而,即使测量有一个随机的结果,一旦它被执行,量子态就在相应的基矢中。即叠加被破坏。这被称为波函数的坍缩。测量的这一性质是许多正在进行的辩论和研究结果的主题,关于它如何发生以及为什么发生,但重要的是,我们可以在测量后很容易地“计算”相应量子态的状态。然而,将状态投影到基向量是不够的,因为它不会被规范化,所以我们必须将其重新规范化。
例如,如果我们在测量叠加后观察到零,测量后的状态在清单 5-4e 中给出。
ψ = np.array([[np.sqrt(2)/2], [np.sqrt(2)/2]])
Π_0 = zero_ket.dot(zero_ket.T.conj())
probability_0 = ψ.T.conj().dot(Π_0.dot(ψ))
Π_0.dot(ψ)/np.sqrt(probability_0)
Listing 5-4eMeasurment Statistics MeasMixedSt_qiskit.ipynb
它有以下输出。
简单地说,我们得到一个由列向量给出的|0⟩。将两个测量值按顺序放在同一个量子位上,就可以看到结果。第一次测量是随机的,但是第二次测量是确定的,因为在第一次测量之后在计算基础上没有叠加。因此,第二次测量总是给出与第一次相同的结果。下面是我们 Jupyter 笔记本的清单 5-4f 中对此的模拟。我们通过将两次测量的结果写入两个不同的经典寄存器来创建它。
c = ClassicalRegister(2)
circuit = QuantumCircuit(q, c)
circuit.h(q[0])
circuit.measure(q[0], c[0])
circuit.measure(q[0], c[1])
job = execute(circuit, backend, shots=100)
job.result().get_counts(circuit)
Listing 5-4fMeasurment Statistics MeasMixedSt_qiskit.ipynb
下面显示了输出。
可以看到,没有 01 或 10 之类的输出。
现在你已经看到了单量子位中的测量行为,测量多量子位系统是有帮助的。大多数量子计算机实现的是局部测量,也就是说每个量子比特都是单独测量的。因此,如果我们有一个两量子位系统,其中第一个量子位处于相等的叠加态,第二个处于|0⟩态,也就是说,我们有状态,我们观察到“0 和 0”或“0 和 1”作为两个量子位的测量结果。
q = QuantumRegister(2)
c = ClassicalRegister(2)
circuit = QuantumCircuit(q, c)
circuit.h(q[0])
circuit.measure(q, c)
job = execute(circuit, backend, shots=100)
plot_histogram(job.result().get_counts(circuit))
Listing 5-4gMeasurment of Multi-Qubit Systems MeasMixedSt_qiskit.ipynb
这将直方图作为统计输出,如图 5-18 所示。
图 5-18
多量子比特系统的测量统计
接下来,让我们对一个纠缠态进行测量,并获得 100 次这样的测量后的统计量。
q = QuantumRegister(2)
c = ClassicalRegister(2)
circuit = QuantumCircuit(q, c)
circuit.h(q[0])
circuit.cx(q[0], q[1])
circuit.measure(q, c)
job = execute(circuit, backend, shots=100)
plot_histogram(job.result().get_counts(circuit))
Listing 5-4hMeasurement of Entangled State MeasMixedSt_qiskit.ipynb
列表 5-4h 给出了图 5-19 所示的直方图作为统计输出。
图 5-19
纠缠系统的测量统计
作为输出,我们只观察 00 和 11。既然状态是,这应该不足为奇。然而,这里发生了一些不寻常的事情。在最后一段代码的末尾,有相同的统计数据,但是在相同的量子位上有个测量值。我们有两个空间分离的量子位表现出相同的行为,这是一种非常强的关联形式。这意味着,如果我们测量一个量子位并得到比如说 0 的结果,我们肯定知道如果我们测量另一个量子位,我们也会得到 0,即使第二次测量也是一个随机变量。**
为了更好地理解这一点,想象我们正在投掷两枚无偏的硬币。如果我们观察其中一个的正面,除了一个概率为 0.5 的预测外,我们完全无法知道另一个可能是什么。如果我们使用有偏见的硬币,那么我们可能会提高我们的预测准确性。然而,我们仍然不能根据我们在一枚硬币上观察到的结果来肯定地说另一枚硬币是什么。
尽管纠缠现象与两个量子位之间的物理距离无关,甚至可以跨越光年的宇宙距离,但纠缠量子位之间不存在激活或瞬时“超过光速”信号。测量对于量子位是局部的,信息也是局部的。如果其他人正在测量另一个量子位,我们必须通过经典的通信渠道告诉这个人,我们碰巧知道结果会是什么。因此,虽然我们肯定不能用纠缠来违反相对论,但这种强关联形式仍然是许多量子算法的核心。
混合状态
混合状态在第一章中进行了阐述。一个密度矩阵是另一种写量子态的方式,而不是 kets。正如我们已经看到的,胸乳是一种投射。但是它们也可以形成密度矩阵。例如,我们可以写𝜌=|𝜓⟩⟨𝜓|,𝜌是|𝜓⟩.的密度矩阵玻恩法则仍然适用,但是现在结果的轨迹变得重要了。例如, Tr [|0⟩⟨0| ρ |]将是看到 0 的概率。清单 5-4i 是这样的代码。
ψ = np.array([[1], [1]])/np.sqrt(2)
ρ = ψ.dot(ψ.T.conj())
Π_0 = zero_ket.dot(zero_ket.T.conj())
np.trace(Π_0.dot(ρ))
Listing 5-4iTrace in Mixed States MeasMixedSt_qiskit.ipynb
这给出了输出
换句话说,再拿一半。测量后的重正化类似地发生,如下所示。
这显示在清单 5-4j 中。
probability_0 = np.trace(Π_0.dot(ρ))
Π_0.dot(ρ).dot(Π_0)/probability_0
Listing 5-4jRenormalization MeasMixedSt_qiskit.ipynb
随着输出
尽管每个状态都被创建为 ket 和 bra,但还有其他被称为混合状态的状态:纯状态上的经典概率分布。形式上,一个混合状态写成∑ρI∣ψI⟩⟨ψI∣,其中∑ρ**I= 1, ρ 我们可以举个例子,比较一下相等叠加态和混合态 0.5( ∣ 0⟩⟨0| + | 1⟩⟨1 ∣)的密度矩阵,如清单 5-4k 所示。
zero_ket = np.array([[1], [0]])
one_ket = np.array([[0], [1]])
ψ = (zero_ket + one_ket)/np.sqrt(2)
print("Density matrix of the equal superposition")
print(ψ.dot(ψ.T.conj()))
print("Density matrix of the equally mixed state of |0><0| and |1><1|")
print((zero_ket.dot(zero_ket.T.conj())+one_ket.dot(one_ket.T.conj()))/2)
Listing 5-4kMixed State MeasMixedSt_qiskit.ipynb
输出如下。
被称为相干的非对角元素在第二种情况下消失了。相干性的存在表明状态是量子的。这些值越小,量子态就越接近经典的概率分布。
第二密度矩阵只有个对角元素,且相等;这是一个均匀分布的等价写法。均匀分布具有最大熵,因此,具有这种结构的密度矩阵称为最大混合态。换句话说,我们完全不知道规范基的哪些元素构成了状态。
理想情况下,量子态应该与环境完全隔绝。然而,在现实中,量子计算机还不能实现高度的隔离。因此,相干性慢慢地消失在环境中。这个过程叫做消相干。退相干发生的速度决定了我们可以在量子计算机上运行的量子算法的长度:如果它发生得很快,我们就有时间应用一些门或进行任何其他形式的计算,并快速测量结果。
密度矩阵比状态向量更有表现力,因为状态向量只能表示纯状态。但是,即使是一个处于混合状态的系统,它也可以被看作是一个处于纯状态的更大系统的一部分。这个将放大系统的混合态转化为纯态的过程叫做净化。一个 n 量子位系统的混合状态可以通过添加更多的 n 量子位并与 2 n 量子位系统一起工作来提纯。一旦纯化,2 个 n 个量子位的联合系统处于纯态,而第一个 n 个量子位仍处于原始混合态。
开放和封闭量子系统
让我们从列出你已经获得的封闭量子系统的见解开始。
-
封闭系统是基本的,任何考虑中的系统都表示为封闭系统。
-
在标准量子力学中,人们考虑封闭系统(即,与环境完全隔离的系统)。由此产生的动力是单一的。
-
这是一种理想化,因为物理系统不可能与它们的环境完全隔离(也许与整个宇宙隔离)。
在封闭的量子系统中,系统的动力学完全独立于环境的动力学。因此,在这个系统产生时与它相关的可观察量,例如,它的总能量,在系统演化期间保持不变。这样的系统,虽然便于获得洞察力和理解,但远远不现实。图 5-20 显示了封闭量子系统的图示。
图 5-20
封闭量子系统
然而,由于每个量子系统都与它的环境相互作用,遵守完美幺正量子动力学的孤立、封闭量子系统的理想化是一种理想化。事实上,每个系统都是开放的,这意味着它与外部环境相耦合。图 5-21 展示了一个开放的量子系统。
图 5-21
开放量子系统
开放量子系统理论是几乎所有现代量子力学及其应用研究的基础。有时,这些开放系统的影响很小,但它们很难被忽略。这在量子信息处理领域中特别相关,在该领域中,相对于经典信息处理的量子优势的存在通常首先来自理想化的封闭系统观点,然后必须在现实的开放系统环境中重新审视。有了这些想法,我们开始考虑以下观点来研究开放系统。
-
开放系统是基础,任何考虑中的系统都表示为开放系统。
-
感兴趣的系统与外部环境相互作用的事实对于我们描述该系统是至关重要的。
当我们在混合环境中单独观察子系统 A 时,两体系统的纯态可能表现得像混合态。如果我们只想知道 A 的动力学呢?即使我们不完全了解子系统 B,我们能描述它的演化吗?如果我们假设二体系统的状态经历幺正演化,我们如何单独描述 A?
封闭系统和开放系统之间的区别在于将系统与环境分开的边界的假定特征。对于封闭系统,边界是不可渗透的(即,系统和环境之间不允许信息流,从而使系统能够孤立地发展)。因此,完整的哈密顿量描述了系统本身的动力学。
在开放的量子系统中,边界不再是不可渗透的,因此,系统可以自由地与其环境交换信息,无论是相位还是能量。因此,没有一个框架来确保可观测的量在系统的演化过程中保持守恒。一个开放的系统比一个封闭的系统更接近真实的场景。因此,宇宙中包含的任何东西(即宇宙的任何子系统都必须是开放系统)。任何被认为是封闭系统的系统都只是一种近似。
量子态演化,其演化由酉矩阵描述。这导致了量子计算中一些有趣的性质。酉进化对于一个封闭的系统是真实的;也就是一个与环境完美隔绝的量子系统。我们今天拥有的量子计算机却不是这样,它们是开放的量子系统,由于与环境的不可控相互作用而发生不同的进化。在本节中,我们将通过一些 Jupyter 笔记本示例来深入了解这一过程。对开放量子系统和相关动力学的深入理论讨论超出了本书的范围。我推荐 Rivas 和 Huelga 的书[62]和麻省理工学院开放课件[63]。
在这本笔记本中,我们对这两种类型的进化都有所了解。如果一个算子与它自己的伴随算子相乘时产生一个单位矩阵作为输出,则该算子被认为是酉的。酉算子有一个与其共轭算子相等的逆算子。算子 U 的逆用U1 表示。这满足以下关系。
其中 I 是恒等运算符。
为了使 U 成为一体,
和
“非”运算是由量子计算机中的 X 门执行的。虽然关于门的一般性讨论只出现在后续的笔记本中,但是我们可以研究 X 门的属性。它的矩阵表示是。Jupyter 笔记本代码
ClosedOpenSystems.ipynb
的清单 5-5a 验证它是否确实是酉的。
import numpy as np
X = np.array([[0, 1], [1, 0]])
print("XX^dagger")
print(X.dot(X.T.conj()))
print("X^daggerX")
print(X.T.conj().dot(X))
Listing 5-5aEvolution of Unitary Gates ClosedOpenSystems.ipynb
清单 5-5a 给出以下输出。
因此, X 看起来是一个合法的酉运算。单一性确保了12范数得以保留;也就是说,量子态被映射到量子态。清单 5-5b 显示了寻找范式演变的代码。
print("The norm of the state |0> before X is applied")
zero_ket = np.array([[1], [0]])
print(np.linalg.norm(zero_ket))
print("The norm of the state after X is applied")
print(np.linalg.norm(X.dot(zero_ket)))
Listing 5-5bEvolution of Norm ClosedOpenSystems.ipynb
以下输出确认了规范得到了保留。
由于酉运算是矩阵,所以线性。测量值也用矩阵表示。这两个观察暗示量子计算机实现的一切都是线性的。如果某种形式的非线性是期望的,那么这必须涉及一些经典的干预。
酉运算的另一个结果是可逆性(即,任何酉运算都可以反转)。因此,量子计算库通常提供逆转整个电路的功能。由于 X 门是自身的共轭转置,因此需要再次应用该门进行反转,这意味着X2= 1。
import numpy as np
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit import execute
from qiskit import BasicAer
from qiskit.tools.visualization import circuit_drawer
np.set_printoptions(precision=3, suppress=True)
backend_statevector = BasicAer.get_backend('statevector_simulator')
q = QuantumRegister(1)
c = ClassicalRegister(1)
circuit = QuantumCircuit(q, c)
circuit.x(q[0])
circuit.x(q[0])
job = execute(circuit, backend_statevector)
print(job.result().get_statevector(circuit))
Listing 5-5cEvolution of norm ClosedOpenSystems.ipynb
输出是
这和预期的完全一样是 0。
正如我们之前强调的,真实的量子系统很少是封闭的。他们不断地以一种非常困难的方式与他们的环境进行交互,以今天的技术水平来看,有时是不可能控制的,这反过来又会导致他们失去连贯性。对于当前和近期的量子计算机来说也是如此。这意味着它们的实际时间演化不是由一个酉矩阵描述的,而是由一个叫做完全 正轨迹保持映射的其他算子描述的。
量子计算库通常提供各种噪声模型来模拟和模仿不同类型的相互作用。增加与环境相互作用的强度会导致更快的消相干。退相干的时间尺度通常被称为T2 时间。在其他几个参数中, T 2 时间对于门的数量或我们可以执行的量子计算的持续时间至关重要。
研究退相干效应的一个简单方法是将一个纯态与最大混合态混合,其中𝑑是量子比特的数量。这样,我们不必指定噪声模型或任何其他映射建模去相干。例如,我们可以混合|𝜙+⟩态和最大混合态。
def mixed_state(pure_state, visibility):
density_matrix = pure_state.dot(pure_state.T.conj())
maximally_mixed_state = np.eye(4)/2**2
return visibility*density_matrix + (1-visibility)*maximally_mixed_state
φ = np.array([[1],[0],[0],[1]])/np.sqrt(2)
print("Maximum visibility is a pure state:")
print(mixed_state(φ, 1.0))
print("The state is still entangled with visibility 0.8:")
print(mixed_state(φ, 0.8))
print("Entanglement is lost by 0.6:")
print(mixed_state(φ, 0.6))
print("Hardly any coherence remains by 0.2:")
print(mixed_state(φ, 0.2))
Listing 5-5dMaximally Mixed State ClosedOpenSystems.ipynb
清单 5-5d 给出了以下输出。
在开放系统中观察量子态的一种方式是通过它的平衡过程。例如,一杯热气腾腾的茶由于与环境相互作用而失去热量,最终达到环境的温度。这个过程包括能量交换。量子态表现出同样的行为。
这个平衡态被称为热态 ,,它有一个非常特殊的结构,我们以后会再讨论它。取自热状态的统计样本的能量遵循波尔兹曼分布【64 】,由下式给出
其中p(ϵI)为状态 i 的概率。 ϵ i 是状态 i 的能量。 k 是玻尔兹曼常数。 T 是系统的温度。M 是感兴趣系统可访问的所有状态的数量。 Q 是归一化分母。温度越高,我们就越接近均匀分布。在无限温度极限下,它恢复均匀分布。在高温下,所有能级的概率相等。相比之下,在零温度下,整个概率质量都集中在最低能级——基态能量。为了了解这个过程,清单 5-5e 绘制了不同温度下的玻尔兹曼分布。
import matplotlib.pyplot as plt
temperatures = [.5, 5, 2000]
energies = np.linspace(0, 20, 100)
fig, ax = plt.subplots()
for i, T in enumerate(temperatures):
probabilities = np.exp(-energies/T)
Z = probabilities.sum()
probabilities /= Z
ax.plot(energies, probabilities, linewidth=3, label = "$T_" + str(i+1)+"$")
ax.set_xlim(0, 20)
ax.set_ylim(0, 1.2*probabilities.max())
ax.set_xticks([])
ax.set_yticks([])
ax.set_xlabel('Energy')
ax.set_ylabel('Probability')
ax.legend()
Listing 5-5eBoltzmann Distribution ClosedOpenSystems.ipynb
这给出了图 5-22 中的图作为输出。
图 5-22
玻尔兹曼能量分布
该图显示 ?? < ?? < ??。?? 是低温,并且预期在低能级急剧达到峰值。相比之下,?? 是非常高的温度,概率分布几乎完全平坦。
这些练习旨在增加你对来自外部观察者的测量的影响如何触发在封闭系统中没有类似物的新型多体现象的理解。概括地说,孤立量子系统的时间演化由单个厄米算符(即哈密顿量)描述。相反,在连续观察下,由于测量反作用,动力学变得本质上非酉,并且不仅由哈密顿量表征,而且由测量过程表征。
量子主成分分析
机器学习和分析练习通常有许多特征,其中一些是相关的。例如,考虑房价,它是房子的许多特征的函数,例如卧室和浴室的数量、平方英尺、地段大小、建造日期和位置。通常,您希望将要素的数量限制为最重要的要素(即获取数据中最大方差的要素)。例如,如果有人只考虑特定街道上的房屋,那么位置可能并不重要,但面积可能会有很大的差异。
确定哪些特征捕捉到最大的方差被称为主成分分析 (PCA) [65]。数学上,PCA 涉及获取原始数据(例如,各种房屋的特征向量)并计算协方差矩阵。
参考文献[66]中提出的用于执行 qPCA(量子 PCA)的量子算法使用密度矩阵表示。这里讨论的算法有四个主要步骤。
-
在量子密度矩阵 ρ 中编码协方差矩阵σ。
-
准备多份 ρ 。
-
对每个拷贝和一个目标系统执行指数交换操作。
-
执行量子相位估计以确定特征值。
要在高噪声模拟器上实现这种 qPCA 算法,请参考参考文献[67]。作者还在 GitHub 的 https://github.com/rmlarose/vqsd
发布了 Cirq 中的代码。图 5-23 显示了在噪声量子模拟器上实现 qPCA 量子算法的步骤。作者称该算法为变分量子态对角化或 VQSD。
图 5-23
qPCA/VQSD 算法实现(来源[67])
下面解释 VQSD 算法的步骤,如图 5-23 所示。
(a)输入是量子态 ρ 的两个副本。这些状态被发送到参数优化循环,(b)其中混合量子经典变分算法(将在后面的章节中解释)近似对角化酉Upαopt。这里, p 是一个超参数,表示解决方案的质量。该最优酉被发送到特征值读出电路(c)以获得位串 z ,其频率提供了对 ρ 的特征值的估计。连同最优酉pαopt,这些位串被送到本征向量准备电路,(d)在量子计算机上准备 ρ 的本征态。特征值和特征向量都是 VQSD 算法的输出。
*## 摘要
这一章冒险进入量子算法的第一部分,从我们上一章结束的地方开始。它着眼于一些重要的算法和方法,如 Deutsch-Jozsa 算法,量子计算复杂性,编码技术(基础,张量积,振幅和哈密顿),以及经典数据输入到量子算法的过程。我们也冒险进入测量和混合状态,量子傅立叶变换,和它的一个重要应用,即相位估计。我们首先查看了 Rigetti 的森林 SDK 和 QVM,并在其他练习中使用了 Qiskit 和 Cirq。下一章继续到先进的量子算法和相关的代码。
Footnotes 1
人们认为这种代码很难被经典计算机破解。例如,没有已知的经典算法能够在有效的时间内分解数字以破解 RSA 加密。
2
Aspen、Forest、Forest SDK、Pyquil、QCS、Quantum Advantage Prize、quil、Quilc、Quil-T、QVM 和 Rigetti 是 Rigetti & Co,Inc .的商标或注册商标。
*
六、QML 算法 2
让你的生命像叶尖的露珠一样,在时间的边缘轻盈地舞蹈。
—罗宾德拉纳特·泰戈尔
量子机器学习在量子计算机上计算经典机器学习中完成的技术方面提供了前所未有的范围。基本量子位状态的纠缠和叠加有望在经典机器学习的性能和范围上提供优势。
到目前为止,你应该对经典量子系统如何跨越它们的界面工作有了一些了解。目前,有两种有前途的方法可以利用量子计算机来完成机器学习任务。
-
第一种方式构建经典机器学习模型的“量子版本”,使得量子算法产生类似于所述经典模型的结果。
-
第二种方式是创建特定于量子计算平台的物理构建模块和基本原理的量子机器学习模型。在这种情况下,模型性能被认为是更重要的。
Note
除了已经介绍过的对量子机器学习很重要的算法之外,本章还介绍了几种算法:测量的更多方面,如施密特分解、交换测试、线性模型、核方法、k 均值聚类概述和 k 中值算法。它还显示了 Qiskit 和 Rigetti 的森林中的 Iris 数据集的内核方法,我们在经典机器学习之旅的第 2 和 3 章中遇到了这些方法。
本章着眼于与量子计算和量子机器学习的一些非常重要的属性相关的其他几种算法:更多的测量方面,更多的算法,以及线性和非线性空间中的数据编码技巧和相关的预测,引导我们走上一条包含量子算法推理的自然道路。计算模型预测的过程被称为推理。你已经看过一些量子算法了。在这一章中,更多的内容将作为对量子推理的更深入的探索,以发现如果给定一个使用量子系统的输入,如何计算一个预测。
图 6-1
量子算法开发过程
图 6-1 展示了一种开发和优化量子算法的方法。算法针对给定的一组资源进行优化,包括辅助和数据量子位以及测量资源。该算法由量子门序列和测量结果的经典后处理决定。为了找到执行 x → f ( x )的算法,对于一组训练数据输入,量化期望输出和实际输出之间的差异的成本函数(第五章)被最小化。在训练数据足够通用的情况下,最小化成本的算法应该是为任何 x 计算 f ( x )的通用算法。
这一章着眼于这些原则和执行测量,这是非常重要的在所有的量子计算系统。在这条道路上,最重要的概念是施密特分解。
施密特分解
我们已经研究了纠缠和相关的性质,包括隐形传态。我们也看到了由纯态和混合态组成的系统的性质。然而,纠缠并不总是指纯态或混合态,实际检测系统中纠缠的存在常常是一个挑战。从探测两体复合系统中的纠缠和相关测量的角度来看,施密特分解是非常重要的。
与经典物理学不同,粒子可以耦合或纠缠,使得复合系统不仅不相等,而且大于组件之和。对于复合系统,方程 4。24 通过不等式给出简化的密度矩阵,如下所示。
复合量子系统由两个或更多不同的物理系统组成。这种复合系统的状态空间由组成物理系统的状态的张量积给出。
第四章讨论了香农熵和冯诺依曼熵,它们只在由相互正交的纯量子态组成的系综中重合。因此,如果一个编码讯息以一组正交的量子位元状态传送,其中每一个都是纯态,它就可以用一个整体的张量积状态来描述。在这种情况下,传输将等同于发送与一组经典比特相同的信息,因为一旦编码基础被确定,每个量子比特是完全可区分的。
一组来自已知基础的状态可以完美逼真地被克隆,这与一般的现实情况相反,后者是不完美的和受限制的。如果未知的量子态是完全可分辨的,它们就可以被完全克隆,“不可克隆定理”将不再重要。
伴随着与纠缠相关的关联,发生了状态分解。作为一个例子,在一个二分量子复合系统中,两个子系统之间的相互量子信息由状态 φ 1 和 φ 2 描述,一个复合系统的联合状态 φ 12 由下式给出
(6.1)
复合系统的状态空间是组成物理系统的状态的张量积。例如,在纯二分态 A 和 B 中,复合系统的总希尔伯特空间(见第一章)变成
(6.2)
其中,⊗表示张量积。∣ψ⟩ab是复合系统的状态向量。如果的维数为 n ,那么这个总向量就是 mn 个基向量的叠加。
复合状态向量∣ ψ ⟩ AB 的定义表明由eI⊗vI给出的至少有一个正交基,其中eI和 v
(6.3)
其中, r 为施密特秩,和aI为施密特基。在施密特分解的这种表示中,求和指数仅上升到相应的两个希尔伯特空间维度中较小的一个。通过将任意相位吸收到{eI}和{vI}的定义中,通常可以方便地将幅度 a i 也称为施密特系数取为实数。如此,aI≥0 和。多体系统中的施密特分解是有限的;只有在两个州才有把握。
作为施密特分解过程的一个例子,我们可以考虑 4 维希尔伯特空间中的一个向量,其中
和
的维数都是 2。这可以由下式给出
对于我们的例子来说,这个状态已经用施密特基写成了,因为对于和
中的每一个,计算基都是施密特基。因此,施密特系数如下。
a 0 = 0 和 a 1 = 1
以下是计算基础。
∣ e i ⟩和∣ v i ⟩用两个酉矩阵 U 、v∈u(2n和 a i 来表示如果 n 量子位状态由 Q ∣00 给出...0⟩∈u(2n),那么,施密特分解中的乘积可能是由 U 、 V 和 Q 与 n 个 CNOT 门组合而成的量子电路给出的,如图 6-2 对于 n = 6。
图 6-2
施密特分解
施密特分解类似于奇异值分解,其中密度矩阵表示对于描述复合量子系统的各个子系统是有用的。复合系统的密度矩阵由下面的张量积给出。
(6.4)
其中分量 ρ A 和 ρ B 均来自复合矢量ρAB。
复合量子系统的子系统由约化密度矩阵描述。子系统 A 的简化密度矩阵根据部分轨迹定义如下
(6.5)
其中 Tr B 是系统 B 上的偏迹算子。对于任何密度矩阵,属于系统 B 的概率振幅由于密度算子【参见第一章】、 Tr ( ρ ) = 1 的偏迹而消失。这个过程也称为描出。在部分跟踪操作后,仅保留属于系统 A 的振幅。
施密特系数或振幅根据以下矩阵计算。
(6.6)
矩阵 φ 有特征值aI2。非零特征值的个数 a i 给出了施密特数或施密特秩 r 。施密特等级的用法如下。
-
如果施密特秩(或数)≥1,则该态是纠缠态
-
如果施密特秩(或数)=1,则状态是独立的
因此,施密特数在区分纠缠态时是有用的。只有当一个态是纠缠态时,它的施密特数才大于 1。它被用作系统中纠缠量的(粗略)量化器,并作为纠缠的标准。因此,施密特分解被视为一种工具,以确认现实生活中的实验量子系统纠缠。施密特分解定理可以应用于更复杂的二分向量空间,即使两个子空间具有不同的维数。
从历史上看,纠缠浓度的最初提议包括“施密特投影”[74]。施密特投影方法需要至少两个非最大纠缠对,并且对于大量的对变得有效。该方法基于一侧所有量子位的“汉明重量”[75]的集体测量,将所有对投影到具有共同施密特系数的状态所跨越的子空间上。测量结果然后被传统地传送到另一侧。或者,在另一侧执行相同的集体测量,这将产生相同的结果,并使得传统的通信可有可无。该方法也适用于尺寸d2【74】。在渐近极限下,将 n 个非最大纠缠输入对的总态矢量转化为 m 个最大纠缠输出对的总态矢量可以通过确定性纠缠变换的优化准则来描述[3],给出 m < n 的纠缠浓度。
总的来说,纠缠的一个重要标志是违反了局部实在论强加的不平等[76]。任何纯粹的两方状态都是纠缠的,当且仅当,对于选定的可观测量,它违反了这样的不平等。
注意,当且仅当复合态的态矢是张量积形式的∣ψ⟩ab=∣ψ⟩a⊗∣ψ⟩b时,换句话说,当施密特数等于 1 时,约化态保持纯态。施密特分解的计算示例可以在附录 a 中找到。
量子计量学
精密测量在所有科学领域都很重要——在量子力学中更是如此,因为需要测量的尺度非常小,并且需要很高的灵敏度。例如,光学相位测量可以测量距离、位置、位移、加速度和光程长度。量子信息技术领域需要接口来执行物理参数的高分辨率和高灵敏度测量。非常重要的是,这些测量接口不会与受审查的量子系统相互作用,或者任何这种相互作用都可以通过过程来区分。这些测量标准由量子理论控制,该理论描述了物理系统并利用了诸如量子纠缠和量子压缩等特征。量子纠缠现象使得精确度比其他方式高得多。
量子计量使用量子或单个能量包来设置定义测量单位的标准。量子力学为任何测量的精确度设定了极限。因此,量子计量学利用量子效应来提高精度,使之超过传统方法的精度。
量子计量学是与从量子系统中提取信息有关的领域。因为这主要是通过测量来完成的,所以状态和可观测值也很重要。由于使用纠缠态而导致的增强是二次的,并且与我们之前对 Grover 和 Grover 类算法的讨论有关。Vittorio Giovannetti、Seth Lloyd 和 Lorenzo Maccone [89]对量子计量的实验和理论结果进行了全面讨论。
实际操作练习有助于您更好地了解为量子计量提供动力的基于纠缠的测量。涉及光及其特性的测量通常涉及马赫-曾德尔干涉仪【90】。在物理学中,Mach-Zehnder 干涉仪是一种用于确定两个准直光束之间相对相移变化的装置,这两个准直光束是通过分离来自单个光源的光而获得的。干涉仪可以测量由样本或其中一个路径的长度变化引起的两个光束之间的相移。该仪器以物理学家路德维希·马赫和路德维希·泽德的名字命名,发表于 1892 年的一篇文章[90]。
Mach-Zehnder 干涉仪经常用于空气动力学、等离子体物理学和热传递,以测量气体中的压力、密度和温度变化,如图 6-3 所示。
图 6-3
马赫-曾德尔干涉仪(来源【91】1)
让我们首先从 Qiskit 导入所需的库,如清单 6-1a 所示,用于从该书的网站下载的entanglementM.ipynb
Jupyter 笔记本,并通过打印随机角度来测试我们的库导入是否有效。在这个练习中,我们使用了一个模拟器。
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
from math import pi
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister, execute
from qiskit.tools.visualization import circuit_drawer
from qiskit.quantum_info import state_fidelity
from qiskit import BasicAer
backend = BasicAer.get_backend('unitary_simulator')
#pick random theta
theta=np.random.randn()
print("rand theta",theta)
Listing 6-1aLibraries for entanglementM.ipynb
随机角度测试给出以下输出。(由于这是一个随机的角度,输出可能在不同的运行中有所不同。)
接下来,让我们看看简单的干涉测量法,如清单 6-1b 所示。在图 6-3 中,干涉仪两个光路之间的相位差 θ (由样品引起)的信息可以通过测量两个输出光束的强度,即光子数来监测这两个输出光束来提取。在没有任何相位差的情况下,所有光子作为检测器 1 处的输出离开设备。另一方面,如果 θ = π 弧度,100%的光子在输出检测器 2 处出射。如果 θ 的值在 0 和 π 之间(即,如果 0<θπ,那么一部分光子在探测器 1 的输出处离开,一部分光子在探测器 2 处离开。
为了计算电路,我们利用旋转算子(第章,方程 1)。26 ),给出围绕 Z 轴通过角度 θ (弧度)的单量子位旋转。
q = QuantumRegister(1)
c = ClassicalRegister(1)
qc = QuantumCircuit(q,c)
qc.h(q[0])
qc.rz(theta,q[0])
qc.h(q[0])
qc.measure(q,c)
qc.draw()
Listing 6-1bSimple Interferometry entanglementM.ipynb
这给出了以下电路作为输出。注意,由于 θ 是随机启动的(theta=np.random.randn).
,输出中的rz
值可能因运行而异
下一步,我们计算零概率(即和相关误差)。这是通过估计以下内容来实现的。
(6.7)
其中xI= 0或 1 取决于第 i 次测量的输出。这里,一个 x i 是一个随机 2 变量。对于随机变量,与它们的平均值相关联的方差(见第二章)是由中心极限定理【91】定义的方差的平均值。
测量期间给出的误差由下式给出
(6.8)
其中所有的δxI差等于δx,因为它们是同一实验的一部分;因此,δxI是第 i 次测量的扩散。清单 6-1c 中给出了该计算的代码。它使用qasm
模拟器。
backend = BasicAer.get_backend('qasm_simulator')
job = execute(qc, backend, shots=1024)
job.result().get_counts(qc)
Listing 6-1cProbability entanglementM.ipynb
这给出了以下输出。
显示测量 x i = 0 或 1 时出现的状态。
纠缠测量
最后一步,我们从 GHZ 态开始演示纠缠测量。三量子比特 GHZ 态是最简单的一种,它表现出非平凡的多体纠缠,由下式给出
GHZ 状态是所有处于状态 0 的子系统的量子叠加,所有子系统都处于状态 1,其中单个子系统的状态 0 和 1 是完全可区分的。在清单 6-1d 中,初始状态为,最终状态由下式给出
在我们的例子中,我们有 N = 3。因此,测量的概率现在由下式给出
这里,我们用 1.5 弧度的值初始化 θ ,同样是 1024 次拍摄。
theta = 1.5
q = QuantumRegister(3)
c = ClassicalRegister(1)
qc = QuantumCircuit(q,c)
qc.h(q[0])
qc.cx(q[0],q[1])
qc.cx(q[0],q[2])
qc.rz(theta,q[0])
qc.rz(theta,q[1])
qc.rz(theta,q[2])
qc.cx(q[0],q[2])
qc.cx(q[0],q[1])
qc.h(q[0])
qc.measure(q[0],c)
qc.draw()
backend = BasicAer.get_backend('qasm_simulator')
job = execute(qc, backend, shots=1024)
job.result().get_counts(qc)
Listing 6-1dProbability entanglementM.ipynb
输出显示了出现的概率(同样,由于随机变量的性质,这可能会因运行而异)。
作为练习,我们鼓励您使用此代码作为模板来尝试以下内容。
-
计算不同 N 值下样本的方差
-
使用不同的θ种子值进行测试
线性模型
在第 2 和 3 章中,你看到了感知器和线性回归形式的经典线性模型。线性模型[Schuld et al. ref 79]可以用时间函数T= { 0,T}(即时间 0 到 T)来描述,该函数映射由xT给出的N维输入,其中由(x1,…, xN)T到M-尺寸输出由yT=(y1,…,yM) 具有由 w 给出的一组权重的线性函数可以表示为
其中 w T 是权重乘以输入向量 x、 ϕ 是依赖于输入和权重的函数。在这个方程中, w T 是一个参数定义的向量,需要从数据中拟合或学习。由于 N 维输入映射到 M 维输出,函数 f ( x , w )有可能是多维的。线性回归函数(第二章)也是线性模型,在这种情况下,可以有多个维度。
图 6-4
图示线性回归给定训练数据点(xIT5, y i )和非线性映射来拟合相同的数据点
图 6-4 显示了在左边给出的训练数据点( x i , y i )的线性回归示意图。机器学习的任务不是确定拟合本身(与统计分析相反),而是基于拟合的函数对新输入的类别标签
进行有根据的猜测。在右侧,图 6-4 说明了输入可以通过非线性映射
转移到更高维的空间,从而增加线性回归拟合非线性函数的能力。
在带有感知器的神经网络中,线性函数也可能表现为线性化层。用感知器(参见 3 一章中的偏置吸收,习惯上定义wT≡(b0, w 1 ,……
让我们看看实现不同线性模型的方法,以将量子进化解释为一般的线性模型。
广义线性模型
广义线性模型 (GLM)是线性回归的推广和延伸。线性回归假设变量呈高斯分布。GLMs 没有施加这样的限制。他们使用连接函数来模拟自变量的因变量和线性组合之间的关系[80,81]。 h ( x )链接函数由下式给出
其中 β 是预测权重的向量。在这种格式中, h ( x )链接函数实现了将因变量或结果变量的分布转换为正态分布以适应线性模型的重要特性,从而产生了广义线性模型[80]。
GLMs 有各种统计扩展,包括纵向数据建模的广义估计方程、具有随机效应的纵向数据的广义线性混合模型和广义加法模型。然而,工业中的许多(如果不是大多数的话)问题不容易用指数族足够精确地建模;此外,线性回归,一般来说,有许多假设可能不符合现实生活中的科学和行业数据。机器学习算法提供了替代方法来最小化测试集的预测值和实际值之间的误差。实现这一点的一种方法是误差平方和,这是优化算法通常使用的方法。许多监督学习算法是广义线性模型的扩展,并且具有内置于算法中的链接函数,以模拟不同的结果分布;示例包括增强回归和贝叶斯模型平均。像深度学习和经典神经网络这样的方法试图通过一系列通用映射来解决类似的问题,从而产生潜在的新型链接函数。
如今,Python、R 或 SAS 中可用的包为 GLMs 和许多这些机器学习模型的链接函数提供了各种选项。然而,当数据集分布有许多零点或异常值时,这种模型就会出现问题,现在,这些包中提供的链接函数中没有一个被接受为给定数据集的最佳选择已经变得很常见。此外,求解正确参数的计算成本非常高,特别是对于增强回归、基于拓扑的回归方法和深度学习模型[82,83]。所有这些因素都会导致已知分布的连续变形,从而产生大量新的可能的连接函数。理想的算法是叠加所有可能的分布并折叠以适合数据集。
量子门是这些限制的解决方案。非高斯变换门,它以计算高效的方式执行任务。通过折叠成理想连接的状态叠加,利用分布之间的几何关系,给出了问题的最佳解决方案[84]。
以量子计算格式表示由标量值表征的线性模型的直观方式是将输入 x 编码成振幅∣ ϕ x ⟩,并将权重 w 编码成振幅∣ϕy⟩.两者的内积给出
(6.9)
测量两个量子态之间的内积是量子信息论的重要组成部分。一些量子电路中量子线之间的叠加可以用来进行这样的测量。最著名的内积干扰电路之一是交换测试。一种广泛应用于量子机器学习练习的方法[85] [86]。
互换测试
swap 测试的量子电路最早由 Buhrman 等人[87]提出,如图 6-5a 所示。这个电路的意义在于,通过测量第一个量子位处于∣1⟩态或∣0⟩态的概率,可以得到量子位态|⟨ϕx|ϕy⟩|2的内积的平方。然后,这个测量值可以被输入到测量辅助量子位的状态的概率中。
图 6-5a
交换测试电路
交换测试电路如图 6-5a 所示。交换测试包括一个辅助量子位,两个量子位寄存器,分别位于∣【ϕx⟩和∣ϕy⟩,以及三个量子门:两个哈达马德门和一个受控交换门,也称为弗雷德金门(见图 6-5b )。受控交换测试在量子机器学习中广泛使用,并已被修改为执行量子系统中的检测和量化纠缠的任务[88]。
*
图 6-5b
C-SWAP 或 Fredkin gate
最初,两个量子态∣x⟩和∣ ϕ y ⟩(图 6-5a )连同状态∣0⟩.中的辅助量子位一起被准备副量子位叠加,∣ϕx⟩和∣ϕy⟩态对调。
1. The Swap Test starts by applying a Hadamard transform to an ancilla qubit that is initially at state ∣0⟩ and the two quantum states ∣ϕx⟩ and ∣ϕy*⟩ and this leads to the first output state.

-
Next, a C-SWAP gate or Fredkin gate is applied to the two registers ∣ϕx⟩ and ∣ϕy⟩. The registers ∣ϕx⟩ and ∣ϕy⟩ are conditioned for the ancilla to be in state ∣1⟩. Hence, this operation swaps the states of the two registers: ∣ϕx⟩ ∣ϕy⟩ ⟼ ∣ϕy⟩ ∣ϕx⟩. At this time, the overall output state is given by
-
Then, another Hadamard gate is applied to the ancilla qubit resulting in the following state.
状态∣ψ3⟩在步骤 3 中给出两个叠加的输出的组合:一个包含两个寄存器的原始和交换状态的和,另一个包含两者之差。需要注意的是,如果∣ϕx⟩=∣ϕy⟩,那么互换测试总是给出零。
测量状态 0 的副量子位的概率为 1 的结果是由下式给出的接受概率
(6.10)
这反过来给出了内积的价值
或者,
(6.11)
因此,如果|⟨ϕx|ϕy⟩|接近 0,那么有接近 1/2 的概率我们观察到 1。如果∣ϕx⟩=∣ϕy⟩那么我们得到一个概率为 0 来观察一个 1。
评估单个点积的整体复杂度由o(ϵ1logn给出。
线性模型可以在量子机器学习中以各种形式使用,例如干涉电路、酉线性模型、作为基编码的线性模型和振幅编码。对此的详细论述超出了本书的范围;然而,感兴趣的读者可以参考 Schuld 等人的书[5]。
线性模型的一个显著局限性是,它们不能为非线性数据提供非常有意义的结果,换句话说,就是不能在线性空间中分离的数据。因此,模型中的非线性功能通常是需要的,正如我们在第 2 和 3 章讨论经典案例时所讨论的。在诸如基本编码和幅度编码的情况下,可以引入非线性。非线性被引入作为非线性激活函数 ϕ ,其将输入 x 映射到输出 ϕ ( x )。当我们遇到这种非线性激活函数的实现时,我们重新审视这个概念。
为了应用和收获算法和模型的好处,最重要的行动之一是执行高精度、高灵敏度的测量,这自然会导致量子计量学。
核心方法
实现线性模型的方法有很多。非线性数据的处理给线性模型带来了挑战。因此,非线性需要支持这种数据特征的函数。第五章讨论了量子特征空间和特征映射。在第二章中,您遇到了最近邻法,其中平方距离法被用作训练点对预测新输入的贡献权重;这里,相似性的度量被称为一个核。正如你在第二章的练习中看到的,内核方法在经典机器学习中提供了许多选项。线性模型具有线性决策边界(相交超平面)。相反,非线性核模型(多项式或高斯 RBF)具有更灵活的非线性决策边界,其形状取决于核的种类及其参数。内核方法还提供了与基于量子计算的学习过程的相似之处。
内核方法[93]在机器学习中非常常见。在深度学习在机器学习领域占据主导地位之前,它们尤其常见。在这种情况下,状态的核意味着对应于状态的零特征值的向量所跨越的空间。这方面的一个例子是在第一章中讨论的支持向量机(SVM)。SVM 是一种监督学习算法,它学习一组给定的独立且同分布的训练实例,并通过将数据映射到特征空间来绘制两类数据点之间的决策边界,在该特征空间中数据变得线性可分。您在第二章中看到,经典的 SVM 模型使用一个核函数,如 sigmoid 和 tanh,它是在原始输入数据的域上定义的。利用经典机器学习中内核方法的原理,量子系统可以通过有效地操纵数据输入,在难以处理的大型希尔伯特空间中执行计算。
内核方法使用一个内核函数κ(xI, x j )来测量输入空间中训练数据点之间的距离,并利用该测量来计算每个训练输入和任何需要分类的新输入之间的距离。内核函数通常使用最近邻类型的逻辑(参见第二章),并在做出预测决策时选择“更近”训练数据点的类别。这种核对应于映射到更高维特征空间的数据点的内积。通过使用核函数,解决了非线性问题,允许将数据嵌入到更高维度的空间中,在该空间中数据变得线性可分。图 6-6【52】显示了原始输入空间和特征空间之间的映射。左侧是训练输入空间,其中来自两个类(蓝色正方形和红色圆圈)的数据在简单的线性模型中不可分。然而,它们可以被映射到右边的空间,这显示了更高维度的特征空间(额外的 n 维由灰色箭头表示)。线性模型足以定义分离超平面作为决策边界。
图 6-6
核方法允许将数据嵌入到更高维的特征空间中,在该空间中分析变得更容易。(改编自资料来源[52])
数据驱动模型的使用方式是定义训练数据集和输入新数据空间之间的相似性;具有与训练数据点相似的特征的输入被假定为具有与训练集相似的输出。为了考虑某些输入训练数据点的重要性,可以给这些数据点分配权重。这类似于第二章中讨论的经典机器学习中的最近邻方法(使用平方距离)。
Schuld 等人[52]在 2018 年提出了量子机器学习的新颖视角。他们提出了一种将输入数据映射到多维希尔伯特空间(参见第一章)的方法来进行数据分析。
希尔伯特空间是一个向量空间,它非常非常大。对于有限域上的任何向量空间,可能向量的总数在向量空间维度上是指数大的。一个 n 量子位的量子系统给每个可能的经典基态位串分配一个振幅。这些振幅可以是任意的复数,因此需要无限量的信息来指定的状态,甚至是单个量子位。为了便于计数,让我们假设这些振幅被离散化为 d 个可能值。由于 2 个 n 个复振幅中的每一个都可以取任何一个 d 个可能的值,所以可能的量子态的总数是 d 个2 个 n 个并且完全指定一个状态所需的位数是该数的对数基数两个,或者 2n×对数 2 对于一台 50 量子位的量子计算机,希尔伯特空间大约有 1125899907000000 维;对于连续变量量子计算机的单个模式,希尔伯特空间有无穷多个维度。因此,在如此巨大的空间中分析数据是一项重大挑战。
利用 schlkopf 和 Smola [94]对核的定义,对于非空集φ ∈ { x 1 , x 2 ,…, x N }对于 N ≥ 2,核 κ 是一个映射。
其中,Kij=κ(xI, x j )被称为克矩阵。内核是正定的,κ(xI,xj)≥0 和κ(xI, x j 其中κ(xI,xj)∫为复共轭。
第五章中介绍的量子特征图为
其中, φ 是一组输入数据, ϑ 是一个特征空间。输出图上的输出数据点 φ ( x )称为特征向量。 ϑ 通常是一个向量空间。核 κ 从输入集映射到输入集上的复值函数,以创建特征图ω,并且核总是可以用于构造ω。可以从该特征图中构造特征空间,该特征空间是具有内积的向量空间。
简单回顾一下,核函数作为一个更高维度空间上的内积,包含从数据点的原始空间到这个空间的一些ω()映射,核函数由κ(xI,xj)= {φ(xI定义这种方法理论上使我们能够将点(它们在原始空间中是不可线性分离的)映射到一个更高维的空间,在那里它们最终可以线性分离。 κ ()函数可以映射到无限维空间,不需要指定。这只有在内核函数κ(xI, x , j ) ≥ 0 且κ(xI, x j
一些基于核的学习算法是基于实例的(即,最终模型保留一些或所有训练实例,并在实际预测中起作用)。因此,支持向量机(SVM)是很好的例子,因为它们是定义两个类别之间的边界的训练实例。表 6-1 列出了一些重要的内核函数。
表 6-1
重要的内核函数
|内核名称
|
内核函数
|
| --- | --- |
| 线性的 | xI, x j |
| 多项式 | [x【I】,【j】)+a** |
| 径向基函数 | ![$$ {e}^{-\alpha {\left\Vert {x}_i-{x}_j\right\Vert}²} $$ |
核的选择和核的参数通常是任意的。它们需要在数据集上反复试验或超参数优化来帮助选择正确的组合。量子计算机,由于其量子性质,自然会产生某些内核。至少有一个重要的变量是值得研究的。
有两种主要的方法来处理量子机器学习过程:修改机器学习算法,直到它包含带有量子变量的子例程,或者逆转该过程,并在给定量子系统及其相关约束的情况下,寻找新的学习方法。例如,干涉在量子物理学中是很自然的事情。因此,让我们考虑下面的过程:我们在某个寄存器中对训练向量进行编码。这个寄存器与一个副量子比特的叠加态∣0⟩纠缠在一起。叠加态的副态∣1⟩与另一个包含测试向量的寄存器纠缠在一起。在辅助设备上应用 Hadamard 会干扰测试和训练实例。对辅助设备的测量和后选择产生一个内核[95]。
带 Qiskit 的核方法
我们首先列出可从该书网站下载的kernel_qiskit.ipynb
Jupyter 笔记本的 6-2a 。我们在这一部分使用 Qiskit,然后在 Rigetti 森林中使用一个例子。首先,让我们导入一些库,调用qasm
模拟器,并初始化一些参数。
from qiskit import ClassicalRegister, QuantumRegister, QuantumCircuit
from qiskit import execute
from qiskit import BasicAer
q = QuantumRegister(4)
c = ClassicalRegister(4)
backend = BasicAer.get_backend('qasm_simulator')
Listing 6-2aLibraries for and Initialization kernel-qiskit.ipynb
状态准备
以特定编码准备一个状态可以产生有趣的内核。一些基于核的学习算法是基于实例的(即,最终模型保留一些或所有训练实例,并在实际预测中起作用)。因此,支持向量机(SVM)是很好的例子,因为它们是定义两个类别之间的边界的训练实例。
为了构造基于实例的分类器,我们计算所有训练实例和测试实例之间的核。在这种情况下,没有实际的学习发生,并且每个预测包括整个训练集。因此,状态准备对该协议至关重要。训练实例在一个寄存器中以叠加方式编码,而测试实例在另一个寄存器中编码。让我们用下面的虹膜数据集3【13】的训练实例来继续这个例子,在第 2 和 3 章中使用了相同的实例。
为了演示,选择两个相对更容易处理的例子是方便的:我们从类 0 中取一个例子,从类 1 中取一个例子作为训练实例,如下所示。
下面是两个测试实例。
有了这些,我们现在可以定义我们的训练和测试实例,如清单 6-2b 所示。
training_set = [[0, 1], [0.78861006, 0.61489363]]
labels = [0, 1]
test_set = [[-0.549, 0.836], [0.053 , 0.999]]
Listing 6-2bTraining and Test Set Definition kernel-qiskit.ipynb
在这种情况下,我们尝试第五章中提到的振幅编码。这意味着第二训练向量被编码为 0.78861006 ∣0⟩ + 0.61489363 ∣1⟩.准备这些向量需要一个旋转,我们需要指定相应的角度。训练集的第一个元素不需要定义角度,因为它是∣1⟩状态。清单 6-2c 显示了这一点。
test_angles = [4.30417579487669/2, 3.0357101997648965/2]
training_angle = 1.3245021469658966/4
Listing 6-2cAngle Definition kernel-qiskit.ipynb
定义状态准备函数,如清单 6-2d 所示。
def prepare_state(q, c, angles):
ancilla_qubit = q[0]
index_qubit = q[1]
data_qubit = q[2]
class_qubit = q[3]
circuit = QuantumCircuit(q, c)
# Ancilla and index qubits into uniform superposition
circuit.h(ancilla_qubit)
circuit.h(index_qubit)
# Prepare the test vector
circuit.cx(ancilla_qubit, data_qubit)
circuit.u3(-angles[0], 0, 0, data_qubit)
circuit.cx(ancilla_qubit, data_qubit)
circuit.u3(angles[0], 0, 0, data_qubit)
# Flip the ancilla qubit > this moves the input
# vector to the |0> state of the ancilla
circuit.x(ancilla_qubit)
circuit.barrier()
# Prepare the first training vector
# [0,1] -> class 0
# We can prepare this with a Toffoli
circuit.ccx(ancilla_qubit, index_qubit, data_qubit)
# Flip index qubit ->
moves the first training vector to the
# |0> state of the index qubit
circuit.x(index_qubit)
circuit.barrier()
# Prepare the second training vector
# [0.78861, 0.61489] -> class 1
circuit.ccx(ancilla_qubit, index_qubit, data_qubit)
circuit.cx(index_qubit, data_qubit)
circuit.u3(angles[1], 0, 0, data_qubit)
circuit.cx(index_qubit, data_qubit)
circuit.u3(-angles[1], 0, 0, data_qubit)
circuit.ccx(ancilla_qubit, index_qubit, data_qubit)
circuit.cx(index_qubit, data_qubit)
circuit.u3(-angles[1], 0, 0, data_qubit)
circuit.cx(index_qubit, data_qubit)
circuit.u3(angles[1], 0, 0, data_qubit)
circuit.barrier()
# Flip the class label for training vector #2
circuit.cx(index_qubit, class_qubit)
circuit.barrier()
return circuit
Listing 6-2dState Preparation Function kernel-qiskit.ipynb
接下来,我们用第一个测试实例生成准备状态的电路,如清单 6-2e 所示。
from qiskit.tools.visualization import circuit_drawer
angles = [test_angles[0], training_angle]
state_preparation_0 = prepare_state(q, c, angles)
circuit_drawer(state_preparation_0)
Listing 6-2eCircuit Generation kernel-qiskit.ipynb
电路生成代码产生如图 6-7 所示的电路。
图 6-7
内核方法示例的电路
在图 6-7 中,垂直线定义了状态准备的分段,并作为屏障,以确保所有的门在该点完成。
-
测试实例在第一个屏障内准备。在从属和索引量子位之间形成均匀的叠加,它们分别是寄存器 0 和 1。测试实例与辅助设备的基态纠缠在一起。
-
在第一个和第二个栅栏之间创建第个训练实例。为此,制备了∣1⟩态,并用 Toffoli 门和 Pauli X 门与副量子的激发态和指数量子位的基态纠缠。托夫里门也被称为受控-受控-非门,描述其动作。
-
准备第二训练实例,并与第三部分中的副量子和索引量子比特的激发态纠缠。
-
类量子位在最后部分翻转,并在编码的训练实例和相应的类标签之间建立联系。
作为内核的干扰
状态准备完成后,实际预测是通过在辅助设备上应用 Hadamard 门进行的,随后进行测量。对于我们的简单示例,这是在浅内核上完成的。辅助设备在状态准备结束时处于均匀叠加状态,并与编码测试和训练实例的寄存器纠缠在一起。因此,在辅助设备上施加第二个哈达玛会干扰纠缠寄存器。以下是测量前的状态。
其中, x i 为训练实例, x t 为测试实例。有了这些信息,我们就生成了一个深度较浅的内核。首先,生成函数,如清单 6-2f 所示。
def interfere_data_and_test_instances(circuit, q, c, angles):
circuit.h(q[0])
circuit.barrier()
circuit.measure(q, c)
return circuit
Listing 6-2fFunction for Kernel with Shallow Depth kernel-qiskit.ipynb
在这一点上对副镜的测量给出了观察到 0 的概率
这将创建一个清单 6-2g 给出的内核。
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
x = np.linspace(-2, 2, 100)
plt.xlim(-2, 2)
plt.ylim(0, 1.1)
plt.plot(x, 1-x**2/4)
Listing 6-2gKernel Generation kernel-qiskit.ipynb
清单 6-2g 给出了下面的输出,这是执行分类的内核。
下一步是在辅助设备的测量上观察 0 时执行后选择,并计算测试实例属于任一类的概率。为此,我们定义一个函数来执行任务,如清单 6-2h 所示。
def postselect(result_counts):
total_samples = sum(result_counts.values())
# lambda function: retrieves only results where the
ancilla is in the |0> state
post_select = lambda counts: [(state, occurences) for state, occurences in counts.items() if state[-1] == '0']
# perform the postselection
postselection = dict(post_select(result_counts))
postselected_samples = sum(postselection.values())
print(f'Ancilla post-selection probability was found to be {postselected_samples/total_samples}')
retrieve_class = lambda binary_class: [occurences for state, occurences in postselection.items() if state[0] == str(binary_class)]
prob_class0 = sum(retrieve_class(0))/postselected_samples
prob_class1 = sum(retrieve_class(1))/postselected_samples
print('Probability for class 0 is', prob_class0)
print('Probability for class 1 is', prob_class1)
Listing 6-2hLambda Function kernel-qiskit.ipynb
这给出了选择后概率的第一个和第二个实例的结果,如清单 6-2i 所示。
circuit_0 = interfere_data_and_test_instances(state_preparation_0, q, c, angles)
job = execute(circuit_0, backend)
result = job.result()
postselect(result.get_counts(circuit_0))
Listing 6-2iFirst Instance kernel-qiskit.ipynb
以下是第一个实例的输出。
清单 6-2j 显示了选择后概率的第二个实例的代码。
angles = [test_angles[1], training_angle]
state_preparation_1 = prepare_state(q, c, angles)
circuit_1 = interfere_data_and_test_instances(state_preparation_1, q, c, angles)
job = execute(circuit_1, backend)
result = job.result()
postselect(result.get_counts(circuit_1))
Listing 6-2jSecond Instance kernel-qiskit.ipynb
以下是第二个实例的输出。
Rigetti 森林的核方法
您已经看到了在 Qiskit 中运行的例程的例子,这些例程用于从内核方法中进行推理。在第五章的中,你还瞥见了里盖蒂的森林利用qvm
和quilc
。在这种情况下,看看如何使用 Rigetti Forest 生成类似的内核方法生成的推理会很有趣。
首先,让我们在森林虚拟环境中打开三个终端,就像我们在第五章中所做的那样。我们在服务器模式下启动 QVM,在服务器模式下启动 Quilc,在 Jupyter notebook 中使用以下命令,每个命令都在各自的终端中。
-
qvm:??]
-
quic:??]
-
Jupyter 笔记本:
jupyter notebook
。然后选择 Python 3 创建一个新的 notebook 实例。
像往常一样,我们首先为kernel-qiskit.ipynb
导入所需的库,如清单 6-3a 所示。
from pyquil import Program, get_qc
from pyquil.gates import *
import cmath
import matplotlib.pyplot as plt
import numpy as np
from pyquil.api import ForestConnection
from pyquil.api import WavefunctionSimulator
from pyquil.api import QVMConnection
from tempfile import mkdtemp
import itertools
import socket
import subprocess
qvm = QVMConnection()
Listing 6-3aImport Libraries kernel_Inference_forest.ipynb
状态准备
首先,我们为编码准备一个状态,并使用以下两个向量的数据集。
下面是两个测试实例。
和以前一样,我们的目标是使用四个量子位为数据集构建一个干涉电路:辅助位、索引位、数据位和类位。
-
副量子位和索引量子位处于均匀叠加状态。
-
测试实例与辅助设备的基态纠缠在一起。
-
将身份门应用于类量子位。
-
解决方案放在一个名为
circuit
的对象中。
带电路准备的部分代码如清单 6-3bkernel_Inference_forest.ipynb
的所示。
## define a function for amplitudes
def get_amplitudes(circuit):
wf_sim = WavefunctionSimulator()
wavefunction = wf_sim.wavefunction(circuit)
amplitudes = wavefunction.amplitudes
return amplitudes
ancilla_qubit = 0
index_qubit = 1
data_qubit = 2
class_qubit = 3
training_set = [[0, 1], [np.sqrt(2)/2, np.sqrt(2)/2]]
labels = [0, 1]
test_set = [[1, 0]]
test_angles = [2*np.arccos(test_set[0][0])/2]
training_angle = (2*np.arccos(training_set[1][0]))/4
angles = [test_angles[0], training_angle]
circuit = Program()
# Create uniform superpositions of the ancilla and index qubits
circuit += H(ancilla_qubit)
circuit += H(index_qubit)
# Entangle the test instance with ground state of ancilla
circuit += CNOT(ancilla_qubit, data_qubit)
circuit += X(ancilla_qubit)
# Apply Identity to Class state
circuit += I(class_qubit)
print('Input = \n', get_amplitudes(circuit))
Listing 6-3bState Preparation kernel_Inference_forest.ipynb
清单 6-3b 打印输入。
然后扩展电路以准备第一个训练实例,并将其与副量子的激发态和索引量子位的基态纠缠,如清单 6-3c 所示。
circuit += CCNOT(ancilla_qubit, index_qubit, data_qubit)
circuit += X(index_qubit)
print('First training instance \n', get_amplitudes(circuit))
Listing 6-3cFirst instance Entanglement kernel_Inference_forest.ipynb
对于这一步,我们将训练实例作为输出。
在下一步中,电路被扩展以准备第二个训练实例,并将其与副量子位和索引量子位的激发态纠缠,如清单 6-3d 所示。
circuit += CCNOT(ancilla_qubit, index_qubit, data_qubit)
circuit += CNOT(index_qubit, data_qubit)
circuit += H(data_qubit)
circuit += CCNOT(ancilla_qubit, index_qubit, data_qubit)
circuit += CNOT(index_qubit, data_qubit)
circuit += H(data_qubit)
circuit += CCNOT(ancilla_qubit, index_qubit, data_qubit)
circuit += CNOT(index_qubit, data_qubit)
circuit += H(data_qubit)
circuit += CCNOT(ancilla_qubit, index_qubit, data_qubit)
circuit += CNOT(index_qubit, data_qubit)
circuit += H(data_qubit)
print('Second training instance \n', get_amplitudes(circuit))
Listing 6-3dFirst Instance Entanglement kernel_Inference_forest.ipynb
这一步给出了如下的第二个实例。
我们通过翻转以索引量子位为条件的类量子位来完成状态准备电路,并运行一个验证码,如果位被翻转则应该打印“否”,如果是而不是则应该打印“是”。我们首先在清单 6-3e 打开的情况下运行这段代码,然后用一个散列符号(#)求反。
circuit += CNOT(index_qubit, class_qubit)
#circuit += CNOT(index_qubit, class_qubit)
Listing 6-3eFirst instance Entanglement kernel_Inference_forest.ipynb
在第一种情况下,位翻转开启。不出所料,输出是 No。在第二种情况下,位翻转无效。是输出。
作为内核的干扰
最后一步后,测量值由下式给出
其中, x i 是训练实例, x t 是测试实例。这里,我们在辅助设备上应用 Hadamard 门来应用干扰,如清单 6-3f 所示。
circuit += H(ancilla_qubit)
print('Circuit \n', get_amplitudes(circuit))
Listing 6-3fFirst Instance Entanglement kernel_Inference_forest.ipynb
最后一步给出了以下输出。
Note
由于计算的概率性质,电路参数的值每次运行都不同。
总之,核技巧允许我们通过用另一个核函数替换一个核函数来构建各种模型。我们将状态准备和信息编码视为量子特征图。
量子k-意思是聚类
作为第二章的总结,k-means【98】是一种无监督聚类算法,它将 n 个观察值组合成 k 个聚类,确保聚类内方差最小化。给定一个数据集D∈{x1, x 2 ,…,xN}和 N 个观察值,目标是将这个数据集聚类到 k 个分区中。我们希望在一个聚类中分配一组彼此靠近的点,而在另一个聚类中分配另一组点。随机初始化 k 个形心。目标是找到集合S∈{S1, s 2 , s , K },使得集合内方差为最小值,而集合间方差为最大值
k-means 算法的量子版本是一种无监督算法,旨在根据一组未标记的训练向量将数据分类到 k 簇。在每次迭代中,训练向量被重新分配到最近的质心,然后计算新的质心,对属于当前聚类的向量进行平均。利用使用振幅编码仅需要 log N 量子位来加载 N 维输入向量的事实,它为非常高维的输入向量提供了指数级加速。使用劳埃德版本算法的经典算法的时间复杂度 O(NM)线性依赖于几个 N 特征和训练实例 M【99】。k-means 算法最消耗资源的操作是计算向量之间的距离。我们希望通过使用量子计算机检索距离来加快速度。
量子 k-means 算法有几个版本。量子 k-means 算法的一个版本利用三个不同的量子子例程来执行 k-means 聚类:交换测试、距离计算(DistCalc)和 Grover 优化(GroverOptim)。
如前所述,s wap 测试子例程基于∣0⟩.状态下控制量子位的测量概率来测量两个量子态⟨ x | y ⟩之间的重叠重叠是两个状态之间相似性的度量。如果控制量子位在∣0⟩态的概率是 0.5,就意味着∣ x ⟩和∣ y ⟩态是正交的;而如果概率是 1,那么状态是相同的。这个子程序应该重复几次,以获得一个好的概率估计值。
使用交换测试的优点是,在程序执行之前,状态∣ x ⟩和∣ y ⟩可能是未知的。控制量子位需要一个简单的测量,它有两个本征态。时间复杂度可以忽略不计,因为这个过程不依赖于代表输入状态的量子位的数量。根据等式 6.10 ,控制量子位处于∣0⟩状态的概率由下式给出
(6.12)
距离计算(DistCalc)子例程遵循交换测试,并提出一种算法来检索两个实值向量 x 和 y 之间的欧几里德距离|x—y|2。该算法由 Lloyd、Mohseni 和 Rebentrost [100]描述。
让我们讨论一下经典数据到量子态的表示。向量 x 中的经典信息被编码为【101】
在 DistCalc 子例程中,准备了两种状态,然后应用子例程交换测试,并重复该过程以获得可接受的概率估计。假设状态已经准备好,子例程交换测试不依赖于特征向量的大小。子例程 DistCalc 中的状态准备被证明具有 O (log N )时间复杂度【100】,因为经典信息被编码在N= log2N 量子位中,并且时间复杂度被期望成比例。经典算法需要 O ( N )来计算两个向量之间的欧氏距离;因此,速度呈指数级增长。
在交换测试和 DistCalc 算法之后,最后一步是运行 Grover 的优化器,它选择最近的集群质心。这就完成了量子 k-means 算法的概述。
量子 k-中位数算法
k-中值算法类似于 k-均值算法;但是,不是通过计算平均值来设置新的聚类质心,而是计算中值。k-means 算法有一个缺点。在某些情况下,计算的平均值可能位于期望区域之外,而作为中值计算的聚类质心总是属于训练向量集。它甚至对量子算法有进一步的影响,因为平均值的计算是在经典计算机上进行的。相反,中值的计算可以使用 MedianCalc 子程序[102]来实现。
k-medians 算法的 quantum 版本需要与 quantum k-means 算法相同的 quantum 子例程:Swap Test、DistCalc 和 GroverOptim,外加一个也使用 GroverOptim 的 MedianCalc。在 k-means 算法中,GroverOptim 量子最小化算法的使用是可选的;而对于 median,它可以用来选择最近的质心,并且必须用来计算 median。
摘要
这一章着眼于施密特分解,线性模型,核方法,交换测试,纠缠测量,除了一些非监督和监督量子模型的介绍。它还研究了使用 Rigetti 的 Forest SDK、QVM 和 Qiskit 进行编码。下一章着眼于先进的量子机器学习算法和方法,如 VQE,曲波,QAOA,HHL 和 qSVM 的相关应用和相关代码的 D-Wave,Forest,Qiskit 和 Cirq。
Footnotes 1
丹尼尔·马德是最初的上传者。由 Inkscape 于 2005 年 10 月 6 日在 SuSE 9.3 盒子上创建。 https://commons.wikimedia.org/w/index.php?curid=2151148
。
2
在概率论和相关领域,随机或随机过程是一个数学对象,通常被定义为一族随机变量。
3
虹膜数据集: https://archive.ics.uci.edu/ml/datasets/iris
,参考文献【13】。
**
七、QML 技术
蝴蝶计算的不是月份,而是瞬间,它有足够的时间。
—罗宾德拉纳特·泰戈尔
在我们对各种量子算法和平台的探索中,我们经历了有趣的一点,量子计算机是概率性的,意味着它可以返回多个答案。其中有些可能是你正在寻找的答案,有些可能不是。起初,这听起来像是一件坏事,因为当你问计算机同样的问题时,它会返回一个不同的答案,这不会产生信心!然而,在量子计算机中,返回多个答案可以给出关于计算机置信度的重要信息。
如果我们给计算机看一个苹果的图像,让它给同一个图像贴 100 次标签,而它给的答案是苹果 100 次,那么计算机就确信这个图像是一个苹果。但是,如果它 50 次返回答案 apple,50 次返回答案 raspberry,那么计算机就不确定我们正在向它显示的图像。如果我们给它展示一个有苹果和覆盆子的图像,它会是完全正确的!在设计能够做出复杂决策和了解世界的系统时,这种不确定性可能非常强大。
Note
本章重点介绍量子计算和机器学习的高级算法和技术。介绍了 D-Wave 的退火平台及其优化能力。D-Wave、pyQuil 和 Qiskit 中的代码从理论的角度涵盖了 VQE、QAOA 和曲波。
第六章讨论了量子线性模型和量子相位估计(QPE)的实现,特别是基于量子傅立叶变换(QFT)的算法。然而,QPE 和一些其他算法的应用并不局限于有限数量的情况;相反,常见的是,一旦数据可用于量子计算设备,就用诸如量子相位估计和矩阵求逆(HHL 算法)之类的算法对其进行处理。迄今为止, HHL 算法已经在各种量子计算机上实现。
各种各样的经典数据分析和机器学习协议通过对高维向量空间中的向量执行矩阵运算来操作。然而,这正是量子力学的全部内容!量子力学利用高维向量空间(如希尔伯特空间)中向量的矩阵运算。这些方法背后的关键成分是, n 个量子位或量子位的量子状态是 2n维复向量空间中的向量,因此,对量子位执行量子逻辑运算或测量将相应的状态向量乘以 2n×2n矩阵。
量子计算机执行常见的线性代数运算,例如傅立叶变换[116],寻找特征向量和特征值[116],以及在时间上求解 2【n】维向量空间上的线性方程组,其在 n 中是多项式,比它们最著名的经典对应项[115]快得多。后者被称为哈罗、哈西迪姆和劳埃德(HHL)算法[115]。
HHL 算法(矩阵求逆)
线性系统的量子算法首先由哈罗、哈西迪姆和劳埃德(HHL) [115]提出。HHL 算法是许多量子机器学习协议的基础,但它是一种具有许多条件的重要算法。本章着眼于算法的实现,以便更好地理解它是如何工作的以及何时有效地工作。实践练习来源于参考文献[113]和[114]。
用于反演线性方程的 HHL 算法是一个基本的子程序,支撑着许多量子机器学习算法。该算法的目标是使用量子计算机求解Ax=b,其中 x 和 b 用“粗体”表示,表示它们是向量。求解 x 的问题,尝试通过获取算子 A 的期望值,假设为埃尔米特,用 x ,x和 A x 代替直接获取的值当在量子计算机上求解时,这被认为是有用的,因为量子系统通常为一些测量提供概率。通常,这些运算符是泡利运算符 X、Y、z。然后,测量的概率可以转换为这些运算符的期望值。
HHL 算法将问题ax=b通过将向量 x 表示为量子态∣ x ⟩和向量b∈cn表示为量子态∣ b 因此,等式 Ax = b 可以通过将等式两边乘以A1AA的倒数来求解。然后,根据 HHL 算法,我们可以构造与a1∣b⟩.成正比的量子态一般来说,当 a 有零个特征值(不是平方的)时,那么该算法可以用来找到最小化[117]|a|x⟩−|b⟩|.的状态∣x⟩
如果{| v i ⟩}和{ λ i }分别是 A 的特征向量和特征值,其中 0<λI<1,那么状态∣ b ⟩可以写成特征向量的线性组合如下
HHL 算法旨在以的形式获得∣ * x * ⟩。HHL 程序使用量子子程序相位估计找到 A 的特征值,如第六章所述。
图 7-1 所示的算法使用了三组量子位:单个辅助量子位,一个存储 A 的特征值的寄存器,以及内存量子位(给 store∣ b ⟩和∣ x ⟩).
图 7-1
HHL 算法被细分为 QPE(量子相位估计)以确定特征值,受控旋转 R y 以提取特征值信息,以及非计算以恢复相位估计
在图 7-1 中,执行以下动作。
-
量子相位估计提取 A 的特征值
-
辅助量子比特的受控旋转
-
用逆量子相位估计解算 1 。
这些步骤描述如下。
首先,由于特征值 λ i 都是二进制形式(0。a1a2a3……)∣λI⟩=∣a1a2a3由于谱定理说每个埃尔米特矩阵都有一个特征向量的正交基,我们可以写出矩阵,其中 κ 是矩阵 A 的条件号 2 。为了更好地形象化这一点,让我们用这本书网站上的 Jupyter 笔记本
HHL_qiskit.ipynb
做一些练习。代码改编自赵等人3【113】并在 Qiskit 中完成。*
如果你对不同的编码选项感兴趣,谷歌的 Cirq 教程在 GitHub [119]上的 https://github.com/quantumlib/Cirq/blob/master/examples/hhl.py
有 HHL 算法实现的全面展示。
我们通过对一个 2 × 2 矩阵求逆来建立方程Ax=b的解,其中 anb
。矩阵𝐴被编码为一个哈密顿量,而𝑏在一个寄存器中。我们总共需要五个量子位和一个经典寄存器用于选择后操作,另一个量子位和一个额外的经典寄存器用于创建交换测试,以将结果与理想状态进行比较。
import numpy as np
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit import execute
from qiskit import BasicAer
π = np.pi
q = QuantumRegister(6)
c = ClassicalRegister(2)
hhl = QuantumCircuit(q, c)
Listing 7-1aLibraries and for HHL_qiskit.ipynb
在下一步骤中,执行相位估计以在附加寄存器中映射(或编码)矩阵𝐴的特征值。量子相位估计算法执行以下映射
(7.1)
其中∣ u ⟩是某酉算子 U 的一个特征向量,具有未知的特征值eI2πφ??I表示复平面而不是指数。
等式 7.1 中 kets 上的上标与存储相应状态的寄存器名称有关。
在 HHL 算法中,输入寄存器以特征向量的叠加开始(即)。酉算子由 e * iAt 给出。为避免分母中 2 π 的因子,往往将演化时间t0 取为 2 π 。在此步骤中,我们考虑时钟寄存器控制的哈密尔顿模拟门 U 。有了这些假设,最初的目标是创建一个应用于不同持续时间的哈密顿量的𝐴叠加。因为本征值总是位于复单位圆上,所以本征结构由叠加中不同演化的分量揭示。因此,条件哈密顿量的演化可以表示为张量态积上的
∣ψ0⟩⊗∣b⟩.这一操作使状态∣b⟩在由状态∣ψ*0⟩.确定的时间段𝜏内由哈密顿量𝐴控制
由于状态∣ψ0⟩具有 0 和 T 之间所有可能时间步长的叠加,因此结果是所有可能演变的叠加。我们需要适当选择时间步长𝑇的数量和总演化时间t?? 以允许对特征值的二进制表示进行编码。
作为 HHL 算法的一部分,在量子相位估计 (QPE)过程中的最后一步,应用逆傅立叶变换,将编码𝐴特征值的相位写入新寄存器。
应用 A 下的相位估计有助于计算λn。因此,在这一步,我们在一个附加的寄存器中对矩阵𝐴的特征值进行编码。图 7-2 显示了相位估计电路。
图 7-2
HHL 算法的 QPE 电路
在特征值为 2 的幂的 2 × 2 矩阵中,我们选择 t 0 = 2 π 和 T = 4 来获得具有两个受控进化的精确结果。
# Superposition
hhl.h(q[1])
hhl.h(q[2])
# Controlled-U0
hhl.cu3(-π / 2, -π / 2, π / 2, q[2], q[3])
# hhl.cu1(3 * π / 4, q[2], q[3])
hhl.cp(3 * π / 4, q[2], q[3])
hhl.cx(q[2], q[3])
#hhl.cu1(3 * π / 4, q[2], q[3])
hhl.cp(3 * π / 4, q[2], q[3])
hhl.cx(q[2], q[3])
# Controlled-U1
hhl.cx(q[1], q[3]);
Listing 7-1bSuperposition and Quantum Circuit Definition HHL_qiskit.ipynb
然后,量子逆傅立叶变换将相位写入寄存器。
hhl.swap(q[1], q[2])
hhl.h(q[2])
hhl.cp(-π / 2, q[1], q[2])
hhl.h(q[1]);
Listing 7-1cInverse QFT HHL_qiskit.ipynb
QFT 分解后系统的状态由近似给出,其中
。这里,∣ * b * ⟩是𝐴.本征基中向量 b 的编码
下一步是对∣λI⟩进行运算,使其反转。在这种情况下, A 的特征值为 λ 1 = 2 = 10(二进制)和 λ 2 = 1 = 01。特征值的倒数为和λ2—1= 1⟹2λ2—1= 10。在这种情况下,交换门获得状态
,该状态编码特征值的倒数。
hhl.swap(q[1], q[2]);
在应用 A 下的相位估计来计算λn之后,我们将副量子位围绕 Y 轴旋转的角度。完成辅助量子位的这种受控旋转是为了获得接近如下的状态
(7.2)
hhl.cu3(0.392699, 0, 0, q[1], q[0]) # Controlled-RY0
hhl.cu3(0.19634955, 0, 0, q[2], q[0]); # Controlled-RY1
Listing 7-1dAncilla Rotation HHL_qiskit.ipynb
执行量子计算时,除了将算法所需信息存储在最终寄存器中的操作之外,您必须取消所有操作的计算。这一步是必要的,以防寄存器纠缠在一起,影响结果。在本例中,步骤 2 中的 QPE 必须是未计算的。在不计算之后,最终期望的状态是
(7.3)
hhl.swap(q[1], q[2])
hhl.h(q[1])
hhl.cp(π / 2, q[1], q[2]) # Inverse(Dagger(Controlled-S))
hhl.h(q[2])
hhl.swap(q[2], q[1])
# Inverse(Controlled-U1)
hhl.cx(q[1], q[3])
# Inverse(Controlled-U0)
hhl.cx(q[2], q[3])
hhl.cp(-3 * π / 4, q[2], q[3])
hhl.cx(q[2], q[3])
hhl.cp(-3 * π / 4, q[2], q[3])
hhl.cu3(-π / 2, π / 2, -π / 2, q[2], q[3])
# End of Inverse(Controlled-U0)
hhl.h(q[2])
hhl.h(q[1]);
Listing 7-1eUncompute Action on QPE HHL_qiskit.ipynb
接下来,我们通过投影到期望的状态∣1⟩.来执行后期选择为了获得预期的解决方案,需要手动准备正确的输出状态,以对结果执行交换测试。
# Target state preparation
hhl.rz(-π, q[4])
hhl.p(π, q[4])
hhl.h(q[4])
hhl.ry(-0.9311623288419387, q[4])
hhl.rz(π, q[4])
# Swap test
hhl.h(q[5])
hhl.cx(q[4], q[3])
hhl.ccx(q[5], q[3], q[4])
hhl.cx(q[4], q[3])
hhl.h(q[5])
hhl.barrier(q)
hhl.measure(q[0], c[0])
hhl.measure(q[5], c[1]);
Listing 7-1fPsot-Selection HHL_qiskit.ipynb
执行两个测量:一个用于后选择的辅助寄存器,另一个输出交换测试的结果。为了计算成功概率,我们定义了一些辅助函数。
def get_psuccess(counts):
try:
succ_rotation_fail_swap = counts['11']
except KeyError:
succ_rotation_fail_swap = 0
try:
succ_rotation_succ_swap = counts['01']
except KeyError:
succ_rotation_succ_swap = 0
succ_rotation = succ_rotation_succ_swap + succ_rotation_fail_swap
try:
prob_swap_test_success = succ_rotation_succ_swap / succ_rotation
except ZeroDivisionError:
prob_swap_test_success = 0
return prob_swap_test_success
Listing 7-1gSuccess Functions HHL_qiskit.ipynb
最后,电路在模拟器上运行。
backend = BasicAer.get_backend('qasm_simulator')
job = execute(hhl, backend, shots=100)
result = job.result()
counts = result.get_counts(hhl)
print(get_psuccess(counts))
Listing 7-1hCircuit
run HHL_qiskit.ipynb
这给出了 1 的输出。
辅助设备的测量值为 1 表示矩阵转换成功。这使得系统处于与解向量∣ x ⟩.成比例的状态在许多情况下,你对∣ x ⟩的单个向量元素不感兴趣,而只对某些性质感兴趣。
如果测量辅助量子位,如果观察到 1,那么每个本征态除以 λ n ,这影响了逆。在施加幅度放大之后,状态准备电路需要被施加以成功的次数是,其相当于矩阵的条件数 κ 。
HHL 算法需要o[(logn)2]个量子步骤来输出∣ x ⟩,相比之下,在经典计算机上使用最知名的方法找到 x 需要o(nlogn个步骤。
谈到 HHL 算法,有几个事实需要考虑。
-
HHL 算法性能的一个重要因素是条件数κ 。随着 κ 的增加,矩阵 A 趋向于向不可逆矩阵增长,并且解成比例地变得不稳定。条件数大的矩阵称为病态矩阵。
-
从量子态∣ x ⟩中寻找 x 的完整答案需要 O ( N )次重复重构 x 的 N 分量。对 HHL 的推广,如最小二乘拟合,通过允许输出比输入维数少得多来回避这个问题。
-
需要准备输入向量 b,或者在量子计算机上,或者使用 qRAM(量子 RAM),这可能是昂贵的。
-
矩阵必须是条件良好的,并且必须能够高效地模拟e—iA。
曲波
二次无约束二元优化(曲波),也称为无约束二元二次规划,将金融和经济学中广泛应用的各种组合优化问题统一到利用量子计算领域中应用的优化模型的机器学习中[103]。近年来,曲波已经发展成为一个数学公式,可以包含工业、科学和政府中发现的各种各样的重要组合优化问题(见 Anthony 等人【104】和 Kochenberger 等人【105】)。一旦将曲波解算器放入适当的曲波框架中,它们的力量可以用来有效地解决许多重要问题。
曲波模型作为量子退火领域的坚实基础具有无可争议的重要性,并且已经成为神经形态计算的研究主题。曲波模型是 D-Wave 开发的量子计算机和 IBM 开发的基于门的量子计算机实验的核心。商业领域的 IBM、Google、Amazon、Microsoft、D-Wave 和 Lockheed Martin 以及公共领域的 Los Alamos 国家实验室、Oak Ridge 国家实验室、Lawrence Livermore 国家实验室和 NASA 的 Ames 研究中心等组织正在探索曲波模型与量子计算之间关系的后果。目前,量子计算社区中的各种研究机构正在深入研究曲波模型,并评估其作为传统建模和解决方法的替代方案的有效性。
伊辛模型
曲波模型的重要性在于它能够包含组合优化中的几个模型。卢卡斯[110]表明,曲波模型等价于伊辛模型4【111】。伊辛模型是关于统计力学的铁磁性的非物理数学模型,在物理学中起着突出的作用。该模型使用离散变量来表示自旋状态的磁偶极矩(为+1 或–1)。自旋状态被组织成一个格子,这样每个自旋可以和它的邻居相互作用(见图 7-3 )。
图 7-3
伊辛模型
伊辛模型不符合实际的物理系统。这是一个巨大的(正方形)站点网格,其中每个站点可以处于两种状态之一。每个站点都标有索引 i ,这两种状态分别称为–1 和+1。例如,当我们声明自旋σI= 1 时,我们的意思是第 i 个位置处于状态-1。磁行为可以通过把每个原子想象成一个自旋来理解,指向上或下。自旋可能希望逆着磁场或与磁场对齐。邻近的自旋会互相影响,但较远的自旋不会。因为自旋-自旋相互作用出现在两个自旋之间,所以有必要对成对的位置求和,以找到它对能量的总相互作用。作为一个物理类比,伊辛模型可以被认为是一个简化的玩具磁铁。
伊辛模型的能量根据其哈密顿量定义如下
(7.4)
其中 J 代表自旋-自旋相互作用, h 代表外场, σ 是每个格点上的单个自旋。对于伊辛模型,自旋在以下范围内给定值:σI∈{-1,+1}。从数学的角度来看,在这个方案中, h 和 J 是可调常数,其中一个 h 分配给每个自旋和一个 J 分配给每个相互作用的自旋对。
伊辛模型中的曲波
采用 Ising 模型形成量子粒子以促进量子系统中的计算是通过以下调整实现的。
-
Define QUBO as follows.
(7.5)
其中 q 是量子位变量 0 和 1(而不是伊辛模型中的 1 和+1)。
-
将 α 和 β 定义为可调常数。
-
Perform conversion between the 0/1 variables (for QUBO) and spins (Ising) via the following.
(7.6)
因此,由最先进的曲波解决方法有效解决的广泛的最优化问题被在物理学应用中出现的问题的一个重要领域加入。根据 Kochenberger 和 Glover [109],曲波模型解决的优化问题包括以下内容,但不限于。
-
最大独立集问题
-
最大切割问题
-
图着色问题
-
数字分割问题
-
线性排序问题
-
团划分问题
-
聚类问题
-
模块化最大化
-
相关聚类
-
其他的
-
-
任务分配问题(分布式计算机系统)
关于它与量子计算的关系,D-Wave 发表的一些论文谈到了在量子计算的背景下使用伊辛模型的优化和机器学习应用,例如[112]。
曲波模型可以用下面的表达式来表示。
(7.7)
其中 x 是一个二进制决策向量的变量。 Q 是一个元素为常数的方阵 a ij 。通常假设 Q 是对称的或者是上三角形式,这可以在不失一般性的情况下实现。
当对于所有的 i 和 j ,除了 i = j ,aij被替换为(aij+aJi/时,就产生了一个对称形式线性项的系数出现在矩阵的主对角线上,我们忽略任何常数。
上三角形式:为所有 i 和 j ,用 j > i ,aij替换为(aij+aJi);然后所有的aij对于 j < i 都被替换为 0。如果矩阵是对称的,那么这个动作将矩阵对角线上方的aij值加倍,主对角线下方的所有值都被设置为 0。
让我们看一个对称矩阵的例子。考虑下面的优化问题。
其中变量 x 、 y 、 z 、 w 为二进制;也就是说,它们只能有值 0 和 1。
为了用曲波解决这个优化问题,我们观察以下事实。
-
f 是二元变量的二次函数。它有一个线性部分(5x3y8z6w)和一个二次部分(4xy+8xz+2yz+10zw)。
-
Binary variables satisfy x = x2, y = y2, z = z2 and w = w2, since their values can be either 0 or 1. Hence,
-
现在,我们能够将模型写成如下矩阵形式。
-
结式矩阵可以写成方程 7.7 的形式,其中 x 为二元变量的列向量。注意,线性项的系数出现在 Q 矩阵的主对角线上。
唯一的约束是将 0 或 1 作为决策变量的值的限制,除此之外曲波是一个无约束的模型。曲波的所有问题数据都包含在 Q 矩阵中。
-
模型的解如下:f= 11;x=w= 1; y = z = 0。
本章稍后将使用 pyQuil 探讨这个问题的编程解决方案。
曲波最优化问题的其他例子可以如下。
-
一个变量的曲波:5 x + 8
-
两个变量的曲波:10+3x—6y+9xy
-
三变量曲波:2xy+3xz-yz
这些特征使得曲波成为组合优化问题的特别有吸引力的建模框架,作为经典约束公式的替代。总之,曲波模型属于 NP 难问题。这一点的实际意义在于,除了小的问题实例之外,为寻找“最优”解而设计的精确解算器(例如,商用的 CPLEX 解算器( www.ibm.com/uk-en/analytics/cplex-optimizer
))很可能不成功。使用这种方法,实际规模的问题可能会运行几天甚至几周,而不会产生高质量的解决方案。幸运的是,正如我们在接下来的章节中所披露的,通过使用旨在在适度的计算机时间内找到高质量但不一定是最优的解决方案的方法,正在取得令人印象深刻的成功。正如你在本章中看到的,这些方法为经典和量子计算的结合提供了有价值的可能性。
变分量子电路
在第六章中,你看到了从伊辛模型中得到的量子优化的灵感,这与铁磁性的物理学有关。通常,薛定谔方程可以用来研究和模拟单个量子粒子的行为和演化。然而,现实世界的现象依赖于许多不同量子系统之间的相互作用。对模拟物理系统的多体哈密顿量的研究是凝聚态物理、分子动力学和模拟的中心主题。变分方法在量子机器学习实践和当前研究中至关重要,因此,我们花了一些时间试图解决这些想法的基础。
目前,由于希尔伯特空间的特性,多体哈密顿量本质上很难在经典计算机上建模和研究,希尔伯特空间的维度随着系统中粒子的数量呈指数增长。因此,对于经典计算机来说,寻找这些运算的特征值变得不可行。这就是量子计算机变得非常有用的地方。它允许我们用更少的开销来研究这些多体系统,因为所需的量子比特数只是多项式增长。对于一台完美的量子计算机来说,各种各样的任务应该成为日常工作的一部分。
然而,尽管使用量子计算机解决与多体物理和分子模拟相关的问题似乎很有吸引力,但当前和近期的量子计算机远非完美,并存在不完美之处。这就是为什么在近期有噪声的量子计算机上运行需要深层电路的长算法仍然是一个挑战(目前是紧张研究的主题)。使用低深度量子电路制备量子态是小型量子计算机最有前景的近期应用之一,特别是如果电路足够短,门的保真度足够高,可以在没有量子纠错的情况下执行。这种量子态制备可用于变分方法,优化电路中的参数,以最小化给定问题哈密顿量的构造量子态的能量。
自 2013 年以来,已经研究和开发了一种算法(见参考文献[120]和[121]),这些算法专注于从不完美的量子计算机中获得优势。基本思想是运行一个简短的门序列,其中一些门被参数化。然后,该过程读出结果,在经典计算机上调整参数,并在量子硬件上用新参数重复计算。通过这种方式,在量子和经典处理单元之间创建了一个迭代循环,从而创建了如图 7-4 所示的经典-量子混合算法。
图 7-4
混合量子经典系统的变分电路
这些算法被称为变分以反映改变参数的变分方法。
这种量子态制备可用于变分方法,优化电路中的参数,以最小化给定问题哈密顿量的构造量子态的能量。由于这些原因,变分电路也被称为参数化量子电路。
这些变分算法如图 7-5 所示,为我们提供了问题的近似解。虽然不是 100%完美,但他们可以给我们接近完美的答案。这就是它们如此有用的原因,尤其是 VQE 算法。
图 7-5
量子变分算法的图解(来源[122])
图 7-5 是一个变分量子算法 (VQA)的示意图。该过程的第一步是开发一个 VQA 来定义一个成本(或损失)函数 C 。成本函数 C 对问题的解决方案进行编码。在下一步中,提出了 ansatz(即,依赖于一组可以优化的连续或离散参数 θ 的量子操作。然后在混合量子经典循环中用来自训练集的数据训练该 ansatz,以解决以下优化任务
(7.8)
以下是 VQA 输入:对问题的解决方案进行编码的成本函数 C ( θ ),其参数被训练以最小化成本的 ansatz,以及可选地(如果需要),在优化期间使用的一组训练数据。在循环的每一次迭代中,量子计算机都会有效地估计成本或其梯度。这些信息的输出被输入到一个经典的计算机中,该计算机利用优化器的能力来导航成本导数并解决方程 7.8 中的优化问题。一旦满足终止条件,VQA 估计问题的解的输出。输出的形式取决于具体的任务。图 7-5 显示了一些最常见的输出类型。
在第四章中介绍的成本函数将可训练参数 θ 的值映射为实数。成本定义了一个超曲面,通常称为成本景观(见图 7-5 )。优化器的任务是在成本范围内导航并获得全局最小值。不失一般性,成本可以表示为
(7.9)
其中 f k 是对任务进行编码的函数。离散和连续参数组成 θ 。{Ok}定义了一个集合的可观测量。 U ( θ )是参数化的酉。{ρk}由输入状态(来自训练集)组成。对于一个给定的问题, f k 可以不同,这可能导致有用成本。
图 7-6
ansatz 的示意图
由于成本函数对 VQAs 很重要,所以选择 ansatz 也很重要。ansatz 的形式定义了 θ 参数,以及如何训练它们以最小化成本。ansatz 的具体结构通常取决于任务。在某些情况下,关于问题的信息可以定制一个 ansatz,这是一个受问题启发的 ansatz 。其他一些 ansatz 架构是通用的,与问题无关,这意味着即使没有相关信息可用,也可以使用它们。对于等式 7.9 中的成本函数,参数 θ 可以被编码在酉 U ( θ )中,该酉被应用于量子电路的输入状态。如图 7-6 所示, U ( θ )一般可以表示为 S 依次应用单位的乘积。
(7.10)
有了,
(7.11)
其中ℍ n 为厄米算子, W n 为非参数化酉。
变分量子本征解算器(VQE)
变分量子本征解算器(VQE) [121]是一种混合量子经典算法,是优化从化学到金融等各种应用的工具。VQA 方法仅限于寻找低能本征态,并有助于最小化任何可以表示为量子可观测的目标函数。目前,确定这些量子变分算法在什么条件下成功是一个公开的问题。探索这类算法是对噪声中等规模量子 (NISQ)计算机研究的关键部分。
在量子力学中,变分法是寻找量子系统低能态的典型经典方法。这种方法背后的基本思想是将试验波函数(或如前所述的 ansatz)定义为一些参数的函数,以找到这些参数的值,该值使相对于这些参数的能量期望值最小化。这个最小化的安萨兹然后是对最低能量本征态的近似,期望值作为基态能量的上限。因此,实际上,我们最终会找到特定哈密顿量的最小特征值的上界及其对应的特征向量。VQE 帮助我们确定量子系统的基态能量。
在 VQE,对于给定的安萨兹波函数,使能量最小化的一组参数就是问题的解。该算法由两个部分组成:一个量子电路和一个经典优化器。量子电路执行两项任务。
-
它以给定的变分参数为输入,生成系统的安萨兹波函数。
-
它测量能量(或哈密顿量的期望值)相对于波函数的能量。
测量结果然后被馈送到经典优化器中,以生成一组新的变分参数,这给出了较低的能量估计。图 7-7 显示了参考文献【121】中原理图中的原始 VQE 过程。
图 7-7
变分量子本征解算器(来源[121])
已知最小化期望〈h〉的特征向量对应于具有最小特征值[121]的h的特征向量。因此,在图 7-7 中,可以尝试所有可能的试波函数∣ ψ ⟩,以找到给出最小期望值的特征向量。我们如何创建这些试用状态?在该算法中,试验状态是从参数化电路中创建的。不同的波函数或安萨兹态可以通过改变参数来创建[121]。
经典的反馈决策是一些改变量子态制备参数的优化方法。对于不同的量子模块,该算法计算每个泡利项的期望值,然后通过经典计算机使用经典加法器将它们相加(见图 7-7 )。然后,算法返回到经典反馈决策,为量子态准备选择更好的参数。VQE 重复这一过程,直到优化方法满意所获得的结果。
图 7-8 展示了在量子计算机上模拟一维晶格上相互作用的自旋半费米子的物理过程。该系统的哈密顿量由哈伯德 5 模型【123】描述,其中除了晶格位置之间的跳跃,具有相反自旋的费米子通过现场库仑势相互作用。
图 7-8
哈伯德模型的 VQE 过程示例
如图 7-8 所示,哈伯德模型的 VQE 算法从一组变分参数 θ (0) 开始。然后创建酉算子∣ψ(θ(0))⟩=u(θ【0】)∣ψ1⟩所代表的安萨兹电路,生成安萨兹波函数∣ ψ ( θ 其通常被选择为非相互作用哈密顿量H0 的基态。 系统的能量是通过测量哈密顿量相对于安萨兹的期望值得到的,这严格大于或等于基态能量 E0;也就是说,
在最后一步中,经典优化器根据先前的参数和能量生成一组新的参数θ【1】。这些新参数被反馈到安萨茨电路中,以产生一个能量更低的新波函数。这里,优化器被建模为基本搜索算法,其中参数空间被随机采样。重复整个过程,直到能量e(θ(n))足够接近基态能量 E 0 ,使得θ(n)为问题的解,通过首先生成波函数∣υ,可以提取系统的任何信息
回到伊辛模型、物理学和分子基态能量,中心任务是找到给定哈密顿量 H ( 不要与哈达玛门混淆)的基态(最低能量本征态)!).
(7.12)
其中λ??g为基态本征值,∣ ψ ⟩为本征态。研究基态给了我们关于系统低能性质的信息。一旦∣ ψ ⟩已知,就可以从波函数推导出物理性质。但方程 7.12 中的挑战是,一般来说 λ G 的值和本征态都是未知数;因此,获得这些的估计是最重要的。状态的能量估计可以通过计算哈密顿量的期望值来获得。
(7.13)
其中, E 为能量本征态。 E 0 为基态。变分原理指出
(7.14)
现在,哈密顿量 H 可以由任何埃尔米特矩阵的性质描述如下。
(7.15)
因此, H 的期望值可以表示为
(7.16)
方程 7.16 表示任何可观测状态的期望值都可以用与 H 相关的特征值作为权值的和来表示。并且,根据量子力学的假设,已知线性组合中的权重必须大于或等于零。这就是 VQE 算法的工作原理。
为了从计算的角度更深入地研究哈密顿量,哈密顿量可以用泡利算符的张量积之和(泡利项)来表示。
(7.17)
其中,泡利算符以其标准形式表示。
给定方程 7.17 的哈密顿量和状态∣ ψ ⟩,VQE 中的目标是测量 H 的期望值
(7.18)
从方程 7.18 可以推测,VQE 算法为每个泡利项构建一个量子电路,并计算相应泡利项的期望值。然后,算法将所有计算出的泡利项的期望值相加,得到 H 的期望值。该算法针对不同的试验波函数(ansatz 状态)重复运行估计 H 的期望值的例程。
状态准备电路的参数由经典计算机控制。在每一步中,经典计算机通过使用一些优化方法来改变参数,以创建具有比之前的 ansatz 状态更小的期望值的 ansatz 状态。这个过程允许经典计算机和量子计算机一起工作,以实现算法的目标,即找到基态能量。这就是为什么 VQE 是一个混合经典量子算法。
现在我们已经看了 VQE 的理论和实践,探索不同格式的 VQE 的例子是很好的,因为 VQE 是量子机器学习中最重要的概念之一。
VQE 与 Qiskit
在这个例子中,任务是使用变分量子本征解算器方法(VQE)确定矩阵 M 的最低本征值,其中
作为第一章的总结,泡利矩阵由下式给出
;
;
两个量子位的向量可以表示为
作为第一步,矩阵 M 被分解成两个量子比特算子的和。
(7.19)
其中⊗表示张量积, α , β , γ , λ 是未知系数, I 是单位泡利矩阵,下标 1,2 表示算符作用的特定量子位。使用张量积的矩阵表示来解决这种分解。
为了形象化这种表示,在清单 7-2a 中为VQE_qiskit.ipynb
Jupyter 笔记本文件定义了泡利矩阵、 𝑋 、 𝑌 、 Z ,以及常见的库调用。
from qiskit import *
import numpy as np
# Define the Pauli matrices
X = np.array([[0,1],[1,0]])
Y = np.array([[0,-np.complex(0,1)],[np.complex(0,1),0]])
Z = np.array([[1,0],[0,-1]])
Listing 7-2aLibraries and Pauli Matrices for VQE_qiskit.ipynb
下一步,我们创建这些运算符的张量积,如清单 7-2b 所示。
# Compute the tensor product of the Pauli matrices
XX = np.kron(X,X)
YY = np.real(np.kron(Y,Y)) # This will be a real matrix
ZZ = np.kron(Z,Z)
II = np.identity(4)
print("The XX gate is: \n{} \n".format(XX))
print("The YY gate is: \n{} \n".format(YY))
print("The ZZ gate is: \n{} \n".format(ZZ))
Listing 7-2bLibraries and Pauli Matrices for VQE_qiskit.ipynb
清单 7-2b 给出了下面的输出。
清单 7-2c 验证我们通过检验所知道的;也就是说, M 可以分解成以下两个量子比特算符的和。
(7.20)
# This is the decomposition of the "M" matrix
M = (XX+YY+ZZ-II)/2
print('M = \n',M)
print('')
Listing 7-2cDecomposition of M in VQE_qiskit.ipynb
反过来,它给我们一个确认作为输出,这是矩阵 M 。
计算算子的期望值
随着 M 的分解到位,是时候利用变分定理确定 M 的最低特征值上的界了。为了完成这个任务,我们需要知道 M 对于不同试探波函数的期望值。我们从量子力学的基础知识中知道,算符𝑀对基态波函数∣ ψ ( θ )⟩的期望值具有如下形式。
其中 E ( θ )是矩阵 M 的期望值。∣ ψ ( θ )⟩是由角度 θ 参数化的变分波函数。
其中最简单的可计算期望值是z1⊗z2 算子。当作用于∣ ϕ ⟩ = ( a , b , c , d )给定的状态,使得⟨ ϕ | ϕ ⟩ = 1 时,期望值由下式给出
项 a 2 和 d 2 分别对应于状态∣00⟩和∣11⟩的概率,而 b 2 和 c 2 是状态∣01⟩和∣10⟩.的概率
为了制定模拟,按如下方式计算概率。
从分解试验中取出一片叶子来确定试验状态的其他算符的期望值,我们寻求将所有两个量子比特的算符分解成以下形式。
其中 U 是特定于 Q 的酉矩阵。以下分解与该任务相关。
(7.21)
(7.22)
其中 H 是哈达玛门,并且
等式 7.20 、 7.21 、 7.22 允许我们将原矩阵 M 写成算子之和,如下。
根据这些恒等式,矩阵 M 的期望值被给出为
新的进化状态在哪里
和
VQE 的 Ansatz
在计算出矩阵 M 的期望值后,下一步是定义一个试探波函数作为 ansatz。
清单 7-2d 给出了 ansatz 电路的可视化。
# Visualize Ansatz-circuit
theta=np.pi
q = QuantumRegister(2)
c = ClassicalRegister(2)
circuit = QuantumCircuit(q,c)
circuit.h(q[0])
circuit.rz(theta,q[0])
circuit.cx(q[0],q[1])
circuit.x(q[1])
circuit.barrier()
circuit.draw()
Listing 7-2dAnsatz Circuit Visualization VQE_qiskit.ipynb
这个代码片段给出了下面的输出,作为我们的 ansatz 电路。
清单 7-2e 定义了一些函数,方便我们对 M 的期望值进行评估(如注释中所述)。
def anzatz(circuit,q,c,theta):
'''
The Anzatz wave function
|psi > = (I X)(CX)(Rz(theta) I)(H I)|00>
'''
circuit.h(q[0])
circuit.rz(theta,q[0])
circuit.cx(q[0],q[1])
circuit.x(q[1])
circuit.barrier()
return circuit
def measure_ZZ(circuit,N_shots=2**10,simulator_backend='qasm_simulator'):
'''
Measures the expectation value of ZZ on the 2-qubit states
<ZZ> = the number of ( 00 ) and (11) states, minus the number of (01) and (10) states
normalized over the number of trials
'''
simulator = Aer.get_backend(simulator_backend)
result = execute(circuit,backend=simulator,shots=N_shots).result()
items =result.get_counts().items()
s = 0
for key, counts in items:
s+= (-1)**(int(key[0])+int(key[1]))*counts
s = s/N_shots
return s
def hamiltonian(theta,N_shots=2**10):
'''
The hamiltonian for the problem that corresponds
to our matrix M:
M = (1/2)*(XX+YY+ZZ-II)
The hamiltonian is computed by separating it into three components
according to the discussions in the previous cells.
'''
q = QuantumRegister(2)
c = ClassicalRegister(2)
## 0.5*XX component
circuit_xx = QuantumCircuit(q,c)
circuit_xx = anzatz(circuit_xx,q,c,theta)
circuit_xx.h(q[0])
circuit_xx.h(q[1])
circuit_xx.measure(q,c)
E_XX = 0.5*measure_ZZ(circuit_xx,N_shots=N_shots)
## 0.5*YY component
circuit_yy = QuantumCircuit(q,c)
circuit_yy = anzatz(circuit_yy,q,c,theta)
circuit_yy.sdg(q[0])
circuit_yy.h(q[0])
circuit_yy.sdg(q[1])
circuit_yy.h(q[1])
circuit_yy.measure(q,c)
E_YY= 0.5*measure_ZZ(circuit_yy,N_shots=N_shots)
# 0.5*ZZ component
circuit_zz = QuantumCircuit(q,c)
circuit_zz = anzatz(circuit_zz,q,c,theta)
circuit_zz.measure(q,c)
E_ZZ = 0.5*measure_ZZ(circuit_zz,N_shots=N_shots)
# The - 1/2 comes from the fact that <psi|II|psi> = 1
# it is always a constant
return (E_XX+E_YY+E_ZZ-0.5)
Listing 7-2eFunction Definition VQE_qiskit.ipynb
量子电路模拟在下一步运行,如清单 7-2f 所示。
# Generate several thetas, and find the best set of parameters
import matplotlib.pyplot as plt
# The number of trials to run
N_shots = 2**10
# Generate theta grid
theta = np.linspace(0.0,2*np.pi,200)
E = np.zeros(len(theta))
# Calculate the expectation value of the Hamiltonian for different theta
for k in range(len(theta)):
E[k] = hamiltonian(theta=theta[k],N_shots=N_shots)
# Plot the results
plt.title('Expectation value vs Angle',fontsize=15)
plt.ylabel('Expectation value of H',fontsize=15)
plt.xlabel('Theta (radians)',fontsize=15)
plt.plot(theta,E,label='Number of shots: {}'.format(N_shots))
plt.legend()
plt.show()
# Determine the lowest bound from varying theta
print('='*100)
print('The minimum bound on the lowest eigenvalue of M is E0={},\n'.format(min(E)))
print('The parameter that corresponds to this energy is theta={:0.2f} Rads'.format(theta[np.argmin(E)]))
print('='*100)
Listing 7-2fMinimum Expectation Value of M VQE_qiskit.ipynb
这个代码片段给出了下面的输出作为我们的期望值。
输出中哈密顿量的最小能量的最小值出现在波函数 ansatz 中大约 θ = π 处,以 2 作为期望值的下限。能量以任意单位表示。
现在发现 M 的最小特征值的下界为E0 = 2.0,可以直接计算最小特征值来验证我们的解。
w, v = np.linalg.eig(M)
print('='*100)
print('Minimum eigenvalue using classical computer: Lambda={:0.2f}'.format(min(w)))
print('The minimum bound of the Eigenvalue from the quantum computing simulations is E={:0.2f}'.format(min(E)))
print('='*100)
Listing 7-2gAnsatz Circuit Visualization VQE_qiskit.ipynb
列表 7-2g 给出了以下输出,验证了量子电路的下限与矩阵的最低特征值一致。
VQE 与谷歌 Cirq
谷歌的 Cirq 根据佩鲁佐等人(2014 年)[121]和韦克尔等人(2015 年)[147]的研究,提供了一个关于 VQE 实现的综合教程。
教程中的变分算法试图通过以下三个步骤获得给定 ansatz 状态的目标函数值。
-
准备 ansatz 状态。
-
进行测量,从哈密顿量中的一些项中取样。
-
转到 1。
他们还指出了一个重要的方面,即在没有量子相位估计的情况下,你不能总是直接测量哈密顿量(参见第六章)。因此,人们通常依赖期望值的线性来测量步骤 2 中的部分哈密顿量。人们总是需要重复测量来获得期望值的估计值。
本教程展示了您可以使用量子计算机来获得 ansatz 的目标函数的估计。然后可以在外部循环中使用它来获得目标函数的最低值的参数。对于这些值,您可以使用最佳的 ansatz 来产生问题的解决方案的样本,这获得了目标函数的最低可能值的一个有希望的良好近似。本教程在https://quantumai.google/cirq/tutorials/variational_algorithm
【148】完整代码完成。强烈建议您访问此页面,并尝试 Cirq 中的 VQE 实现示例。
为了方便阅读本教程的材料,经 Google 许可,相关的开源 Jupyter 笔记本代码【148】已经作为variational_algorithm_Cirq.ipynb
包含在本章中。
VQE 与里盖蒂森林
本章前面讨论了 Qiskit 中的 VQE 编程。鉴于 VQE 在量子机器学习和分子建模中的重要性,了解其他平台如何实现它是有帮助的。我们首先看一个类似于 Qiskit 练习的 VQE 的 Rigetti 森林实现,然后看一个利用 VQE 的分子建模练习。随着本书的深入,我们将 VQE 用于各种平台相关的各种 QML 应用程序和库。
首先,我们在森林虚拟环境中打开三个终端,就像我们在第五章中所做的一样。我们在服务器模式下启动 QVM,在服务器模式下启动 Quilc,在 Jupyter notebook 中使用以下命令,每个命令都在各自的终端中。
-
qvm:??]
-
quic:??]
-
Jupyter 笔记本:
jupyter notebook
。选择 Python 3 来创建一个新的笔记本实例。
让我们先来看一个使用 Forest 的基本 VQE 实现。为了运行一些优化任务,我们需要导入 Rigetti 的 Grove 库。
像往常一样,我们首先导入所需的库,用 Pauli Z-gate 定义一个矩阵,并定义一个 ansatz,如清单 7-3aVQE_pyquil.ipynb
的所示。
# Variational-Quantum-Eigensolver
import numpy as np
from scipy.optimize import minimize
from pyquil.api import QVMConnection
import pyquil.api as api
from pyquil.gates import *
from pyquil import Program, get_qc
from grove.pyvqe.vqe import VQE
# Create connection with QVM
qvm = QVMConnection()
qc = get_qc('2q-qvm')
# Define a matrix
from pyquil.paulis import sZ
H = sZ(0)
# Define an ansatz
from pyquil.gates import RY
def ansatz(params):
return Program(RY(params[0], 0))
Listing 7-3aAnsatz Circuit Visualization VQE_pyquil.ipynb
在下一步中,我们定义了用于计算期望值的函数,与我们在 Qiskit 中为我们的试验 ansatz 定义的 10,000 个测量值相同。这显示在清单 7-3b 中。
# Function calculating expectation value
def expectation(params):
# Define number of measurements
samples = 10000
# Define program
prog = ansatz(params)
# Measure
ro = prog.declare('ro', 'BIT', 1) # Classical registry storing the results
prog.measure(0, ro[0])
# Compile and execute
prog.wrap_in_numshots_loop(samples)
prog_exec = qc.compile(prog)
ret = qc.run(prog_exec)
# Calculate expectation
freq_is_0 = [trial[0] for trial in ret].count(0) / samples
freq_is_1 = [trial[0] for trial in ret].count(1) / samples
return freq_is_0 - freq_is_1
# Test of expectation value function
test = expectation([0.0])
print(test)
Listing 7-3bFunctions VQE_pyquil.ipynb
清单 7-3b 生成 1.0 作为输出,证实了我们的估计。
列表 7-3c ,绘制了期望值与参数值(即 θ 的值)的 VQE 图。
# Draw expectation alue against parameter value
params_range = np.linspace(0.0, 2 * np.pi, 25)
data = [expectation([params]) for params in params_range]
import matplotlib.pyplot as plt
plt.xlabel('Parameter value (Thetas)')
plt.ylabel('Expectation value')
plt.plot(params_range, data)
plt.show()
Listing 7-3cPlot the VQE curve VQE_pyquil.ipynb
我们得到下面的输出,它与 Qiskit 的情况非常相似。
输出中哈密顿量的最小能量的最小值出现在波函数 ansatz 中的 θ = π 处,以 1 作为期望值的下限。能量以任意单位表示。
正如在 VQE 的两个例子(Qiskit 和 Forest)中所看到的,可以根据参数计算的期望值的数量是有实际限制的。需要更多参数值的大得多的哈密顿量的期望值的计算是一个挑战。这可以通过使用优化算法来解决。例如,可以通过 SciPy optimize 包应用 Nelder-Mead [149]优化算法,如清单 7-3d 所示。
# Eigenvalue Optimization
initial_params = [0.0]
minimum = minimize(expectation, initial_params, method='Nelder-Mead',
options={'initial_simplex': np.array([[0.0], [0.05]]), 'xatol': 1.0e-2})
print(minimum)
Listing 7-3dNelder-Mead Optimization VQE_pyquil.ipynb
内尔德-米德 6 方法【149】用单工操作。单纯形在二维是三角形,在三维是四面体。维基百科页面说明了单纯形如何移向最小值;它不断改变它的大小和形状,在接近最小值时变得更小。如果满足两个条件,则搜索成功。
-
单纯形的大小最多为
xatol
,是 SciPy 库的一部分。它根据绝对误差定义了结果的精度。例如,如果 xatol 为 0.01,并且该方法返回最小值的位置为[1.33,2.56],则有希望(但不确定)实际最小值的坐标在 1.32–1.34 和 2.55–2.57 之间。 -
单纯形顶点处的函数值差最多为
fatol
。
这意味着单纯形变得更小,而目标函数值在其顶点几乎保持不变。
清单 7-3d 给出了下面的输出,其中fun
是最小特征值。
到目前为止,我们已经处理了无噪声 QVM 公式。Rigetti Forest 还提供了向模拟中添加噪声的选项。因为 VQE 算法旨在用于近期的量子计算平台,所以考虑使用特定噪声模型的 QVM 运行是有帮助的。清单 7-3e 是在 pyQuil 中设置吵闹的 QVM 的代码片段。
pauli_channel = [0.1, 0.1, 0.1] #10% chance of each gate at each timestep
noisy_qvm = api.QVMConnection(gate_noise=pauli_channel)
#Verify Simulator is indeed noisy
p = Program(X(0), MEASURE(0, 1))
noisy_qvm.run(p, [0, 1], 10)
Listing 7-3eNoisy-QVM VQE_pyquil.ipynb
清单 7-3e 介绍了每个门在每个时间戳有 10%的机会。测量∣0⟩状态的代码输出示例显示了正在测量的位 0,这表明 QVM 模拟器确实有噪声。
通过在角度 θ 和期望值的范围内运行for
循环,可以生成噪声 VQE 的曲线图。要实现这一点,必须使用以下命令将 Forest 的grove
库安装在与 QVM 和 Quilc 相同的目录中。
$ pip install quantum-grove
安装命令和初始输出如下面的屏幕截图所示,其中,grove
库被安装在一个名为qml
的虚拟环境中。
实际一代的 VQE 情节与嘈杂的 QVM 是留给你作为一个练习。请参考 https://grove-docs.readthedocs.io/en/latest/vqe.html
处的 Grove 文档。
分子系统的 VQE
作为展示 VQE 型算法实际价值的一个快速示例,下面是一个获得分子系统最低能量状态的精确近似值的练习。提高运行这种算法的效率的能力对药物和药物开发以及材料工程方法的改进具有直接的积极影响。
本代码改编自 https://grove-docs.readthedocs.io/en/latest/vqe.html
的 Grove 文档。Grove 允许我们定义自己的哈密顿量,并使用 sigma Z 和 sigma Y 的泡利矩阵获得结果。列表 7-3e 展示了哈密顿量的选择如何导致不同的测量结果。理论上,如果可以确定氢分子哈密顿量的泡利矩阵分解,那么我们就能够用适用于该分子的哈密顿量的组合来代替所用的哈密顿量。因此,要么可以生成参数变化的图形,并用肉眼发现结果,要么我们可以使用从 VQE 函数接收的数据尝试不同的最小化方法。
清单 7-3f 给你一个 VQE 的味道,帮助解决一个真实世界的分子模拟练习,其中我们循环期望值 10,000 次。
# Molecular Systems Solutions
from pyquil.paulis import sY
initial_angle = [0.0]
#Hamiltonian is sigma Y
hamiltonian = sY(0)
vqe_inst = VQE(minimizer=minimize,
minimizer_kwargs={'method': 'nelder-mead'})
#ansatz is rotation by X
def small_ansatz(params):
return Program(RX(params[0], 0))
#looping from 0 to 2 pi
angle_range = np.linspace(0.0, 2 * np.pi, 20)
data = [vqe_inst.expectation(small_ansatz([angle]), hamiltonian, 10000, qvm)
for angle in angle_range]
plt.xlabel('Angle [radians]')
plt.ylabel('Expectation value')
plt.plot(angle_range, data)
plt.show()
Listing 7-3fMolecular System VQE_pyquil.ipynb
列表 7-3f 生成以下曲线图,作为分子哈密顿量的期望值相对于参数 θ 变化的输出。
总之,VQE 是一种混合量子经典算法[121],可以找到给定哈密顿量的最小特征值和相应的特征向量。该算法的主要应用之一是寻找分子的基态能量。目前,在 NISQ 时代,我们的量子计算能力仅限于处理非常嘈杂的量子位,因为它们没有有效地与环境隔离。这种限制为诸如 VQE 算法等利用小深度电路的算法提供了巨大的优势。
由于计算成本极高,模拟大型量子系统或求解大规模线性代数问题等应用对经典计算机来说极具挑战性。量子计算机有望开启这些应用,尽管容错量子计算机可能在几年内都不会出现。目前,量子设备有严重的限制,包括有限的量子位数量和限制电路深度的噪声过程。
分子模拟中的 VQE 实际上利用了量子计算机的特性,因为它是一种“近期”量子计算算法。这意味着它不依赖于数千个量子位、可靠且可扩展的纠错、长的相干时间或大的电路深度。这些算法类型具有很高的潜力来提高运行在量子平台上的应用程序的效率。
QAOA
量子交替算子 Ansatz(QAOA)——也称为量子近似优化算法——最初由 Farhi 等人[69]在 2014 年提出,用于获得组合优化问题的近似解。后来,它被概括为一个独立的 ansatz [124],被证明是计算通用的[125]。QAOA 是 VQE 算法家族中最重要的例子之一。
QAOA 是量子计算机的一种浅回路变分算法,受量子退火的启发。量子系统的演化受薛定谔方程支配;∣ψ(t)⟩=e??iht/∣0⟩(其中ℏ是约化普朗克常数)描述了一个系统在应用哈密顿量 H 一段时间 t 后所处的状态。给定这些条件,哈密顿仿真输出一系列计算门,这些计算门实现了酉U=e-iHt,为了便于计算,我们在适当的单位中取= 1。
总哈密顿量是厄米算符,通常是大量单个哈密顿量的总和。作为一个例子,哈密顿量 H 可以等于(H1+H2),这又可以使用 Lie 乘积公式 7 表示如下。
(7.23)
由于方程 7.23 的极限是无穷大,所以在量子计算机上实现这个公式时需要对级数进行截断。截断程序在模拟中引入误差,该误差可由最大模拟误差 ϵ 限定,该误差由以下条件定义
这个截断的过程如图 7-9 所示,被称为截断。它被广泛用于在量子计算机上模拟非交换哈密顿量。通用的三值化公式如下所示
(7.24)
图 7-9
Trotterization 来源[122]
用一个简单的例子就可以说明 Trotterization 和方程 7.20 的重要性。假设我们想要模拟一个哈密顿量H=X0+Z0,其中 X 和 Z 是泡利矩阵,下标是应用哈密顿量的量子位的标签。在这种情况下,不可能单独模拟每个哈密顿量,因为泡利门 X 和 Z 不交换。在这种情况下,通过在短时间内在X0 和Z0 之间反复切换来进化整个哈密顿量。
在 QAOA 框架中,绝热路径被离散在一些 p 步骤中,其中 p 是精度的度量,并且每个离散时间步骤 l 具有两个参数: β l 和 γ l 。和一般的 VQE 一样,经典的变分算法在量子硬件运行结束时,根据观察到的能量来优化这些参数。因此,QAOA 可以被解释为一个Trotterized*绝热变换,其中 troterized 的阶数 p 决定了解的精度。
QAOA 算法的目标是通过顺序应用问题酉和混合器酉
【127】将输入状态∣ψ0⟩映射到给定问题的基态,哈密顿量 H p 。这给出了下面的 ansatz,它是方程 7.10 和 7.11 的形式的。
(7.25)
在哪里,
从根本上说,期望的动作是在绝热条件下离散化(即单独分离和区分)由H(t)=(1-t)H0+tH1给出的时间相关的哈密顿量。这是通过旋转单元来实现的。例如,对于时间步长 t 0 ,酉可以拆分为U(t0)=U(H0,β0)U(H1)我们可以在随后的时间步骤中继续这样做,最终将进化分割成这样的块。
(7.26)
哈密顿量 H 0 称为驱动或混合哈密顿量, H 1 称为成本哈密顿量。最简单的混合哈密顿量由给出。通过在两个哈密尔顿函数之间交替,混合哈密尔顿函数驱动状态朝向相等的叠加,而代价哈密尔顿函数试图找到它自己的基态。在优化参数的最后,离散化的演化产生绝热路径的近似。
请注意,由于哈密顿量中的多体项和有限的器件连接性,将单位分解成本征门可能会导致更长深度的电路。然而,QAOA 的优势之一是某些问题的可行子空间小于完整的希尔伯特空间,这种限制可能导致更好的执行算法。
Rigetti Forest 的实践 QAOA
现在我们已经了解了 QAOA 的理论方法,最好有一个实际的动手方法。我们与里盖蒂森林和 QVM 合作。和以前一样,我们在服务器模式下启动 QVM 和 Quilc,并在各自的终端中使用以下命令启动 Jupyter 笔记本。
像往常一样,我们首先导入所需的库,用泡利 Z 门定义一个矩阵,并定义量子位的数量,如清单 7-4aQAOA_pyquil.ipynb
的所示。
#Libraries
import numpy as np
from functools import partial
from pyquil import Program, api
from pyquil.paulis import PauliSum, PauliTerm, exponential_map, sZ
from pyquil.gates import *
from pyquil import Program, get_qc
from pyquil.api import ForestConnection
from pyquil.api import WavefunctionSimulator
from pyquil.api import QVMConnection
from scipy.optimize import minimize
np.set_printoptions(precision=3, suppress=True)
qvm = QVMConnection()
# Number of qubits
n_qubits = 2
Listing 7-4aLibraries and Qubits QAOA_pyquil.ipynb
接下来,我们定义一些量子位上的混合哈密顿量。为了达到这个目的,我们使用 Pauli-X 算符,它的系数表示给定量子位的横向场强度。这个算符对所有的量子位都不起作用,除了给定的那个。下面是两个量子位上混合哈密顿量的定义。
Hm = [PauliTerm("X", i, 1.0) for i in range(n_qubits)]
Listing 7-4bLibraries and Qubits QAOA_pyquil.ipynb
作为一个例子,伊辛问题可以最小化。伊辛问题由成本哈密顿量定义,其最小值在
时达到。
J = np.array([[0,1],[0,0]]) # weight matrix of the Ising model. Only the coefficient (0,1) is non-zero.
Hc = []
for i in range(n_qubits):
for j in range(n_qubits):
Hc.append(PauliTerm("Z", i, -J[i, j]) * PauliTerm("Z", j, 1.0))
Listing 7-4cDefine Ising Problem QAOA_pyquil.ipynb
下一步,我们计算迭代的和
。为此,我们可以使用 pyQuil
exponential_map
函数来构建两个函数,这两个函数接受 γ 和 β 并返回和
。
exp_Hm = []
exp_Hc = []
for term in Hm:
exp_Hm.append(exponential_map(term))
for term in Hc:
exp_Hc.append(exponential_map(term))
Listing 7-4dDefine Ising Problem QAOA_pyquil.ipynb
然后,我们为 p 设置值,并初始化 γ i 和 β i 参数。
n_iter = 10 # number of iterations of the optimization procedure
p = 1
β = np.random.uniform(0, np.pi*2, p)
γ = np.random.uniform(0, np.pi*2, p)
Listing 7-4eInitializing Values QAOA_pyquil.ipynb
初始状态是所有状态∣q1q2…qn⟩的均匀叠加,并且可以在∣0⟩.状态的所有初始量子位上使用哈达玛门来创建
initial_state = Program()
for i in range(n_qubits):
initial_state += H(i)
Listing 7-4fInitializing Values QAOA_pyquil.ipynb
接下来,我们通过组合由函数evolve
给出的不同酉矩阵来创建电路。
def create_circuit(β, γ):
circuit = Program()
circuit += initial_state
for i in range(p):
for term_exp_Hc in exp_Hc:
circuit += term_exp_Hc(-β[i])
for term_exp_Hm in exp_Hm:
circuit += term_exp_Hm(-γ[i])
return circuit
Listing 7-4gCircuit Definition QAOA_pyquil.ipynb
接下来,创建一个evaluate_circuit
函数,该函数采用由 γ 和 β 串联而成的单个向量beta_gamma
,并返回⟨ψ|h|c|ψ⟩=hc|ψ⟩,whereψ
def evaluate_circuit(beta_gamma):
β = beta_gamma[:p]
γ = beta_gamma[p:]
circuit = create_circuit(β, γ)
return qvm.pauli_expectation(circuit, sum(Hc))
Listing 7-4hCircuit Evaluation QAOA_pyquil.ipynb
最后,我们优化角度。
result = minimize(evaluate_circuit, np.concatenate([β, γ]), method='L-BFGS-B')
result
Listing 7-4iOptimize Angles QAOA_pyquil.ipynb
这为我们提供了以下输出。
以下是对结果的解释。
使用找到的最佳参数创建电路。
circuit = create_circuit(result['x'][:p], result['x'][p:])
statevector_simulator
后端,以显示电路创建的状态。
wf_sim = api.WavefunctionSimulator(connection=fc)
state = wf_sim.wavefunction(circuit)
print(state)
这给出了一个输出。
该输出显示状态大约为。这里, φ 是一个相位因子,它不影响概率。这个结果对应的是经典问题的两个解的一致叠加:( σ 1 = 1, σ 2 = 1)和(σ1= 1,σ2= 1)。最后,我们评估运算符
和
。
print(qvm.pauli_expectation(circuit, PauliSum([sZ(0)])))
print(qvm.pauli_expectation(circuit, PauliSum([sZ(1)])))
这为我们提供了以下输出。
输出显示两者都近似等于零,这是一个预期的结果,因为两个自旋状态都是-1 和 1/2 的时间。输出对应于典型的量子行为,其中
曲波的 QAOA 解决方案
现在,我们来看一个用 QAOA 解决曲波问题的例子。近年来,量子粒子在解决离散组合优化任务方面受到了极大的关注,这些任务在物流行业中广泛存在。量子粒子也因为在近期量子硬件上易于实现而变得流行。
我们在本章前面看了一个计算曲波的例子。这个练习的重点是使用里盖蒂·QVM 和 SciPy 库解决同一个曲波问题。概括一下,下面是我们的优化问题的例子。
其中变量 x 、 y 、 z 、 w 为二进制;也就是说,它们只能有值 0 和 1。为了解决曲波的优化问题,我们创建了如下矩阵形式的模型。
Note
线性项的系数出现在矩阵的主对角线上。唯一的约束是将 0 或 1 限制为决策变量的值;否则,曲波就是一个不受约束的模特。曲波的所有问题数据都包含在矩阵中。
为了解决这个问题,我们开始导入一些库并定义与 QVM 的通信,如 Jupyter 笔记本格式的清单 7-5a 。
# Import Libraries and communicate with QVM
import numpy as np
import matplotlib.pyplot as plt
from pyquil.paulis import PauliSum
from pyquil.api import WavefunctionSimulator
from pyquil.api import ForestConnection
from pyquil.api import QVMConnection
from scipy.optimize import minimize
from pyquil.unitary_tools import lifted_pauli
from scipy.optimize import minimize
np.set_printoptions(precision=3, suppress=True)
qvm = QVMConnection()
Listing 7-5aLibraries QUBO_pyquil.ipynb
接下来,我们使用func_y
函数定义矩阵形式,使用另一个函数num_2_bin
定义系数的二进制值映射。然后我们画出结果。
def func_y(config):
matr = np.array([[-5, 2, 4, 0], [2, -3, 1, 0], [4, 1, -8, 5], [0, 0, 5, -6]])
return config @ matr @ config
def num_2_bin(num):
bin_str = np.binary_repr(num, width=4)
bin_arr = np.array([int(x) for x in bin_str])
return bin_arr
Listing 7-5bQUBO Solution QUBO_pyquil.ipynb
列表 7-5b 为相应变量值的最小化 f 生成以下输出图。
图 7-10 显示了模型的解如下:f= 11;x=w= 1; y = z = 0。 x = 1, y = 0, z = 0, w = 1 为位串 1001;也就是数字 9 的二进制表示,其对应的函数值是f= 11。
图 7-10
曲波 QAOA 解决方案
监督学习:量子支持向量机
数据分类是最重要的机器学习工具之一,因为它可以识别、分组和研究与用例相关的新数据,这些用例多种多样,如计算机视觉问题、医学成像、药物发现、手写识别、地统计学和许多其他领域。在机器学习中,最常见的数据分类方法之一是支持向量机(SVM)。SVM 是一种监督学习方法,并且特别有用,因为它允许通过使用超平面来分离两个类别,从而将输入的训练数据集分类为两个类别之一。与超平面一起使用的支持向量本质上是用于最大化类之间距离的数据点。
第 5 和 6 章讨论了将经典数据映射到特征地图中。量子支持向量机(QS VM)使用特征映射将数据点映射到量子电路。qSVMs 是多项理论和实验研究的主题[129]。qSVMs 使用量子比特而不是经典比特来解决问题。许多 qsvm[130]、[131]、[132]和量子启发的 SVM [133]算法在量子域中利用内核技巧。Havlicek 等人[135]发表了一篇关于 qSVM 和监督学习的优秀研究论文。
生成基于 qSVM 的练习需要以下条件。
-
缩放、归一化和主成分分析
-
生成核矩阵
-
估计用于 QSVM 分类的一组新数据点(测试数据)的核
在 QSVM 分类阶段,经典 SVM 产生分离超平面而不是量子电路,这里量子计算机被使用了两次。在第一种情况下,为所有训练数据对估计核。第二次,为新的日期或测试数据估计内核。
在第二章所涵盖的经典 SVM 的延续中,我们考察了将知识转化到量子领域的要求。
-
要完成这个任务,首先要考虑的是如何将经典数据点 x 转化为量子数据点∣ ψ ( x )⟩.这可以通过创建包含 ψ ()的电路 C ( ψ ( x )来实现,其中 ψ 是应用于经典数据的任何经典函数。
-
接下来,用参数 ϑ 构建一个参数化的量子电路 V ( ϑ )来处理数据。
-
执行测量,为每个识别经典数据标签的经典输入 x 返回经典值-1 或+1。
-
最后,我们利用量子变分电路 (QVC)的概念,为这个问题定义了一个形式为v(ϑ)c(ψ(x))∣0⟩.的 ansatz
Note
写这本书的时候,还没有确切的实验证据证明 QSVM 提供了明显的量子优势。然而,参考文献[135]的作者认为,如果我们使用特征映射会有优势,因为否则,我们就不需要量子计算机来构建内核。出于这个原因,也因为今天大多数库都为量子 SVM 提供了一个独特的内置函数,所以这里不探讨这方面的实际代码。如果您有兴趣尝试 qSVM 的实践代码,请参考 Qiskit 文档,网址为https://qiskit.org/documentation/tutorials/machine_learning/01_qsvm_classification.html
【136】.
在写这本书的时候,建立用例来说明 qSVM 相对于经典 SVM 的优势是一个非常活跃的研究领域。例如,欧洲粒子物理研究所(CERN)大型强子对撞机(LHC)的研究人员正在积极工作,看看与他们的实验需求相关的巨大计算挑战是否可以在量子计算机的帮助下得到解决。为此,他们已经成功地将 qSVM 用于 ttH (H 到两个光子),希格斯耦合到 LHC 的顶夸克分析[138]。
很多数据分析和机器学习技术都涉及到优化。为此,使用 D-Wave 处理器通过量子退火来解决组合优化问题多年来一直备受关注。
D 波量子计算
D-Wave Systems 成立于 1999 年,生产利用量子退火的量子计算设备,量子退火已被用于执行深度量子学习协议超过十年。
今天存在的量子计算有不同的定义。常见的格式是利用门模型的量子计算。这是经典门模型的扩展,其中计算门应用于量子位寄存器,以执行由量子位组成的量子状态的任意转换。你熟悉经典计算中的门模型计算的基本方法。量子计算领域中的门模型是一种自然延伸。
另一个常见的范例是量子退火,通常被称为绝热量子计算,尽管存在细微的差异。量子退火通过使工程挑战相对容易地扩大规模来解决特定的问题。他们的最新系统 Advantage 在 2020 年拥有 5000 个超导量子位,相比之下,门模型量子计算机的超导量子位不到 100 个。D-Wave 十多年来一直在建造超导量子退火炉,该公司目前保持着量子比特数量的记录。
量子退火是 D-Wave 量子计算机所基于的计算模型,它通过将多体量子系统从一个容易表征的系统逐渐演化为一个难以表征的系统来工作。在这个模型中,有效的开放系统采样需要量子系统的快速演化。
图 7-11 说明了退火过程。
图 7-11
量子退火(改编自[137])
在退相干引发热化之前,当接近共振点时,量子态可以被隧穿。蓝色的阴影说明了能级的占有情况。在图 7-11 中,图 A 显示了量子态在热退火中必须穿越局部最小值的标准,而相干量子态在接近共振时可以隧穿。图 7-11 中的图 B 说明了相干效应通过与环境的相互作用而衰减,导致系统能级占有率的概率分布遵循吉布斯分布。
深度量子学习的一个本质特征是,它不需要大型通用量子计算机。量子退火器不是通用量子计算机(UQC),但比任何 UQC 都更容易构建和升级(见图 7-11(??)中的图表 A)。量子退火器非常适合实现深度量子学习器,早在 2011 年就已经通过 D-Wave 上市。D-Wave 量子退火器是一种可调谐的横向伊辛模型,可以通过编程产生经典系统和某些量子自旋系统的热态。
从硬件角度来看,D-Wave 实现了使用超导金属超导回路的通量量子位。这个金属环允许电流顺时针或逆时针流动,这就是信息在量子位上编码的方式。量子玻尔兹曼机器[139],具有能够实现通用量子逻辑的更一般的可调耦合,目前处于设计阶段[140]。Biamonte 等人[140]的一项研究确立了非量子随机(也称为非随机 ) D 波量子退火硬件的当代实验目标,该硬件可能能够实现通用量子玻尔兹曼机器。此外,片上硅波导与数百个可调干涉仪构成线性光学阵列。专用超导量子信息处理器可以用来实现量子近似优化算法。
D-Wave 计算平台的能力被 Google、NASA 和 Los Alamos 等许多公司用来解决问题。实现相干伊辛模型的 QNN 云也实现了量子光学。它的限制不同于超导架构。一些这样的研究和工业机构已经利用他们的量子系统平台产生了经过验证的优化和量子机器学习的好处。
D-Wave 已经通过 Leap quantum cloud service 为 38 个国家的用户提供了他们的量子计算服务(正如本书撰写时的情况)。用户可以浏览到 https://cloud.dwavesys.com/leap/
,请求获得他们现实生活中量子硬件上免费但有限的使用时间和资源。图 7-12 显示成功登录后的 D-Wave Leap 界面。
图 7-12
D-Wave Leap 网站 https://cloud.dwavesys.com/leap/
关于他们的系统和文件的更多信息可以在https://cloud.dwavesys.com/leap/resources
【142】获得。库和示例代码可以在 GitHub 上的 Ocean SDKhttps://github.com/dwavesystems
【141】中获得。写这本书的时候,D-Wave ( www.dwavesys.com
)上有超过 250 个用户开发的量子应用,包括航班调度、选举建模、量子化学模拟、汽车设计、预防性医疗保健、物流等等。
基本上,量子退火的工作原理是首先将一个问题编码到候选解的搜索空间中,其中最优解是需要最低能量的解。D-Wave 的处理器通过叠加同时遍历所有可能的解决方案,找到能量最低的解决方案,从而找到这个最佳解决方案。
D 波量子退火系统的编程
当对 D-Wave 量子退火系统进行编程时,用户将一个问题映射为对“最低能量谷”的搜索,对应于最佳可能结果。量子处理单元同时考虑所有的可能性,以确定形成这些关系所需的最低能量。这些解是对应于所发现的量子位的最佳配置或能量分布中的最低点的值。这些值通过网络返回给用户程序(参考 D-Wave 网站[143])。因为量子计算机是概率性的,而不是确定性的,所以计算机会在很短的时间内返回许多非常好的答案——确切地说,一秒钟内会有数千个样本。这不仅提供了找到的最佳解决方案,还提供了可供选择的其他有效方案。D-Wave 的量子计算机对于解决最优化和 NP 难问题特别有用,例如旅行售货员问题 (TSP)和 Max-Cut。
D-Wave 的开源 Ocean SDK ( https://github.com/dwavesystems/dwave-ocean-sdk
),可在 GitHub 和 Leap ( www.dwavesys.com/take-leap
)上使用,有内置的算法模板,能够使用熟悉的编程语言 Python 开发新代码,有助于应用程序开发。图 7-13 展示了 D-Wave 量子计算平台的整体架构及其 Ocean 软件堆栈。
图 7-13
D-Wave 平台和海洋软件栈(来源[143])
该程序是根据一个具有如下一般结构的数学表达式建模的(参考 D-Wave 文档[141],[142])。
(7.27)
用于定义编程模型([141]、[142])的方程 7.27 的组成部分在表 7-1 中列出。
表 7-1
程序设计模型
|qI
|
量子位
|
参与退火循环并进入两种可能的最终状态之一的量子位:{0,1}
|
| --- | --- | --- |
| qIqj | 耦合器 | 允许一个量子位影响另一个量子位的物理设备。 |
| 一个 一个我一个 | 重量 | 与程序员控制的每个量子位相关联的一个实值常数。它影响量子位坍缩成两种可能的最终状态的趋势。 |
| bij | 力量 | 与编程器控制的每个耦合器相关的一个实值常数。它控制一个量子位对另一个量子位的影响。 |
| 目标 | 目标 | 在退火周期中最小化的实值函数。 |
D-Wave Ocean 软件是一套开源 Python 工具,用于使用量子计算机解决困难问题,帮助重新表述应用程序的问题,以获得量子计算机或量子经典混合工作流的解决方案。它还处理应用代码和量子计算机之间的通信,如图 7-14 所示。
图 7-14
海洋软件栈的可编程性(改编自[142])
以下是关于一个问题如何在 D-Wave 量子计算机上运行的结构指南。
-
这些问题被公式化为伊辛模型或曲波模型。
-
当问题被编程到 D-Wave QPU(量子处理单元)上时,常数 a 和 b 被转换成电压、电流和磁场。
-
量子位自旋从它们的叠加态开始。
-
量子位自旋进化,探索问题空间。
-
在退火周期结束时,系统处于基态,或者是所提交问题的低激发态。
-
自旋的状态被读取,可选的后处理被应用,并被传送回用户。
-
这可以每秒进行数百或数千次
图 7-15 以 NP-hard 旅行推销员问题为例,描述了量子退火系统[38]中端到端编程的全栈工作流。TSP 将在本章后面的实践编码中描述。
图 7-15
全栈量子退火工作流程(改编自[38])
D-Wave 的系统利用了曲波。作为一个快速回顾,以下是 D-Wave 的编程过程所利用的曲波属性。
-
变量的最高幂是 2。
-
没有对变量应用任何约束。
-
变量值在{0,1}内。
-
最小化或最大化目标函数。
在这一章的前面,曲波背后的理论包括一个使用对称形式的例子。D-Wave 编程通常利用定义曲波的上三角形式。在图 7-16 中,图表 A 显示了曲波的矩阵表示。图 B 是同一表达式的图示:2x+3y-4z+xy-2.5xz+7yz。
图 7-16
曲波论 D-Wave(改编自[142])
以下是图 7-16 中图 A 的矩阵表示中的规则。
-
二次项出现在非对角线上。
-
对于 D-Wave 的海洋,上对角线就足够了。
-
在这种表示法中,常数项和变量名通常被省略。
-
线性项出现在对角线上。
当用图形表示曲波时,如图 7-16 中的图 B,我们遵守以下规则。
-
二次项出现在边缘。
-
在这种表示法中,常数项和变量名通常被省略。
-
线性项出现在节点上。
被描述为描述经典或量子系统的能量的对象的哈密顿量,也描述了由依赖于时间(即,状态演化依赖于时间)的薛定谔方程表达的随时间演化的系统:。
如果薛定谔方程解了一段时间 t ,其中U=e??iHt/,那么我们就得到一个辅助状态演化的幺正算符。注意,这里的哈密顿量描述了系统的能量:h∣ψ(t)⟩=e∣ψ(t)⟩,其中 E 为能量。
绝热量子计算
典型地,在绝热过程中,条件演化得足够慢,以使系统适应新的配置。例如,在一个量子力学系统中,我们可以从某个哈密顿量 H i 开始,慢慢地把它变成另一个哈密顿量 H i + 1 。最简单的演变可以用线性时间表来描述。
h(t=(1-t)【I】+
**哈密顿量的时间依赖性使得薛定谔方程解的推导相当复杂。绝热定理指出,含时哈密顿量的缓慢演化(变化)应该有助于保持所得到的动力学简单。因此,如果我们开始接近一个本征态,系统保持接近一个本征态。这意味着,如果在某些条件下系统将在基态E?? 启动,那么系统将停留在E0 或非常接近于E0 的状态。
两个状态(例如基态和第一激发态)之间的能级差异被称为能隙或能隙。如果在过渡期间 H ( t )对于每个 t 具有非负间隙,并且变化适当缓慢地发生,则系统应该停留在基态。如果时间相关间隙由δt给出,则速度限制的近似值按比例缩放为。
绝热定理允许一些相当不寻常的事情:可以获得一个容易求解的量子多体系统的基态,哈密顿量变成了我们感兴趣的系统。作为一个例子,可以从简单的哈密顿量开始,因为它的基态是相等的叠加态。作为一个利用 D-Wave 的
dimod
API、 8 的动手示例,我们在两个站点上进行了尝试,如 Jupyter 笔记本Annealing_QC_DWave.ipynb
所示。
import numpy as np
np.set_printoptions(precision=3, suppress=True)
X = np.array([[0, 1], [1, 0]])
IX = np.kron(np.eye(2), X)
XI = np.kron(X, np.eye(2))
H_0 = - (IX + XI)
λ, v = np.linalg.eigh(H_0)
print("Eigenvalues:", λ)
print("Eigenstate for lowest eigenvalue", v[:, 0])
Listing 7-6aLibraries and Arrays Annealing_QC_DWave.ipynb
以下是 NumPy 文档[155]中代码块使用的一些函数的描述。
-
numpy.kron()
或np.kron():``NumPy
中两个数组的克罗内克乘积。计算 Kronecker 积,这是一个复合数组,由第二个数组的块按第一个数组的比例组成。 -
numpy.linalg.eigh
()或numpy.linalg.eigh
():返回复厄米(共轭对称)或实对称矩阵的特征值和特征向量。
清单 7-6a 给出了以下作为特征值和本征态计算的输出。
一旦知道了本征值和本征态,哈密顿量就可以慢慢地转化为经典的伊辛模型,从而得到整体解。绝热量子计算过程利用了这一现象,并可以在最终哈密顿量与方程 7.4 中的一般形式相同的情况下进行计算。
通过遵守速度限制和保证有限间隙来实现哈密顿量的量子计算系统可以被认为近似等同于门模型。
量子退火
绝热量子计算的一个主要限制是速度极限的计算,这是很重要的。计算速度极限通常比解决寻找感兴趣的哈密顿量的基态的主要问题更难。此外,还有工程上的限制,例如量子位元的消相干和温度控制。量子退火通过绕过限速挑战解决了这些挑战。它反复重复退火(或跃迁),直到收集到几个样本,能量最低的自旋组态被选为优先解。然而,通常不能保证这就是基态。
量子退火的软件栈与门模型量子计算机略有不同,如图 7-15 所示。代替量子电路,抽象层次是以经典伊辛模型的形式,并且感兴趣的问题以同样的形式被公式化。伊辛模型的经典解算器是模拟退火炉。
import dimod
J = {(0, 1): 1.0, (1, 2): -1.0}
h = {0:0, 1:0, 2:0}
model = dimod.BinaryQuadraticModel(h, J, 0.0, dimod.SPIN)
sampler = dimod.SimulatedAnnealingSampler()
response = sampler.sample(model, num_reads=10)
print("Energy of samples:")
print([solution.energy for solution in response.data()])
Listing 7-6bEnergy Annealing_QC_DWave.ipynb
这里,我们使用dimod
API,它包含一个二进制二次模型(BQM)类,该类包含 D 波采样器使用的伊辛和二次无约束二进制优化(曲波)模型,以获得以下输出作为样本的能量。
为了在基于退火的量子系统中获得所需的解决方案,我们需要在编程期间将问题的连通性与硬件相匹配。要实现这一点,就需要找到一种将几个物理量子位组合成一个逻辑量子位的图形镜像嵌入。
次要嵌入问题的部分是 NP 难的(在下一节解释)。因此,概率方法找到了一个嵌入。例如,对于 D-Wave 生产的某些代量子退火机,量子位垂直或水平地“定向”在 QPU(量子处理单元)上,并具有包含一个 K 4,4 二分全连通图的单位单元,从每个量子位到相邻单位单元中的量子位有两个远程连接。图 7-17 显示了一个单元及其本地和远程连接。
图 7-17
嵌合图中的单位细胞(来源 D-Wave 文档[155])
图 7-17 称为嵌合图。在每一个渲染图[155]中,有两组四个量子位。每个量子位连接到另一组中的所有量子位,但不单独连接到任何一个,形成一个K4,4 图;例如,标有 0 的绿色量子位连接到粗体的量子位 4 到 7。
Chimera 图在dwave_networkx
包中以 NetworkX 图的形式提供。我们的示例绘制了图 7-17 的缩小版,利用了chimera_graph()
函数,由 2 × 2 个单位单元组成。
import matplotlib.pyplot as plt
import dwave_networkx as dnx
%matplotlib inline
connectivity_structure = dnx.chimera_graph(2, 2)
dnx.draw_chimera(connectivity_structure)
plt.show()
Listing 7-6cCells in Chimera graph Annealing_QC_DWave.ipynb
该代码片段产生了图 7-18 中的以下输出。
图 7-18
嵌合图中的 2 × 2 单位细胞
我们可以生成不同的图形——例如,4 × 4 个单位单元,如图 7-19 和connectivity_structure = dnx.chimera_graph(4, 4).
所示。然而,图 7-18 中的 2 × 2 个单位单元是为了视觉清晰。
图 7-19
嵌合图中的 4 × 4 单位细胞
接下来,我们尝试一个具有不同连接结构的图,例如,16 个节点的完整Kn图。
import networkx as nx
G = nx.complete_graph(16)
plt.axis('off')
nx.draw_networkx(G, with_labels=False)
Listing 7-6d16-node graph Annealing_QC_DWave.ipynb
这产生了图 7-20 中的输出。
图 7-20
在 16 个节点上完成KnT5
一个完整的 K n 图有九个节点,代码为G = nx.complete_graph(9)
将给出图 7-21 中的图。为了视觉上的方便,我们继续这个九节点图。
图 7-21
在 9 个节点上完成KnT5
在我们的下一步中,我们尝试嵌入图 7-21 的图形并绘制它。
import minorminer
embedded_graph = minorminer.find_embedding(G.edges(), connectivity_structure.edges())
dnx.draw_chimera_embedding(connectivity_structure, embedded_graph)
plt.show()
Listing 7-6eEmbed 9 Node Graph Annealing_QC_DWave.ipynb
清单 7-6e 给出了以下输出,作为九个节点的Kn=K9图嵌入。如果这个片段运行了不止一次,那么我们可能会看到结构的变化;也就是说,可以获得不同的嵌入。这些结果都没有错。它们都是可能的正确图形。
图 7-22
9 个节点的嵌入
在图 7-22 中,具有相同颜色的量子位对应于图 7-21 的 K 9 图定义的原问题中的一个逻辑节点。量子位结合形成了一条链。虽然这个问题有 9 个变量(节点),但玩具嵌合体图上几乎所有 32 个可用的变量都被用上了。清单 7-6f 给出了最大链条长度。
max_chain_length = 0
for _, chain in embedded_graph.items():
if len(chain) > max_chain_length:
max_chain_length = len(chain)
print(max_chain_length)
Listing 7-6fMaximum Chain Length Annealing_QC_DWave.ipynb
输出是值 4。
硬件上的chain
是通过元素间的强耦合实现的;这个链条的强度是用户所能设定的两倍。但是,长链仍然可能断裂,导致偶尔出现不一致的结果。一般来说,较短的链是优选的,以最小化量子位的浪费并获得更可靠的结果。
如果你对探索 D-Wave 的力量感兴趣,请前往 www.youtube.com/playlist?list=PLPvKnT7dgEsujrrP7i_mgbkivBN3J6A8u
参加乔尔·戈特利布博士(前 D-Wave)关于实用量子计算基础的三部分免费量子计算辅导课程。
解决 NP 难问题
对于一个在计算上可行的问题,它必须在所谓的 ?? 多项式时间内是可计算的。多项式时间是指找到一个解所需的计算步数,对于一个大小为 n 和某个常数 c 的问题,必须是多项式函数 n c 。任何需要多项式以上的步骤来计算的问题;例如,指数级的 c n 步数被认为是不可行的,因为计算时间随着问题规模增长得太快,需要比宇宙年龄更多的时间来计算像 n ≃ 100 这样小规模的问题。
图 7-23
问题的复杂性
根据问题的可行性,将问题分成不同的复杂类别。最相关的复杂性类别及其关系如图 7-23 所示。
-
BQP(有界误差量子多项式 时间):使用量子计算机可以在多项式时间内高效解决问题。BQP 类包括 P 和至少一些 NP-中级的问题。然而,BQP 类不包括 NP 难或 NP 完全问题。例子包括整数因式分解(NP-intermediate)和量子系统的模拟。
-
P(多项式时间)😛 中的问题定义为可以在多项式时间内高效解决的问题。这些问题被认为在经典计算机上是可行的。例如整数乘法、排序和列表搜索。
-
NP(非确定性多项式时间****):NP 中的问题是可以被高效验证的问题;也就是说,可以在多项式时间内确认有效解。如果 P≠ NP,则不也在 P 中的 NP 问题不可能被有效解决(如 P 和整数因式分解中的所有问题)。
-
NP-hard 和 NP-complete : NP-hard 问题至少和 NP 中的每一个问题一样难;也就是说,相当于用一些额外的开销来解决一个 NP 问题。这样的问题如果也在 NP 中,就是 NP 完全的。
NP-hard 问题不能有效地解决。然而,大多数有用的问题在现实世界中可能是 NP 难的,包括广泛适用于许多学科的基本问题,从密码学到调度到解决数独,等等[153]。幸运的是,存在可接受的近似解,使得足够小的 NP 困难问题可以用可接受的努力量来解决,但是总是有改进算法的空间。例如旅行推销员问题、停顿问题、地图着色和最大割问题。其中,我们在实践练习中尝试了最大割问题。在第八章中,我们还会看到用 D-Wave 编译器编码一个更复杂的旅行推销员问题。
无监督学习和优化
在本章的前面,我们看了监督学习和 qSVMs 的一些方面。无监督学习意味着缺乏标签(参见章节 2 和 3 ),我们在数据中寻找结构,而没有对该结构特征的直觉。无监督学习的一个常见例子是聚类,其目标是识别在一些高维空间中聚集在一起的实例。一般来说,与有监督的学习相比,无监督的学习更难解决问题。深度学习为激励监督学习注入了巨大的推动力。它引发了无监督学习的重大进展。然而,仍有很大的改进余地。在下面的代码示例中,我们探索了将无监督学习问题映射到图优化的方法,这可以在量子计算机上解决。
我们考虑的第一个问题是聚类到优化的映射。假设有个点是高维空间
的成员。为了形成聚类,我们需要能够定义、区分和分组彼此靠近的点和彼此远离的点。为了更好地理解,让我们用公式表示一个包含两个类的数据集:前十个实例属于第一类,后十个实例属于第二类。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline
n_instances = 20
class_1 = np.random.rand(n_instances//2, 3)/10
class_2 = (0.6, 0.1, 0.05) + np.random.rand(n_instances//2, 3)/10
data = np.concatenate((class_1, class_2))
colors = ["red"] * (n_instances//2) + ["green"] * (n_instances//2)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d', xticks=[], yticks=[], zticks=[])
ax.scatter(data[:, 0], data[:, 1], data[:, 2], c=colors);
Listing 7-7aData Points 3-D unsupervisedLearning.ipynb
这为我们提供了数据点的三维可视化。
作为一个额外的例子,如果我们希望我们的数据点在一个二维空间中,下面的代码片段将为每个类生成五个实例。
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
np.set_printoptions(precision=3, suppress=True)
np.random.seed(0)
# Generating the data
c1 = np.random.rand(5, 2)/5
c2 = (-0.6, 0.5) + np.random.rand(5, 2)/5
data = np.concatenate((c1, c2))
plt.subplot(111, xticks=[], yticks=[])
plt.scatter(data[:, 0], data[:, 1], color='navy')
Listing 7-7b2-D Data Points
清单 7-7b 给出了以下输出。
欧几里德距离测量是在高维空间中测量的最简单的情况。可以使用列表 7-7c 计算数据点之间的成对距离。
import itertools
d = np.zeros((n_instances, n_instances))
for i, j in itertools.product(*[range(n_instances)]*2):
d[i, j] = np.linalg.norm(data[i]-data[j])
print("The distances are ", d)
Listing 7-7cGram Matrix unsupervisedLearning.ipynb
这将打印点之间的距离,如以下截断的输出所示。
列表 7-7c 生成的矩阵称为克矩阵或核矩阵。Gram 矩阵包含高维空间中点的拓扑信息。Gram 矩阵可以解释为图的加权邻接矩阵:两个节点代表两个数据实例。如 Gram 矩阵中所定义的,点之间的距离是连接它们的边上的权重。如果距离为零,则它们没有通过边连接。这是一个有很多边的密集图,通过施加一个指数级变小的距离函数,可以改善可视化。
我们可能想知道这些图表在我们寻找星团的任务中有多有效。这就是我们可以考虑最大割的地方,这是一个边的集合,如果删除,它会将图一分为二,同时最大化这些边的总权重,如 Otterbach 等人 2017 [159]所示。这是一个众所周知的自然映射到伊辛模型的 NP-hard 问题。
退火最大切割(D 波)
最大割是一个 NP 难的图论问题,正如理查德·卡普[156]在 1972 年发表的开创性论文以及其他 20 个 NP 难问题中所显示的。计算机科学家、数据科学家和数学家对 Max-Cut 进行了广泛的研究。问题的 NP 难性质无法在多项式时间内求解,但可以在多项式时间内验证。由于 NP-hard 问题没有多项式时间算法,所以对近似算法和启发式算法进行了大量的研究。最大割(Max-Cut)图问题简单地说就是将图的节点分成两个子集,使得子集之间的边数最大化。
最大割问题在现实世界中有广泛的应用,例如计算机网络。假设有各种服务器,每一个都有不同类型的接口(即,一些有 10 Gb 以太网端口,一些有 USB 端口,一些有蓝牙)。我们的目标是将这些计算机分为两组,用于两个不同的项目,以保证两组可以连接。然而,在现实生活中,连接经常由于物理和逻辑系统的不匹配而失败。这里的目标是计算保持联系的最佳方式。
最大割理论为我们提供了一种方法。为了创建我们的服务器网络的工作模型,我们可以将服务器形成的图可视化为节点(或顶点),并且在服务器之间绘制边,以便它们可以连接,如图 7-24 所示。
图 7-24
最大割问题
图 7-24 的左侧是一个图表,右侧是同一图表的可能最大割解。两个分区分别是 P 1 = {1,4}和 P 2 = {2,3,5}。最大切削尺寸为 f ( x ) = 5,其中 x = (1,1,1,1)。值得注意的是,这个例子有多个解决方案(具有相同大小切割的分区),这是其中一个例子。
如果我们在图中寻找一个最大割,我们希望把节点分成两组,这样在两组之间就有尽可能多的边。然后,在我们的服务器网络中,我们有两个组,这两个组之间有尽可能多的连接。现在,如果一个连接断开,我们可以使用多个连接作为冗余路径。该解决方案通过在一个连接出现故障时在组之间提供冗余连接,帮助创建更具弹性的网络。
量子退火是可视化 NP 难最大割问题的一种强有力的方法。为了了解这是如何做到的,我们使用 D-Wave 的dimod
和 NetworkX ( https://docs.ocean.dwavesys.com/projects/dwave-networkx/en/latest/
)等等来看一个 12 节点最大割问题。
import numpy as np
import matplotlib.pyplot as plt
import dwave_networkx as dnx
import networkx as nx
from dimod import ExactSolver, SimulatedAnnealingSampler
Listing 7-8aMax-Cut Libraries and Preliminaries maxcut_DWave.ipynb
SimulatedAnnealingSampler()
是一个使用模拟退火算法的dimod
采样器。清单 7-8b 定义了 12 个节点及其连接,并调用dwave_networkx()
【154]
函数来创建图形。
sampler = SimulatedAnnealingSampler()
G = nx.Graph()
G.add_edges_from([(0,6),(0,7),(0,8),(0,9),(0,10),(0,11),
(1,6),(1,7),(1,8),(1,9),(1,10),(1,11),
(2,6),(2,7),(2,8),(2,9),(2,10),(2,11),
(3,6),(3,7),(3,8),(3,9),(3,10),(3,11),
(4,6),(4,7),(4,8),(4,9),(4,10),(4,11),
(5,6),(5,7),(5,8),(5,9),(5,10),(5,11)])
pos = nx.spring_layout(G)
nx.draw(G,pos,with_labels=True)
nx.draw_networkx_nodes(G,pos)
plt.show()
candidate = dnx.maximum_cut(G, sampler)
print (candidate, " is the maxcut")
S = dnx.maximum_cut(G, ExactSolver())
print (S, " is the maxcut")
Listing 7-8bGraph Generation maxcut_DWave.ipynb
代码片段给出了以下输出,作为我们的 Max-Cut 解决方案。由于计算的概率性质,每次运行的解可能不同。这并不意味着任何解决方案都是错误的。都是正确的!
我们生成了具有明确定义的边和节点的图。作为练习,我们可以随机选择节点并观察解决方案的质量。
seed = random.randrange(1, 1000)
G1 = nx.erdos_renyi_graph(n=12, p=0.3, seed=seed)
pos = nx.spring_layout(G1)
nx.draw(G1,pos,with_labels=True)
plt.show()
sampler = SimulatedAnnealingSampler()
candidate = dnx.maximum_cut(G1, sampler)
print (candidate, " is the maxcut")
S = dnx.maximum_cut(G1, ExactSolver())
print (S, " is the maxcut")
Listing 7-8cGraph Generation maxcut_DWave.ipynb
在清单 7-8c ,erdos_renyi_graph
9 是 Python NetworkX 的一部分。它返回一个 G n , p 随机图,也称为 Erdős-Rényi 图或二项式图。 G n , p 模型以概率p
(此处概率赋值为 30%)选择每个可能的边。该算法在O(n2)时间内运行。random()
功能产生给定范围内的伪随机数(见 https://docs.python.org/3/library/random.html
)。下面是代码块的输出。
由于节点选择的随机性,这个解看起来比前一个更随意。由于计算的概率性质,每次运行的解可能不同。
用 QAOA (pyQuil)进行最大切割
既然你已经对 Max-Cut 有了深入的了解,并且已经看到了它在 D-Wave 量子退火上的工作,同样的 Max-Cut 问题也可以在 Rigetti Forest 或其他门模型量子计算机上解决。为了实现这一点,翻译耦合和现场字段以匹配编程接口,如清单 7-9 所示(和以前一样,打开三个单独的终端来启动 QVM 服务器(qvm -S
)、Quilc 服务器(quilc -S
)和 Jupyter 笔记本(jupyter notebook
)。导入必要的库并定义网络边。
# Import Libraries and define QVM Connection
import numpy as np
from grove.pyqaoa.maxcut_qaoa import maxcut_qaoa
import pyquil.api as api
import matplotlib.pyplot as plt
import networkx as nx
qvm_connection = api.QVMConnection()
# assign network edges
nw_edges=[(0,1),(1,2),(2,3),(3,4),(4,5),(5,6),(7,0),(7,8),(8,9),(9,2),(9,10),(10,11),(11,4),(11,12),(12,6),(0,10),(3,12)]
Listing 7-9aAssign the Edges maxcut_QAOA_pyquil.ipynb
然后我们在 QVM 上运行优化。
steps = 2
inst = maxcut_qaoa(graph=nw_edges, steps=steps)
betas, gammas = inst.get_angles()
steps = 2
inst = maxcut_qaoa(graph=nw_edges, steps=steps)
betas, gammas = inst.get_angles()
t = np.hstack((betas, gammas))
param_prog = inst.get_parameterized_program()
prog = param_prog(t)
wf = qvm_connection.wavefunction(prog)
wf = wf.amplitudes
wlist = []
for state_index in range(2**len(inst.qubits)):
ww = np.conj(wf[state_index])*wf[state_index]
wlist.append([inst.states[state_index], ww.real])
wlist.sort(key=lambda x: float(x[1]),reverse=True)
Listing 7-9bRun Optimization on QVM maxcut_QAOA_pyquil.ipynb
以下是截断的输出。
我们可以通过wlist
命令获得一个带有权重的分区解决方案列表(为了简洁起见,没有显示输出,但是包含在笔记本中)。
接下来,寻找最大分割分区。
mxcutlist0 = []
mxcutlist1 = []
for i in range(len(wlist[0][0])):
if wlist[0][0][i] == '0':
mxcutlist0.append(i)
else:
mxcutlist1.append(i)
print("maxcut0 is ",mxcutlist0)
print("maxcut1 is ",mxcutlist1)
Listing 7-9cMax-Cut Partitions maxcut_QAOA_pyquil.ipynb
分区的输出如下。
我们可以从下面的代码片段中生成最大割图和分区。
G1 = nx.Graph()
G1.add_edges_from(nw_edges)
pos = nx.spring_layout(G1)
#gd.draw_custom(G2,pos)
nx.draw(G1,pos,with_labels=True)
plt.show()
print("The first set from maxcut partioning is ",mxcutlist0)
print("The second set from maxcut partioning is ",mxcutlist1)
Listing 7-9dMax-Cut Graph maxcut_QAOA_pyquil.ipynb
下面的输出显示了我们在 pyQuil 中的 Max-Cut 解决方案和分区的图表。
由于计算的概率性质,输出图可能因运行而异。
最大割问题的一个常见实际例子是超大规模集成(VLSI)电路设计在引脚预分配和层偏好中的应用。另一个常见的例子是应用外磁场寻找自旋玻璃的基态。巴拉霍纳等人(2016 年)[157]对这两种情况都进行了研究。
解决 Max-Cut 等问题是基于退火的量子计算机(如 D-Wave)的强大功能的一个例子。据推测,基于 QAOA 的 Max-Cut 解决方案需要基于门的量子计算机上的数百个量子位才能实现任何潜在的量子加速优势(Guerreschi 等人,2019 年)[158]。
摘要
本章着眼于量子计算和机器学习中一些非常重要和常用的算法和技术,如 VQE、曲波、QAOA 和 HHL。它推出了 D-Wave 的退火系统,这是世界上第一台商业化生产的量子计算机。使用各种平台和优化技术解决类似问题的方法在下一章很有帮助,我们将探索更复杂的优化问题的实践示例,如 TSP、量子深度学习、量子神经网络和利用 Xanadu 的 PennyLane 的量子机器学习。
Footnotes 1
未计算: https://en.wikipedia.org/wiki/Uncomputation
2
矩阵的条件数被定义为最大奇异值与最小奇异值之比,并且当最小奇异值为 0 时是未定义的。一般来说,当矩阵的奇异值介于其条件数的倒数和 1 之间时,该矩阵被称为“条件良好的”。
3
Z.赵,A. Pozas-Kerstjens,P. Rebentrost,p .,《量子计算机上的贝叶斯深度学习》,(2018),arXiv:1806.11463 [quant-ph], https://arxiv.org/abs/1806.11463
,本书参考文献[113]。
4
例如,参见 https://en.wikipedia.org/wiki/Ising_model
5
哈伯德模型: https://en.wikipedia.org/wiki/Hubbard_model
6
neld-mead:https://en.wikipedia.org/wiki/Nelder%E2%80%93Mead_method
7
参考: https://en.wikipedia.org/wiki/Lie_product_formula
8
dimod 是采样器的共享 API(参见 https://github.com/dwavesystems/dimod
)。它提供了一个二元二次模型(BQM)类,包含 D-Wave 系统等采样器使用的伊辛和二次无约束二元优化(曲波)模型;离散二次模型(DQM)类和高阶(非二次)模型;以及采样器和合成采样器的参考示例。
9
参考: https://networkx.org/documentation/networkx-1.10/reference/generated/networkx.generators.random_graphs.erdos_renyi_graph.html
***
八、深度量子学习
头脑无所畏惧的地方
并且头被抬得高高的
知识是免费的。
—罗宾德拉纳特·泰戈尔
通过学习来拓展我们的知识是人类的天性。通过不断学习来培养和发展优化我们生活中每一个小角落的艺术,是人类文明史上进步的支柱。我们受益于改善日常生活各个方面的努力。第七章讲述了量子退火,虽然最优化理论来源于数学概念,但它们也可以被转化并构建到物理学中。比如物理学有最小作用量原理,最小熵产生原理,变分原理。物理学提供物理退火,它先于计算模拟退火。物理学还提供了绝热原理,从量子形式来看,就是量子退火。因此,物理机器可以解决优化的数学问题,包括约束——这种属性可以扩展到使用量子系统来处理经典和量子数据。
*Note
第章 7 解决了最大割 NP 难问题。本章着眼于利用 D-Wave 的 qbsolve 解决一个更复杂的 NP-hard 问题:旅行推销员问题。我们还从第 2 和 3 章中从经典神经网络获得的见解中收集信息,并在 Xanadu 的 PennyLane 和谷歌的 TensorFlow Quantum 提供的库的帮助下,发展成为量子深度学习的选项。
为了解决今天的现实问题,量子计算机需要读取、解释和分析输入数据集。量子系统的输入数据可以是自然或人工量子系统中的任何数据源。
图 5-6 显示了经典数据驱动量子计算过程的三个一般执行阶段,此处再次显示以供参考。
转载图 5-6 。量子计算机执行的三个阶段
将经典数据加载到量子态以供量子计算机处理的量子电路公式是当前研究的活跃焦点。由于不同的量子算法对如何加载经典输入数据并将其格式化成相应的量子状态具有不同的限制,因此目前在该领域中使用了几种数据加载电路(例如,基本编码、幅度编码等。).随着本章的深入,你会看到经典数据是如何通过量子系统进行编码和处理的。
作为第七章的延续,我们来看看如何使用 D-Wave 的 qbsolve 来解决一个众所周知的 NP 难题:旅行销售人员。
通过 D-Wave 优化学习
在第七章中,我们从 D-Wave 探索了一些基于量子退火的系统可以解决的功能和问题。经典的最优化问题,由方程式 7 给出。27 (为便于阅读在此转载),给了我们以下数学表达式,可以用来在 D-Wave 平台上建立编程模型。
方程式 7。27 通过伊辛模型哈密顿量量化,并用于通过在退火驱动平台上映射来实现量子增强优化。为此,方程式 7。4 , 7。5 和 7。27 制定以下哈密顿量(D-Wave 文档[144])。
(8.1)
其中 A ( s )和 B ( s )为拉格朗日乘数。 1 在编程术语中, A ( s )也被称为gamma
参数(后面解释)。
在这种背景下,熟悉 D-Wave 的 QB solve(https://github.com/dwavesystems/qbsolv
)【161】是有帮助的。qbsolve 是一个分解,混合量子/经典求解器。它通过将一个大型二次无约束二元优化(曲波)问题分解成多个部分来寻找其最小值,通过 D-Wave 系统或经典的禁忌求解器来求解。这是一个开源软件工具,专为太大和/或太密集的问题而设计,无法在 D-Wave 量子计算机上运行,该计算机将问题分成块,并迭代成子量子。qbsolve 过程可以在经典计算机上运行。
qbsolve 采用曲波文件格式或 Q 矩阵作为模拟退火或 QPU 的输入,并给出位串作为输出(见图 8-1 )。
图 8-1
免除混合算法工作流
图 8-1 显示了 qbsolve 算法的工作流程,包括以下步骤。
-
读取曲波实例
-
划分成更小的子量子
-
求解子量子(这可以在 CPU 或 QPU 上完成)
-
合并结果
qbsolve 的一个很好的例子是旅行推销员问题。
旅行推销员问题(qbsolve)
旅行推销员问题(TSP)2【162】是一个众所周知且臭名昭著的 NP-hard 问题,它让数学家们兴奋了几个世纪,也让计算机科学家们兴奋了几十年。从应用程序的上下文来看,TSP 类型的问题在金融和营销行业中很重要。TSP 由于其硬度以及与实践中出现的一些其他相关组合优化问题的相似性而被认为是重要的。
基于早期分析的数学公式是由爱尔兰数学家 W. R .汉密尔顿和英国数学家托马斯·柯克曼在 19 世纪早期提出的。从数学上来说,这个问题可以用图来抽象(例如,最大割)。图的节点上的 TSP 要求可以通过每个节点的最短哈密顿圈。哈密尔顿圈是一个封闭的路径,它使用图的每个顶点一次。一般的解决方案是未知的,并且有效地找到它的算法,例如,不期望在多项式时间内存在。
TSP 的公式如下:一个旅行推销员从一个城市到另一个城市去推销商品。给定一个城市列表和每对城市之间的距离,最短的可能路线是什么,可以访问每个城市一次,然后返回出发城市?这种优化的路线使销售人员能够在最短的时间内实现最大的潜在销售额。
在我们的例子中,我们考虑一个九个城市的 TSP,其中销售人员必须访问九个城市来进行销售。这个问题对于任何数量的城市都可以解决。我们选择了以下九个美国首都城市,并用它们的位置参数(纬度和经度)定义了一个数据文件(data_9cities.txt
),并为它们编制了索引,以便于编程(该文件可在本书的网站上找到)。
0,Colorado,Denver,39.7391667,-104.984167
1,Connecticut,Hartford,41.767,-72.677
2,Delaware,Dover,39.161921,-75.526755
3,Illinois,Springfield,39.783250,-89.650373
4,Indiana,Indianapolis,39.790942,-86.147685
5,Massachusetts,Boston,42.2352,-71.0275
6,Michigan,Lansing,42.7335,-84.5467
7,New Hampshire,Concord,43.220093,-71.549127
8,New Jersey,Trenton,40.221741,-74.756138
我们定义了另一个数据文件(data_distance9.txt
),其中每对首都城市之间的距离总共为 9 × 8 = 72 个距离(这个文件可以在本书的网站上找到)。下面是一个问题路径的例子。
或者
如果路径和行进时间对于销售人员来说是优化的,则可以使用任何其他组合来最大化他们的销售。当制定 QUBU 时,在我们的问题中考虑以下两个约束。
-
销售人员在他开始的地方结束。
-
他每个城市只去一次。
最初,我们需要考虑用数学方法来建模这个问题。为此,我们首先定义我们的二进制变量。
这些约束允许我们用数学公式来最小化我们的距离算子
记住我们的限制,每个城市在曲波出现两次——一次到达,一次离开。举个例子,
对于城市 0(丹佛),我们有
对于城市 1(哈特福德),我们有
如此类推,直到第八个城市,也就是特伦顿。
既然我们已经定义了预备工作,我们必须制定约束和目标(方程式)7。27 。
其中, min 代表最小化。最小化的动作寻找边之间的最短距离,这发生在相等时。使用正方形是为了消除负距离。约束由下式给出
接下来,我们结合目标和约束来制定我们的曲波。
其中, γ 是一个拉格朗日参数,可以对其进行调整以获得最佳结果。
有了这个,我们开始练习 Jupyter 笔记本文件TSP_9City_Dwave.ipynb
,可以从该书的网站下载。第一个代码片段是库和可视化工具。
## Libraries & visualization tools for us to use.
import networkx as nx
import pylab
import matplotlib.pyplot as plt
from matplotlib.pyplot import pause
import sys
from bokeh.sampledata import us_states
from bokeh.plotting import *
from bokeh.models import Plot, Range1d, MultiLine, Circle, HoverTool, TapTool, BoxSelectTool
from bokeh.io import output_notebook
from bokeh.palettes import Spectral4
from bokeh.models.graphs import from_networkx, NodesAndLinkedEdges, EdgesAndLinkedNodes
output_notebook()
%matplotlib inline
import argparse
import re
Listing 8-1aLibraries and Pauli
Matrices for TSP_9City_Dwave.ipynb
这里的bokeh
指的是为现代网络浏览器创建交互式可视化的 Python 库。在我们的练习中,我们用它来创建一张美国地图和旅行过的城市的地图。
下一个任务是设置问题中城市的数量和一个索引函数。二元变量是xI, j = 1 当且仅当在停靠点 j 访问城市 i 时。曲波字典/矩阵是N2×N2,因此,这些变量必须被赋予行和列索引。函数 x ( a , b )给 x a , b 变量分配一个曲波矩阵索引。
# Number of cities in our problem
N = 9
# Function to compute index in Q for variable x_(a,b)
def x(a, b):
return (a)*N+(b)
Listing 8-1bMatrix for TSP_9City_Dwave.ipynb
在这个例子中,有两个拉格朗日参数。
-
A 或
gamma
是标准的拉格朗日参数,表示我们的约束在我们的解决方案的质量中有多重要。这可以微调以获得最佳结果。这决定了是满足约束条件更重要还是找到最短距离更重要。对于这个问题,至关重要的是我们要访问路线上的每个城市,所以我们应该将这个参数设置为大于两个城市之间的最大距离。 -
𝐵指出了目标函数在我们的曲波中的重要性。一般我们定义 B = 1,修改 A 中的值。
也可以调整以下参数。
-
链强度 (
chainstrength
):这告诉嵌入函数将物理量子位的链捆绑在一起形成一个逻辑量子位的强度。这应该大于曲波中的任何其他值。 -
运行次数 (
numruns
):这告诉系统我们的问题要运行多少次。由于 D 波 QPU 的概率性质,我们应该多次运行该问题,并寻找找到的最佳解决方案。
这段代码不会在物理 QPU 上运行,而是离线或传统地使用qbsolv
。numruns
经常运行qbsolv
,但是链强度不会影响样本,除非我们修改代码使用 QPU。
# Gamma = A
A = 6500
B = 1
chainstrength = 3000
# Number of runs
numruns = 100
Listing 8-1cTunable Parameters TSP_9City_Dwave.ipynb
接下来,利用城市位置data_9cities.txt, the
第一个数据文件,我们生成美国地图。销售人员去过的城市用红色标出。
us_states = us_states.data.copy()
# Delete states Hawaii and Alaska from mainland map
del us_states["HI"]
del us_states["AK"]
# separate latitude and longitude points for the borders
# of the states.
state_xs = [us_states[code]["lons"] for code in us_states]
state_ys = [us_states[code]["lats"] for code in us_states]
with open('data_9cities.txt', "r") as myfile:
city_text = myfile.readlines()
myfile.close()
cities = [',']*N
states = [',']*N
lats=[]
longs=[]
for i in city_text:
index, state, city,lat,lon = i.split(',')
cities[int(index)] = city.rstrip()
states[int(index)] = state
lats.append(float(lat))
longs.append(float(lon))
# init figure
p = figure(title="Find shortest route that visits each city",
toolbar_location="left", plot_width=550, plot_height=350)
# Draw state lines
p.patches(state_xs, state_ys, fill_alpha=0.0,
line_color='blue', line_width=1.5)
# The scatter markers
p.circle(longs, lats, size=10, color='red', alpha=1)
show(p)
Listing 8-1dMap
of the cities TSP_9City_Dwave.ipynb
这段代码生成了如图 8-2 所示的美国地图,突出显示了 bokeh 提供的九个城市。
图 8-2
参观过的九个城市的地图
现在我们有了基础地图,我们通过文件data_distance9.txt
上传城市间的距离。
# Input file containing inter-city distances
fn = "data_distance9.txt"
# check that the user has provided input file
try:
with open(fn, "r") as myfile:
distance_text = myfile.readlines()
myfile.close()
except IOError:
print("Input distance file missing")
exit(1)
Listing 8-1eInter-City Distances TSP_9City_Dwave.ipynb
距离存储在一个 N × N 矩阵中。矩阵在对角线上有零点。从一个城市(例如 0)到下一个城市(例如 1)的距离在条目中,因为当在两个城市之间的任一方向旅行时,距离是相同的。矩阵是对称的。
# Initialize matrix of correct size with all 0's
D = [[0 for z in range(N)] for y in range(N)]
# Read in distance values and enter in matrix
for i in distance_text:
if re.search("^between", i):
m = re.search("^between_(\d+)_(\d+) = (\d+)", i)
citya = int(m.group(1))
cityb = int(m.group(2))
D[citya][cityb] = D[cityb][citya] = int(m.group(3))
Listing 8-1fCreate the Matrix TSP_9City_Dwave.ipynb
在下一步中,我们通过创建一个所有值都初始化为 0 的空 Q 矩阵,开始开发这个问题的曲波。
Q = {}
for i in range(N*N):
for j in range(N*N):
Q.update({(i,j): 0})
Listing 8-1gQ-matrix TSP_9City_Dwave.ipynb
下一个代码块定义了在置换矩阵中每行恰好有个 1 的约束。对于第 1 行,此约束条件为
for v in range(N):
for j in range(N):
Q[(x(v,j), x(v,j))] += -1*A
for k in range(j+1, N):
Q[(x(v,j), x(v,k))] += 2*A
Listing 8-1hPermutation Matrix TSP_9City_Dwave.ipynb
下一步是开发曲波。主要目标是最小化行进的距离。
考虑这样的情况,旅行的销售人员在第 3 站访问城市 u ,在第 4 站访问城市 v 。然后,他在这一段旅行的距离是。如果他在第 3 站访问城市 u 并在第 4 站访问城市 v ,则总距离增加
,否则总距离增加 0。因此,对于每一对城市, u 和 v ,我们添加
这将添加从城市 u 和 v 到总路线的直接行驶距离。双向中的每个 u 和 v 选项都需要添加。
for u in range(N):
for v in range(N):
if u!=v:
for j in range(N):
Q[(x(u,j), x(v,(j+1)%N))] += B*D[u][v]
Listing 8-1iAdd Distance objective TSP_9City_Dwave.ipynb
运行问题
现在我们离线运行 qbsolv。qbsolv 3 是一个问题分解工具,它既可以经典的离线运行(例如在我们的笔记本电脑上),也可以以经典和 QPU 的混合方式运行。
from dwave_qbsolv import QBSolv
resp = QBSolv().sample_qubo(Q)
Listing 8-1jRun qbsolve TSP_9City_Dwave.ipynb
下一步,我们做后处理。一旦qbsolv
运行,我们收集结果并报告找到的最佳答案。这里,我们列出了找到的最低能耗解决方案、销售人员路线中城市的访问顺序,以及这条路线所需的总里程。我们在此输出中包含了一些有效性检查,指示某个站点是否被分配给多个城市,以及某个站点是否没有分配城市。
# First solution is the lowest energy solution found
sample = next(iter(resp))
# Display energy for best solution found
print('Energy: ', next(iter(resp.data())).energy)
# Print route for solution found
route = [-1]*N
for node in sample:
if sample[node]>0:
j = node%N
v = (node-j)/N
if route[j]!=-1:
print('Stop '+str(i)+' used more than once.\n')
route[j] = int(v)
# Compute and display total mileage
mileage = 0
for i in range(N):
mileage+=D[route[i]][route[(i+1)%N]]
print('Mileage: ', mileage)
print('\nRoute:\n')
for i in range(N):
if route[i]!=-1:
print(str(i) + ': ' +cities[route[i]]+ ',' + states[route[i]] + '\n')
else:
print(str(i) + ': No city assigned.\n')
Listing 8-1kAdd Distance Objective TSP_9City_Dwave.ipynb
这个运行在 qbsolve 上的代码片段以最低的能耗、总里程和路线给出了我们想要的输出。
请注意,由于计算的概率性质,所访问城市的顺序可能会因运行而异。鼓励你将拉格朗日值从低变高,并观察计算出的最低能量的变化。通常,参数 A 的值被设置为大于两个城市之间的最大距离。
让我们运行一些检查来验证我们的结果是有效的。
-
如果每个城市在我们的列表中恰好出现一次,那么我们的路线列表由数字 0、1、2……(N-1)按照一定的顺序组成,总计为N(N-1)/2。如果这个总数不正确,我们的路线就无效。
-
验证是否每个城市都有指定的站点,反之亦然。如果没有,我们打印一条消息给用户,让他们知道。
alert = 0
if sum(route)!=N*(N-1)/2:
print('Route invalid.\n')
for i in range(N):
if route[i]==-1:
print('Stop '+str(i)+' has no city assigned.')
if alert==0:
print("Route valid.")
Listing 8-1lVerify If Route Is Valid TSP_9City_Dwave.ipynb
在我们的例子中,代码块验证路由是有效的。
最后的代码块将找到的路线可视化。
Path = nx.Graph()
coord={}
coord[route[0]]=(longs[route[0]],lats[route[0]])
Path.add_node(cities[route[0]],pos=coord[route[0]],label=cities[route[0]])
for i in range(N-1):
e=(cities[route[i]],cities[route[i+1]])
Path.add_edge(*e)
coord[route[i+1]]=(longs[route[i+1]],lats[route[i+1]])
Path.add_node(cities[route[i+1]],pos=coord[route[i+1]],label=cities[route[i+1]])
e=(cities[route[N-1]],cities[route[0]])
Path.add_edge(*e)
fig, ax = plt.subplots(figsize=(120,60))
margin=0.15
fig.subplots_adjust(margin, margin, 1.-margin, 1.-margin)
ax.axis('equal')
nx.draw(Path, nx.get_node_attributes(Path, 'pos'), with_labels=True, width=10, edge_color='b', node_size=200,font_size=72,font_weight='bold', ax=ax)
plt.show()
Listing 8-1mVisualization of the Route TSP_9City_Dwave.ipynb
最后一个代码块给出了地图上路径的可视化输出。
我们鼓励您将数据文件(data_9cities.txt
和data_distance9.txt
)修改为更多的城市及其坐标、额外的城市间距离,并多次尝试可视化。随着城市数量的增加,每次跑步的视觉效果可能会有所不同。
如果你有兴趣体验真正的量子位计算代码,D-Wave 在 Leap ( https://cloud.dwavesys.com/leap/
)上提供有限的免费用户配额——基于云的硬件平台访问。如第 1 和 7 章所述,来自 38 个国家(目前)的用户可以在 Leap 注册免费账户,并利用大量的培训材料、文档、开发者资源等等。一旦您登录到 Leap 平台,他们需要在第一个登录屏幕上向下滚动。左下角有一个带有 API 信息的框,可以复制并用于进行 API 调用,以利用 D-Wave 的实际 QPU。
要使用 qbsolve 调用 QPU 来解决本节中的 TSP 问题,可以使用下面的代码块。
from dwave.system.composites import EmbeddingComposite
from dwave.system.samplers import DWaveSampler
sampler = DWaveSampler(solver={'qpu': True}) # Some accounts need to replace this line with the next:
sampler = EmbeddingComposite(DWaveSampler(token = 'my_token', solver=dict(name='solver_name')))
print("Connected to QPU.")
蓝色的两个代码行在非此即彼的基础上使用。对于大多数用户来说,需要 API 令牌的第二行是有效的。API 令牌从 Leap 接口复制并输入到<my_token>
中,以保护到实际 QPU 的连接。使用 qbsolve 时,名称的值由name='qbsolve'.
给出
让我们前进到量子领域的深度学习方法论。量子深度学习今天有几个实现;除了 D-Wave,还有 Google 的 TensorFlow Quantum 和 Xanadu 的 PennyLane。
量子深度神经网络
经典深度神经网络是机器学习的有效工具,也是发展深度量子学习方法的基础。最简单的用于量化的深度神经网络是玻尔兹曼机器[139]。经典玻尔兹曼机器(阿克利等人 1985 年[168];Du 和 Swamy 2019 [169])为概率分布建模提供了一个强大的框架。这些类型的神经网络使用无向图结构来编码相关信息。相应的信息存储在网络节点的偏置系数和连接权重中,这些网络节点通常与二进制自旋系统相关,并被分组为确定输出的那些:可见节点;还有那些作为潜在变量的:隐藏节点。网络结构链接到能量函数,其通过使用来自统计力学的概念(即吉布斯状态)来促进在可能的节点配置上概率分布的定义(Boltzmann 1877【170】;吉布斯 1902 [171])。
经典玻尔兹曼机 4 由相互作用可调的部件组成。通过调整这些相互作用来训练玻尔兹曼机器,以便由玻尔兹曼–吉布斯分布(见图 7-11b )描述的比特的热统计再现数据的统计。为了量子化玻尔兹曼机器,神经网络被表示为对应于可调谐伊辛模型的一组相互作用的量子自旋。用作玻尔兹曼机器输入的神经元被初始化为固定状态;在此之后,系统可以热化,并且输出量子位作为结果被读取。深度量子学习的一个吸引人的特点是,它不需要大型通用量子计算机。
之前我们讨论了专用量子信息处理器,如量子退火器,它们非常适合构建深度量子学习网络[164,165,166]。本章还着眼于基于可编程光子电路的量子系统,因为它们对于创建高效的量子深度学习网络也是有用的。
经典神经网络涉及神经元的处理、神经元执行的转换、神经元之间的互连、神经网络动力学和学习规则。神经网络学习规则控制神经网络连接强度的变化。神经网络通过监督或无监督方式的训练来区分。神经网络可以使用单个系统来保存不同类别的数据,并以分布式方式对刺激进行分类。因此,神经网络在创建分类系统方面非常有用。
量子态中的相干性被称为叠加,被认为类似于经典神经网络中的神经元。量子计算中的测量功能类似于经典神经网络中的互连。神经网络中的增益函数类似于量子计算中的纠缠特性。
量子神经网络(QNN)类似于大脑功能,有助于创建新的信息系统。qnn 用于解决需要指数级容量和内存的经典挑战性问题。简而言之,qnn 被认为是神经计算系统进化的自然下一步。
量子计算和机器学习之间的联系在过去几年里一直在发展。然而,许多定义明确的“教科书”QML 算法是在考虑容错量子计算机的情况下设计的。在当前的高噪声中尺度量子(NISQ)器件时代,需要一套不同的算法、工具和策略。有必要介绍一下 NISQ 时代机器学习的关键思想,并调查一下当前的发展状况。
用 Xanadu 进行量子学习
Xanadu 是一家位于加拿大多伦多的全栈量子初创公司,该公司正在推进一种量子光子处理器,该处理器采用开源的全栈量子软件平台,名为 Strawberry Fields。该公司还开发了一个用于量子计算机可微分编程的跨平台 Python 库[146],名为 PennyLane ( https://pennylane.readthedocs.io/en/stable/introduction/pennylane.html
)。PennyLane 和 Strawberry 字段是用 Python 实现的。Xanadu 还开始发布他们在不同领域的硬件和软件成果,如量子化学、图论、量子机器学习等。
PennyLane5【145】是一个围绕量子可微编程构建的开源软件框架,用量子计算机实现机器学习任务。它将经典的机器学习库与量子模拟器和硬件无缝集成,使用户能够训练量子电路。PennyLane 虽然有 QML 的能力,但也有多种多样的能力。
-
支持混合量子和经典模型,允许用户将量子硬件与 PyTorch、TensorFlow 和 NumPy 连接,从而增强量子机器学习能力
-
允许量子电路的内置自动微分
-
提供优化和机器学习工具
-
硬件不可知——相同的量子电路模型可以在不同的后端运行——并允许插件访问不同的设备,包括 Strawberry Fields、Amazon Braket、IBM Q、Google Cirq、Rigetti Forest、Microsoft QDK 和 ProjectQ
安装 PennyLane 非常简单。它需要 Python 3.6 或更高版本。推荐的 Python 安装是 Anaconda Python 3 ( www.anaconda.com/download/
)。因为这本书从一开始就承认了 Anaconda,所以我们在这方面应该没问题。剩下的很简单:通过下面的命令安装最新版本的 PennyLane。
pip install pennylane --upgrade
这个命令应该可以在 Python 3.6+环境上成功而轻松地安装 PennyLane。PennyLane 有一些依赖项,比如 NumPy、SciPy、network,它会在安装时检查这些依赖项(如果需要,会自动安装它们),如图 8-3 所示。
图 8-3
PennyLane 安装过程
Xanadu 正在开发一种光子量子计算机:一种处理以光的量子状态存储的信息的设备。光子量子计算机使用连续的自由度——如光的振幅和相位——来编码信息。这种连续或模拟结构使得光子器件成为神经网络量子版本的一个有吸引力的平台。
qnn 是量子电路或算法,非常类似于经典神经元和神经网络的结构(见第三章),同时用强大的量子属性扩展和概括它们。已经发表了利用光子学的 qnn 研究[84],并且在文献中还有几个其他的提议。
用光子学模拟量子阱的提议让一些研究团体兴奋不已。基洛兰等人在 2018 年发表了一篇论文[84],其中他们提出了一种由一系列重复的构建块或层组成的光子电路。这些层可以用一层的输出作为下一层的输入来构建。这些光子层类似于经典神经网络中出现的层(见第三章)。经典网络采用一个输入 x ,乘以一个权重矩阵 W ,加上一个偏差 b ,并将结果通过一个非线性激活函数,如 sigmoid、tanh 和 ReLU。
图 8-4
经典神经网络的基本单元
图 8-4 显示了经典神经网络(NN)的基本结构,它执行以下转换。
(8.2)
典型地,在等式 8.2 中,权重 w 由两个正交矩阵和一个对角矩阵表示。
通过使用光子量子门,量子神经网络层类似于图 8-4 中所示的经典神经网络的功能,光子量子门包括由移相器和分束器制成的干涉仪、压缩和位移门以及固定的非线性变换。这些是建造光子量子计算机的相同的门;因此,QNN 架构被解释为具有量子计算机的计算能力。
图 8-5
光子量子神经网络的基本单元
图 8-5 显示了光子量子系统定义的基本 QNN 单位。它有彩色的门来指示它们与图 8-4 中的哪个古典部件相关。干涉仪和压缩门类似于权重矩阵。位移门映射到偏压,量子非线性激活函数映射到经典非线性。神经网络的量子版本与经典神经网络非常相似,可以用来运行经典版本。通过以一种抛弃任何量子“怪异”的方式控制量子网络,比如叠加和纠缠。PennyLane 可以结合现有的经典节点来创建和探索混合模型,如图 8-6 (来自 PennyLane 文档【145】)。
图 8-6
含 PennyLane 的混合经典量子模型的示例结构
当我们讨论量子深度学习时,我们需要记住,我们仍然没有处于一个可以在量子 NN 模型上训练和测试大量量子数据的时代。今天现实生活中的许多数据本质上都是经典的。因此,我们需要问自己如何编码这些经典数据并将其输入量子机器?
有很多方法可以将经典数据嵌入到量子电路中:量子计算平台的不同供应商已经提供了可用的模板来实现这一点。比如 PennyLane 就有qml.templates
模块。PennyLane 通过一系列插件支持各种量子框架和量子硬件。例如,光子层需要草莓地的pennylane-sf
插件。
为了构建量子节点层(或者 PennyLane 术语中称为 QNodes ),除了手动放置单个门之外,还可以使用预先构建的量子位层的模板。以下是一些预构建的层。
-
RandomLayers
-
StronglyEntanglingLayers
-
BasicEntanglerLayers
-
SimplifiedTwoDesign
-
CVNeuralNetLayers
类似经典神经网络的重复层提供了以下优点。
-
它提供对电路深度的控制。
-
层可以被设计成硬件友好的。
-
这是一个通用量子计算的模型。
用于神经网络的戊炔
现在我们已经探索了量子 NNs (QNNs)和 PennyLane 的理论方面,是时候进行编码了。
用 QNN 拟合余弦函数
以下示例改编自 PennyLane 文献[172]。这个例子构成了学习一维函数的拟合的变分电路。为了实现这一点,我们以带有噪声的cosine
函数的形式生成合成数据,并训练量子神经网络(QNode)来应用它们。
下面解释了如何做到这一点。
-
用
default.qubit.
创建一个device
-
创建一个 QNode,它接受一个输入′x′和可训练权重,并输出一个′y′。
-
定义 x 的训练范围( π 到 π )并计算 y = cos x 。
-
选择 PennyLane 优化器。
-
运行优化循环。
以下示例中使用的变分电路是基洛兰等人(2018) [84]中描述的连续变量量子神经网络模型。
第一步,我们import
PennyLane(安装好之后),PennyLane 提供的 NumPy 的包装版本,以及一个名为AdamOptimizer (
https://pennylane.readthedocs.io/en/stable/code/api/pennylane.AdamOptimizer.html
的优化器。用于此的device
是草莓地模拟器,可以通过 PennyLane 的草莓地插件安装,如下所示。
$ pip install pennylane-sf
从这个练习开始,我们打开名为qnn_cosine_pl.ipynb
的 Jupyter 笔记本,它可以从本书网站的下载链接中获得。
# Import PennyLane, the wrapped version of NumPy provided by PennyLane, and an optimizer.
import pennylane as qml
from pennylane import numpy as np
from pennylane.optimize import AdamOptimizer
import matplotlib.pyplot as plt
import pylab
import pickle
Listing 8-2aLibraries and Optimizer qnn_cosine_pl.ipynb
AdamOptimizer
是随机优化的一种方法。它基于具有自适应学习速率的梯度下降优化器[84]的原理,使用依赖于步长的学习速率提供自适应力矩估计。第三章 ?? 讲述了经典神经网络的梯度下降,这是前馈网络最常见的训练算法之一。梯度下降优化器使用斜率(或梯度)来引导参数空间。数学上,梯度下降,由方程 3 给出。5 ,此处转载。
(8.3)
其中,当前权重是更新后的权重,
是朝着最陡梯度方向向下的前一步的权重, η 是对应于学习速率或步长的用户定义的超参数, E 是成本函数, C 是相对于wij具有导数的 E 的数学等价形式
pickle
模块实现了二进制协议,用于序列化和反序列化 Python 对象结构。酸洗是将 Python 对象层次结构转换成字节流的过程。拆包是相反的操作,一个字节流(来自二进制文件或类似字节的对象)被转换回一个对象层次。Pickle
可用于稍后将数据加载到另一个 Python 脚本中。
下一步,我们创建一个噪声余弦函数进行采样。
Xlim = 5
noise = np.random.normal(0,0.1,100) # generate noise to add to the function values (Y-values)
# define functions
X = np.arange(-Xlim, Xlim, 0.1)
Y = np.cos(X)+noise
Listing 8-2bNoisy Cosine Function Definition qnn_cosine_pl.ipynb
这个代码块用 X 轴和 Y 轴数据生成两个列表 X 和 Y。现在让我们将 Y 轴数据写入一个文件,以备将来使用。
# write the data out to a file
cosdata = open('cosdata.md', 'wb')
pickle.dump(Y, cosdata)
cosdata.close()
plt.plot(X[0:200], Y[0:200])
Listing 8-2cWrite Noisy Cosine Data
to a File qnn_cosine_pl.ipynb
这段代码将 y 的数据写入一个名为cosdata.md
的文件中。有了这个,我们用plt.plot()
函数绘制一些数据,以生成下面的噪声余弦函数图。
现在我们有一些噪声余弦数据来训练我们的 QNN。使用的设备是只有一个量子模式(或线)的草莓场模拟器。为了完成这个练习,我们需要按照之前的指定安装 PennyLane 的草莓地插件。
Note
如果 PennyLane 的 Strawberry Fields 插件是而不是安装的,您会得到以下错误:DeviceError:设备不存在。确保安装了所需的插件。
dev = qml.device("strawberryfields.fock", wires=1, cutoff_dim=10)
Listing 8-2dStrawberry Fields plugin qnn_cosine_pl.ipynb
PennyLane 的草莓地插件访问一个 Fock 6 州模拟器后端。这个模拟器代表了∣0⟩、∣1⟩、∣2⟩,…、∣d1⟩的 Fock 基量子态,其中 D 是用户给定的cutoff_dim
值,该值限制了希尔伯特空间的维度。这种表示法的优点是可以表示任何连续变量的运算。请注意以下事项。
-
模拟是近似值,其精确度随着截止尺寸
cutoff_dim.
的增加而增加 -
对于 M 模式或线以及 D 的截止尺寸,Fock 状态[288]模拟器需要至少跟踪 M D 值。因此,与基于量子位的模拟器相比,模拟时间和所需内存随着模式数量的增加而增长得更快。
-
在优化过程中跟踪量子状态的归一化通常是有用的,以确保电路不会“学会”将其参数推入模拟非常不准确的状态。
下一步,我们利用我们在第七章中对变分电路的探索来定义 QNode。对于单量子模式,变分电路的每一层都定义有一个输入层,一个偏置,一个非线性变换。
def layer(v):
# Matrix multiplication of input layer
qml.Rotation(v[0], wires=0)
qml.Squeezing(v[1], 0.0, wires=0)
qml.Rotation(v[2], wires=0)
# Bias
qml.Displacement(v[3], 0.0, wires=0)
# Element-wise nonlinear transformation
qml.Kerr(v[4], wires=0)
Listing 8-2eDefine the QNN Layer qnn_cosine_pl.ipynb
量子节点中的变分电路首先将输入编码成模式的位移,然后执行各层。输出是x-正交[288]的期望值。
@qml.qnode(dev)
def quantum_neural_net(var, x=None):
# Encode input x into quantum state
qml.Displacement(x, 0.0, wires=0)
# "layer" subcircuits
for v in var:
layer(v)
return qml.expval(qml.X(0))
Listing 8-2fEncode Input qnn_cosine_pl.ipynb
作为目标,我们取目标标签和模型预测之间的损失的平方。
def square_loss(labels, predictions):
loss = 0
for l, p in zip(labels, predictions):
loss = loss + (l - p) ** 2
loss = loss / len(labels)
return loss
Listing 8-2gPrediction Modeling qnn_cosine_pl.ipynb
接下来,我们定义成本函数。在成本函数中计算来自变分电路的输出。函数拟合是一个回归问题,我们将来自量子节点的预期解释为预测,而不应用诸如阈值处理的后处理。
def cost(var, features, labels):
preds = [quantum_neural_net(var, x=x) for x in features]
return square_loss(labels, preds)
Listing 8-2hCost Function qnn_cosine_pl.ipynb
下一步,我们将噪声数据加载到成本函数中。在训练模型之前,让我们检查一下数据(参见清单 8-2i )。
plt.figure()
plt.scatter(X, Y)
plt.xlabel("x", fontsize=18)
plt.ylabel("f(x)", fontsize=18)
plt.tick_params(axis="both", which="major", labelsize=16)
plt.tick_params(axis="both", which="minor", labelsize=16)
plt.show()
Listing 8-2iCost Function qnn_cosine_pl.ipynb
清单 8-2i 给出了下面的输出图。
网络的权重(这里称为var
)用从正态分布中采样的值初始化。我们使用四层。已经发现性能在大约六层时达到稳定。
np.random.seed(0)
num_layers = 4
var_init = 0.05 * np.random.randn(num_layers, 5)
print(var_init)
Listing 8-2jDefine the Number of Layers qnn_cosine_pl.ipynb
这个代码片段给出了层的如下输出。
最后,我们使用 AdamOptimizer。我们运行优化器,并更新本练习中仅50 步的权重。这运行了一段时间。
opt = AdamOptimizer(0.01, beta1=0.9, beta2=0.999)
var = var_init
for it in range(50):
var = opt.step(lambda v: cost(v, X, Y), var)
print("Iter: {:5d} | Cost: {:0.7f} ".format(it + 1, cost(var, X, Y)))
Listing 8-2kRun the Optimizer qnn_cosine_pl.ipynb
运行这个代码块开始 50 步的迭代输出。以下是输出的截断示例。
代码块中的步骤越多,效果越好,但运行时间也越长。我们鼓励您运行此功能;例如,通过调整for it in range(<number_of_steps>).
中的步长值,可以达到 500 或 700 步
接下来,我们收集训练模型在[0,30]范围内的 50 个值的预测,并绘制模型从噪声数据(褐红色点)中“学习”的函数。
x_pred = np.linspace(-3, 3, 50)
predictions = [quantum_neural_net(var, x=x_) for x_ in x_pred]
# plot the function
plt.figure()
plt.scatter(X, Y)
plt.scatter(x_pred, predictions, color="maroon")
plt.xlabel("x")
plt.ylabel("f(x)")
plt.tick_params(axis="both", which="major")
plt.tick_params(axis="both", which="minor")
plt.show()
Listing 8-2lCollect Predictions and Plot Function qnn_cosine_pl.ipynb
这会产生以下输出。
该模型已经学会平滑噪声数据。我们可以使用 PennyLane 来查看模型在完全没有经过训练的情况下产生的典型函数。清单 8-2k 中更高的步数导致更好的拟合,但是运行时间更长。
最后一步,我们用方差超参数绘制函数。
variance = 1.0
plt.figure()
x_pred = np.linspace(-5, 5, 50)
for i in range(7):
rnd_var = variance * np.random.randn(num_layers, 7)
predictions = [quantum_neural_net(rnd_var, x=x_) for x_ in x_pred]
plt.plot(x_pred, predictions, color="black")
plt.xlabel("x")
plt.ylabel("f(x)")
plt.tick_params(axis="both", which="major")
plt.tick_params(axis="both", which="minor")
plt.show()
Listing 8-2mFunctions Against Hyperparameter qnn_cosine_pl.ipynb
这将产生本练习的最后一个输出,绘制超参数方差的函数行为。
这些函数的形状随着权重初始化的方差超参数而显著变化。将这个超参数设置为一个小值会产生几乎线性的函数,因为变分电路中的所有量子门都执行恒等变换。较大的值产生平滑振荡的函数,其周期取决于所用的层数,通常层数越多,周期越小。
PennyLane 二元分类器
第二章介绍了使用 Iris 数据集的分类器(用于经典数据分析)。我们在svmIris.ipynb
中运行了一个支持向量分类器,在 10000 次迭代之后,我们获得了一个混淆矩阵和大约 98%的准确率。第三章在DNNIris.ipynb
中针对经典深度神经网络分类器查看了相同的虹膜数据集,我们运行了 100 个时期以获得 100%的准确率。
观察量子神经网络算法如何不同于相同数据集的经典经验将是有趣的。这里使用的数据在第 2 和 3 章中使用:一个公开可用的数据集,名为 Iris ,可从 Python 的sklearn
获得。标题为qml_iris_pl.ipynb
的 Jupyter 笔记本可从该书的网站上获得。首先,我们从 Python 和 PennyLane 导入所有必要的库,以及 PennyLane 的GradientDescentOptimizer
来执行优化。我们还使用StronglyEntanglingLayers
模板来构建 NN 层。
from itertools import chain
from sklearn import datasets
from sklearn.utils import shuffle
from sklearn.preprocessing import minmax_scale
from sklearn.model_selection import train_test_split
import sklearn.metrics as metrics
import pennylane as qml
from pennylane import numpy as np
from pennylane.templates.embeddings import AngleEmbedding
from pennylane.templates.layers import StronglyEntanglingLayers
from pennylane.init import strong_ent_layers_uniform
from pennylane.optimize import GradientDescentOptimizer
from pennylane.devices.default_qubit import DefaultQubit
Listing 8-3aFunctions Against Hyperparameter qml_iris_pl.ipynb
GradientDescentOptimizer
是一个基本的优化器,它是其他基于梯度下降的优化器的基类。梯度下降优化器的一个步骤通过等式 8.3 中定义的规则计算新值。
StronglyEntanglingLayers
是由单量子位旋转和纠缠组成的层的模板,其灵感来自 Schuld 等人在 2020 年[59]的论文中提出的以电路为中心的分类器设计。
在下一步中,我们导入数据,对其执行预处理(混洗、选择类并将其规范化),并将数据分为 80%–20%,分别用于训练数据集和测试数据集。
# Import data, pre-processing, data splitting
# load the dataset
iris = datasets.load_iris ()
# shuffle the data
X, y = shuffle (iris.data , iris.target , random_state = 0)
# select only 2 first classes from the data
X = X[y <=1]
y = y[y <=1]
# normalize data
X = minmax_scale (X, feature_range =(0 , np.pi ))
# split data into train + validation and test
X_train_val , X_test , y_train_val , y_test = train_test_split (X, y, test_size =0.2)
Listing 8-3bLoad Data, Preprocess and Split qml_iris_pl.ipynb
下一步是构建量子分类器。为了实现这一点,我们定义量子位的数量以匹配特征的数量,用DefaultQubit()
函数定义一个设备,为变分分类器和成本函数设置一个函数。
# Building the Quantum Classifier
# number of qubits is equal to the number of features
n_qubits = X.shape [1]
# quantum device handle
dev = DefaultQubit(n_qubits)
# quantum circuit
@qml.qnode (dev )
def circuit (weights , x= None ):
AngleEmbedding (x, wires = range (n_qubits ))
StronglyEntanglingLayers (weights , wires = range ( n_qubits ))
return qml.expval ( qml.PauliZ (0))
# variational quantum classifier
def variational_classifier (theta, x= None ):
weights = theta [0]
bias = theta [1]
return circuit ( weights , x=x) + bias
def cost (theta , X, expectations ):
e_predicted = \
np.array ([ variational_classifier (theta , x=x) for x in X])
loss = np.mean (( e_predicted - expectations )**2)
return loss
Listing 8-3cBuilding the Quantum Classifier qml_iris_pl.ipynb
StronglyEntanglingLayers()
的参数weights,
包含每层的权重。 7 层数来源于weights
的第一维度。
# number of quantum layers
n_layers = 3
# split into train and validation
X_train , X_validation , y_train , y_validation = \
train_test_split ( X_train_val , y_train_val , test_size =0.20)
# convert classes to expectations : 0 to -1, 1 to +1
e_train = np. empty_like ( y_train )
e_train [ y_train == 0] = -1
e_train [ y_train == 1] = +1
# select learning batch size
batch_size = 5
# calculate numbe of batches
batches = len ( X_train ) // batch_size
# select number of epochs
n_epochs = 10
Listing 8-3dPrepare to Training the Data qml_iris_pl.ipynb
这段代码片段运行了十个时期。我建议你先通过设置n_epochs = 5,
运行五个纪元,然后再运行十个纪元。历元运行的差异反映在最终精度计算中。
在下一步中,我们对数据施加随机权重,训练变分分类器,让优化器开始学习过程,并将训练数据分成批次,就像我们在第 2 和 3 章中对经典系统所做的那样。
# draw random quantum node weights
theta_weights = strong_ent_layers_uniform ( n_layers , n_qubits , seed =42)
theta_bias = 0.0
theta_init = ( theta_weights , theta_bias ) # initial weights
# train the variational classifier
theta = theta_init
# start of main learning loop
# build the optimizer object
pennylane_opt = GradientDescentOptimizer ()
# split training data into batches
X_batches = np.array_split (np.arange (len ( X_train )), batches )
for it , batch_index in enumerate ( chain (*( n_epochs * [ X_batches ]))):
# Update the weights by one optimizer step
batch_cost = \
lambda theta : cost (theta , X_train [ batch_index ], e_train [ batch_index ])
theta = pennylane_opt.step ( batch_cost , theta )
# use X_validation and y_validation to decide whether to stop
# end of learning loop
Listing 8-3eTrain the Data! qml_iris_pl.ipynb
最后,既然我们已经定义并准备好了所有的工具,我们就可以探索推论了。
# Inference
# convert expectations to classes
expectations = np. array ([ variational_classifier (theta , x=x) for x in X_test ])
prob_class_one = ( expectations + 1.0) / 2.0
y_pred = ( prob_class_one >= 0.5)
print ( metrics . accuracy_score ( y_test , y_pred ))
print ("Accuracy: {:.2f} %".format(metrics.accuracy_score ( y_test , y_pred )*100))
print ( metrics.confusion_matrix ( y_test , y_pred ))
Listing 8-3fInference qml_iris_pl.ipynb
此代码块在n_epochs
值为 10 时输出以下内容。
然而,如果我们通过设置n_epochs = 5
将历元减少到值 5,我们会得到下面的输出。
正如在经典案例中所预期的那样,对于更多的历元,我们会得到更准确的结果。
张量流量子 QNN
QNN 被解释为任何具有可训练连续参数的量子电路。QNN 是一种机器学习模型,允许量子计算机对各种数据集进行分类,其中包括图像数据。使用的图像数据是经典数据,但经典数据无法达到叠加状态。因此,要在量子系统上实现这个协议,数据必须能够被一个提供叠加的量子设备读取。QNN 领域相对较新,因为该领域的研究和工作持续增长。我们之前已经看到了一些解决特定 QNN 问题的 PennyLane 代码的例子。本节着眼于 QNN 的图像分类。
QNN 使用监督学习方法来预测图像数据,如 Benedetti,Lloyd 等人(2019) [186]所示。Farhi 和 Neven 在 2019 年提出了[185]一种 QNN,可以表示经典或量子的标记数据,并通过监督学习进行训练。量子电路由一系列依赖于参数的幺正变换组成,它作用于一个输入量子态。对于二进制分类,在指定的读出量子位上测量单个泡利算符。测量输出是输入状态二进制标签的 QNN 预测器。论文的作者[185]写道,“我们继续使用单词 neural 来描述我们的网络,因为该术语已被机器学习社区采用,并认识到与神经科学的联系现在只是历史。”对于类 MNIST 图像分类,作者在电路中随机分配两个量子比特的单位。用于子集宇称的 Reed-Muller 表示[187]是考虑两量子位单位的另一种方式。
图 8-7
量子处理器上 QNN 的示意图(来源 Farhi 和 Neven,2019 [185])
图 8-7 展示了 Farhi 和 Neven【185】在量子处理器上提出的 QNN 的示意图。∣ ψ ,…,1⟩是准备好的输入状态,然后馈入 QNN。这些输入状态经历由uI(θI)依赖于参数 θ i 给出的一系列少数量子位单位,这些量子位单位又在学习过程中得到调整,使得yn
*TensorFlow Quantum (TFQ)由布劳顿等人在 2020 年提出[191],是一个用于混合量子-经典机器学习的 Python 框架,主要专注于对量子数据进行建模。TFQ 是一个应用程序框架,旨在允许量子算法研究人员和机器学习应用研究人员探索利用谷歌量子计算产品的计算工作流,所有这些都来自 TensorFlow。谷歌人工智能于 2020 年 3 月发布了 TFQ,作为量子机器学习模型快速原型的开源库。TFQ 依赖于 Cirq,这是一个在近期计算机上实现量子电路的开源平台。Cirq 包括定义量子计算所需的基本结构,如量子位、门、电路和计算运算符。Cirq 背后的概念是提供一个简单的编程模型,抽象出量子应用的基本构件。
现在,我们将亲身体验 TensorFlow quantum。 8 本练习9【188】构建一个 QNN 对 MNIST 的简化版本进行分类,类似于 Farhi 和 Neven (2019) [185]中使用的方法。将 QNN 在这个经典数据问题上的性能与经典神经网络进行比较。
首先,我们利用谷歌在谷歌实验室的免费计算资源,如第 1 、 2 和 3 章所述。第一步,我们下载并安装 TFQ,这是 TensorFlow 的先决条件。
!pip install tensorflow==2.3.1
Listing 8-4aInstall
TensorFlow qnn_mnist_tfq.ipynb
输出(截断)。
此步骤可能会显示以下有关重新启动 TensorFlow 运行时的消息。
在这种情况下,点击Restart Runtime
按钮。
接下来,安装 TFQ。
!pip install tensorflow-quantum
Listing 8-4bInstall TensorFlow Quantum qnn_mnist_tfq.ipynb
输出(截断)。
接下来,我们导入 TensorFlow 和模块依赖项。
import tensorflow as tf
import tensorflow_quantum as tfq
import cirq
import sympy
import numpy as np
import seaborn as sns
import collections
# visualization tools
%matplotlib inline
import matplotlib.pyplot as plt
from cirq.contrib.svg import SVGCircuit
Listing 8-4cImport Libraries qnn_mnist_tfq.ipynb
现在,我们准备加载数据。在本练习中,我们按照 Farhi 和 Neven [185]的方法,构建了一个二元分类器来区分数字 1 和 7。本节介绍数据处理。
-
从 Keras 加载原始数据。
-
仅将数据集过滤为 1 和 7。
-
缩小图像的尺寸,以便它们可以放入量子计算机。
-
删除任何矛盾的例子。
-
将二进制镜像转换为 Cirq 电路。
-
将 Cirq 电路转换为 TFQ 电路。
在下一步中,我们加载随 Keras 一起分发的原始 MNIST 数据集。
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
# Rescale the images from [0,255] to the [0.0,1.0] range.
x_train, x_test = x_train[..., np.newaxis]/255.0, x_test[..., np.newaxis]/255.0
print("Number of original training examples:", len(x_train))
print("Number of original test examples:", len(x_test))
Listing 8-4dLoad the Data qnn_mnist_tfq.ipynb
输出。
接下来,我们过滤数据集,只保留 1 和 7,删除其他类。同时,将标签 y 转换为boolean
:1 为真,7 为假。
def filter_17(x, y):
keep = (y == 1) | (y == 7)
x, y = x[keep], y[keep]
y = y == 1
return x,y
x_train, y_train = filter_17(x_train, y_train)
x_test, y_test = filter_17(x_test, y_test)
print("Number of filtered training examples:", len(x_train))
print("Number of filtered test examples:", len(x_test))
Listing 8-4eFilter the Data qnn_mnist_tfq.ipynb
过滤过程的输出读出用于训练和测试分割的数字。
我们尝试了一个例子,看看数据是什么样的。
print(y_train[0])
plt.imshow(x_train[0, :, :, 0])
plt.colorbar()
Listing 8-4fExample qnn_mnist_tfq.ipynb
这个代码块给出了下面的输出。
接下来,我们将图像缩小到 4 × 4,因为 28 × 28 的图像尺寸对于当前的量子计算机来说太大了,并在调整大小后显示它。
x_train_small = tf.image.resize(x_train, (4,4)).numpy()
x_test_small = tf.image.resize(x_test, (4,4)).numpy()
print(y_train[0])
plt.imshow(x_train_small[0,:,:,0], vmin=0, vmax=1)
plt.colorbar()
Listing 8-4gExample qnn_mnist_tfq.ipynb
以下是输出。
下一步是通过用量子位表示每个像素,将数据编码为量子电路,其中量子位状态取决于像素的值。第一步是转换成二进制编码。
THRESHOLD = 0.5
x_train_bin = np.array(x_train_nocon > THRESHOLD, dtype=np.float32)
x_test_bin = np.array(x_test_small > THRESHOLD, dtype=np.float32)
Listing 8-4hBinary Encoding qnn_mnist_tfq.ipynb
现在,我们通过一个 X 门旋转量子位,像素索引值超过一个阈值,形成一个电路。
def convert_to_circuit(image):
"""Encode truncated classical image into quantum datapoint."""
values = np.ndarray.flatten(image)
qubits = cirq.GridQubit.rect(4, 4)
circuit = cirq.Circuit()
for i, value in enumerate(values):
if value:
circuit.append(cirq.X(qubits[i]))
return circuit
x_train_circ = [convert_to_circuit(x) for x in x_train_bin]
x_test_circ = [convert_to_circuit(x) for x in x_test_bin]
SVGCircuit(x_train_circ[0])
Listing 8-4iRotate Qubits Through X Gate qnn_mnist_tfq.ipynb
下面是为第一个例子创建的电路(电路图没有显示零门量子位)。
现在,我们可以将该电路与图像值超过阈值的指数进行比较。
bin_img = x_train_bin[0,:,:,0]
indices = np.array(np.where(bin_img)).T
indices
Listing 8-4jComparison qnn_mnist_tfq.ipynb
以下输出。
量子数据以张量的形式加载,定义为用 Cirq 编写的量子电路。TensorFlow 在量子计算机上执行这个张量,生成一个量子数据集。因此,我们现在将这些 Cirq 电路转换为 TensorFlow Quantum ( tfq
)的张量,如清单 8-4k 所示。
x_train_tfcirc = tfq.convert_to_tensor(x_train_circ)
x_test_tfcirc = tfq.convert_to_tensor(x_test_circ)
Listing 8-4kComparison qnn_mnist_tfq.ipynb
现在我们准备建造 QNN。然而,对图像分类的量子电路结构的指导是稀疏的。由于分类是基于对读出量子位的期望,Farhi 等人提出使用双量子位门,读出量子位总是起作用。这在某些方面类似于 Arjovsky 等人[190]提出的跨像素运行小型酉 RNN。
为了实现这一点,我们从构建模型电路开始。下面的代码块显示了一种分层的方法。每一层使用同一个门的 n 个实例,每个数据量子位作用于读出量子位。我们从一个简单的类开始,在电路中增加一层这样的门。
class CircuitLayerBuilder():
def __init__(self, data_qubits, readout):
self.data_qubits = data_qubits
self.readout = readout
def add_layer(self, circuit, gate, prefix):
for i, qubit in enumerate(self.data_qubits):
symbol = sympy.Symbol(prefix + '-' + str(i))
circuit.append(gate(qubit, self.readout)**symbol)
demo_builder = CircuitLayerBuilder(data_qubits = cirq.GridQubit.rect(4,1),
readout=cirq.GridQubit(-1,-1))
circuit = cirq.Circuit()
demo_builder.add_layer(circuit, gate = cirq.XX, prefix='xx')
SVGCircuit(circuit)
Listing 8-4lBuild the QNN Model Circuit qnn_mnist_tfq.ipynb
输出显示了电路。
接下来,我们建立一个两层模型,匹配数据电路的大小,并包括准备和读出操作。
def create_quantum_model():
"""Create a QNN model circuit and readout operation to go along with it."""
data_qubits = cirq.GridQubit.rect(4, 4) # a 4x4 grid
readout = cirq.GridQubit(-1, -1) # a single qubit at [-1,-1]
circuit = cirq.Circuit()
# Prepare the readout qubit.
circuit.append(cirq.X(readout))
circuit.append(cirq.H(readout))
builder = CircuitLayerBuilder(
data_qubits = data_qubits,
readout=readout)
# Then add layers (experiment by adding more).
builder.add_layer(circuit, cirq.XX, "xx1")
builder.add_layer(circuit, cirq.ZZ, "zz1")
# Finally, prepare the readout qubit.
circuit.append(cirq.H(readout))
return circuit, cirq.Z(readout)
model_circuit, model_readout = create_quantum_model()
Listing 8-4mBuild a Two-Layer Model qnn_mnist_tfq.ipynb
下一个任务是用量子组件将模型电路包装在 tfq-keras 模型中,以便训练它。这个模型被输入来自x_train_circ
的量子数据,它对经典数据进行编码。它使用一个参数化量子电路层tfq.layers.PQC
,根据量子数据训练模型电路。Farhi 等人提出在参数化电路中采用读出量子位的期望值来对这些图像进行分类。期望值返回一个介于 1 和–1 之间的值。
# Build the Keras model.
model = tf.keras.Sequential([
# The input is the data-circuit, encoded as a tf.string
tf.keras.layers.Input(shape=(), dtype=tf.string),
# The PQC layer returns the expected value of the readout gate, range [-1,1].
tfq.layers.PQC(model_circuit, model_readout),
])
Listing 8-4nBuild Keras Wrapper qnn_mnist_tfq.ipynb
由于预期读数在[–1,1]
范围内,优化铰链损耗是一个自然的选择。
Note
另一种有效的方法是将输出范围移动到[0,1],并将其视为模型分配给类 1 的概率。这可以与标准的 a TF . loss . binary cross entropy loss 一起使用。
为了使用这里的铰链损耗,我们需要做两个小的调整。首先,我们将标签y_train_nocon
从布尔转换为[-1,1]
,正如铰链损耗所预期的。
y_train_hinge = 2.0*y_train_nocon-1.0
y_test_hinge = 2.0*y_test-1.0
我们使用一个定制的hinge_accuracy
度量,它正确地将[–1, 1]
作为y_true
标签参数。
def hinge_accuracy(y_true, y_pred):
y_true = tf.squeeze(y_true) > 0.0
y_pred = tf.squeeze(y_pred) > 0.0
result = tf.cast(y_true == y_pred, tf.float32)
return tf.reduce_mean(result)
model.compile(
loss=tf.keras.losses.Hinge(),
optimizer=tf.keras.optimizers.Adam(),
metrics=[hinge_accuracy])
print(model.summary())
Listing 8-4oLabel Argument qnn_mnist_tfq.ipynb
这将打印出模型摘要。
我们现在训练 QNN 模型,大约需要 30 到 45 分钟——取决于您的系统。如果你不想等那么久,使用数据的一个小的子集(下面的 set NUM_EXAMPLES=500
)。这不会影响模型在训练过程中的进度,因为它只有 32 个参数,因此,约束这些参数所需的数据并不多。使用较少的例子可以更早地结束训练(大约 5 分钟),但是运行时间足够长,可以显示它在验证日志中取得了进展。
EPOCHS = 3
BATCH_SIZE = 32
NUM_EXAMPLES = len(x_train_tfcirc)
x_train_tfcirc_sub = x_train_tfcirc[:NUM_EXAMPLES]
y_train_hinge_sub = y_train_hinge[:NUM_EXAMPLES]
qnn_history = model.fit(
x_train_tfcirc_sub, y_train_hinge_sub,
batch_size=32,
epochs=EPOCHS,
verbose=1,
validation_data=(x_test_tfcirc, y_test_hinge))
qnn_results = model.evaluate(x_test_tfcirc, y_test)
Listing 8-4pTrain the Quantum Model qnn_mnist_tfq.ipynb
这给出了铰链精度、运行时间和损耗的以下输出。
训练精度报告了整个时期的平均值。在每个时期结束时评估验证准确性。
既然我们已经看了事物的量子方面,我们可能希望找出一个经典网络如何在相同的数据集上运行。尽管 QNN 可以解决这个简化的 MNIST 问题,但基本的经典神经网络在这个任务上可以胜过 QNN。在单个时期之后,传统的神经网络可以在维持集上实现> 98%的准确度。
在下面的示例中,经典的神经网络用于 1–7 分类问题,使用整个 28 × 28 图像,而不是对图像进行二次采样。这很容易收敛到接近 100%的测试集的准确性。
def create_classical_model():
# A simple model based off LeNet from https://keras.io/examples/mnist_cnn/
model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(32, [3, 3], activation='relu', input_shape=(28,28,1)))
model.add(tf.keras.layers.Conv2D(64, [3, 3], activation='relu'))
model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2)))
model.add(tf.keras.layers.Dropout(0.25))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(1))
return model
model = create_classical_model()
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
optimizer=tf.keras.optimizers.Adam(),
metrics=['accuracy'])
model.summary()
Listing 8-4qBuild the Classical Model qnn_mnist_tfq.ipynb
这将生成如下的模型摘要。
这个模型有将近 120 万个参数。接下来,我们按如下方式训练经典模型。
model.fit(x_train,
y_train,
batch_size=128,
epochs=1,
verbose=1,
validation_data=(x_test, y_test))
cnn_results = model.evaluate(x_test, y_test)
Listing 8-4rTrain the Classical Model qnn_mnist_tfq.ipynb
这个代码块为具有 120 万个参数的经典模型生成精度、损耗等方面的输出。为了更公平的比较,我们在二次抽样图像上尝试 37 参数模型。
def create_fair_classical_model():
# A simple model based off LeNet from https://keras.io/examples/mnist_cnn/
model = tf.keras.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(4,4,1)))
model.add(tf.keras.layers.Dense(2, activation='relu'))
model.add(tf.keras.layers.Dense(1))
return model
model = create_fair_classical_model()
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
optimizer=tf.keras.optimizers.Adam(),
metrics=['accuracy'])
model.summary()
Listing 8-4s37-Parameter
Model qnn_mnist_tfq.ipynb
这就产生了我们想要的 37 参数模型。
现在,我们用 37 个参数的新范围来训练这个模型。
model.fit(x_train_bin,
y_train_nocon,
batch_size=128,
epochs=20,
verbose=2,
validation_data=(x_test_bin, y_test))
fair_nn_results = model.evaluate(x_test_bin, y_test)
Listing 8-4tTrain the 37-Parameter Model qnn_mnist_tfq.ipynb
这给出了以下(截断的)输出。
最后,我们比较了量子神经网络和经典神经网络。
qnn_accuracy = qnn_results[1]
cnn_accuracy = cnn_results[1]
fair_nn_accuracy = fair_nn_results[1]
sns.barplot(["Quantum", "Classical, full", "Classical, fair"],
[qnn_accuracy, cnn_accuracy, fair_nn_accuracy])
Listing 8-4uComparison of Quantum and Classical qnn_mnist_tfq.ipynb
此代码块给出以下输出作为比较。
更高分辨率的输入和更强大的模型使得这个问题对 CNN 来说很容易。虽然相似功率(约 32 个参数)的经典模型在一小部分时间内训练到相似的精度,但经典神经网络优于量子神经网络。
在经典数据集中,鉴于近期量子系统的状态,量子系统很难击败经典神经网络。然而,在具有经典输入数据的量子系统上的练习确实承诺利用希尔伯特空间的多维度和某些特定问题的叠加能力。从经典数据中获得的见解也为我们在下一代量子计算系统上实现算法做好了准备,我们希望这将带来前所未有的计算能力。
量子卷积神经网络
如第三章所见,经典卷积神经网络(CNN)是图像处理和计算机视觉相关领域的流行模型。CNN 的结构包括将交替的卷积层(加上一个激活函数)和汇集层应用于输入阵列,通常在输出之前跟随一些完全连接的层。卷积层的工作原理是扫描整个输入阵列,并逐块应用不同的滤波器(通常是 2 × 2 或 3 × 3 矩阵)。它们检测图像中可能出现的特定特征。然后,使用池层对这些卷积的结果进行下采样,以提取最相关的特征并减少数据的大小,从而更容易在后续层中进行处理。常见的池化方法包括用最大值或平均值替换数据块。
CNN 具有便于有效利用数据的相关性信息的属性。然而,如果数据或模型的给定维度变得太大(这在大数据时代很可能发生),与 CNN 相关的计算费用可能会很快成为一个挑战。量子卷积神经网络(QCNN)使用量子计算环境为 CNN 提供了一种新的解决方案,以提高现有学习模型的性能。
图 8-8
QCNN 示意图(来源丛等 2018 [193])
qcn 首先由丛等人(2018) [193]提出。QCNNs 的结构受 CNN 结构的启发,如图 8-8 所示。在 QCNN 中,卷积是在相邻量子位对上执行的操作(参数化酉旋转),类似于常规的变分电路。这些卷积之后是池层,池层通过测量量子位的子集并使用测量结果来控制后续操作而受到影响。完全连接层的模拟是在最终测量之前对剩余量子位的多量子位操作。所有这些操作的参数都是在训练期间学习的。
在 Oh,Choi 和 Kim 在 2020 年完成的研究中[192]提出了一种模型,通过将 CNN 的结构应用于量子计算环境来有效地解决量子物理和化学中的分类问题。该研究还提出了一个可以用 O(log(n))深度计算的模型,使用多尺度纠缠重整化 ansatz (MERA)。
该研究介绍了一种方法,通过在现有计算机视觉中使用的 CNN 学习模型中添加一个使用量子系统的层来提高模型的性能。该模型也可用于小型量子计算机。混合学习模型可以通过在 CNN 模型中增加一个量子卷积层或者用卷积层代替来设计。本文还通过 TensorFlow 量子平台使用 MNIST 数据集进行训练,验证了 QCNN 模型相对于 CNN 是否能够高效学习。
关于丛等人[193]关于 QCNN 的另一篇论文的完整实践教程可在 www.tensorflow.org/quantum/tutorials/qcnn
的 Google AI 上获得。如果你对量子深度学习感兴趣,请按照自己的节奏浏览教程。
量子 CNN 的一个自然应用是对量子态进行分类。丛等人[193]的原始工作使用它们来区分不同的拓扑相位。QCNNs 也可以用来分类图像,就像它们的经典对应物一样。
摘要
量子数据是自然或人工量子系统中出现的任何数据源。这可以是从量子力学实验中得到的经典数据,也可以是由量子设备直接生成的数据,然后作为输入输入到算法中。有证据表明,由于量子力学特性,对量子数据的混合量子-经典机器学习应用可以提供优于仅经典机器学习的量子优势。量子数据表现出叠加和纠缠,导致联合概率分布,这可能需要指数数量的经典计算资源来表示或存储。
也许量子机器学习最直接的应用是量子数据——量子系统和过程产生的实际状态。许多量子机器学习算法通过将数据映射到量子力学状态,然后使用基本的量子线性代数子例程操纵这些状态,来找到经典数据中的模式。这些量子机器学习算法可以直接应用于光和物质的量子态,以揭示它们的潜在特征和模式。由此产生的量子分析模式通常比从量子系统中提取的数据的经典分析更有效和更有启发性。
本章探讨了 D-Wave、Xanadu 的 PennyLane 的 QNN 和 Google 的 TensorFlow Quantum 上的旅行销售员问题和解决方案,并探讨了量子卷积神经网络。我们还探讨了 QCNN 领域的最新研究和进展。
第九章探索先进的领域,如量子化学、量子行走和层析成像,量子机器学习在这些领域正变得活跃并有望发展。
Footnotes 1
湖泊乘数: https://en.wikipedia.org/wiki/Lagrange_multiplier#:~:text=In%20mathematical%20optimization%2C%20the%20method,chosen%20values%20of%20the%20variables
2
出差销售人员问题: https://en.wikipedia.org/wiki/Travelling_salesman_problem#cite_note-6
3
qbsolv 基于 Wang,Lu,Glover 和 Hao (2012)的论文“大型无约束二元二次优化的多级算法”。[163]
4
经典玻尔兹曼机:https://en.wikipedia.org/wiki/Boltzmann_machine
【167】
5
pennylanae/pennylane 根据 Apache 许可证 2.0 获得许可。
6
福克状态: https://en.wikipedia.org/wiki/Fock_state#:~:text=In%20quantum%20mechanics%2C%20a%20Fock,the%20Soviet%20physicist%20Vladimir%20Fock
。
7
strong 纠缠层文档: https://pennylane.readthedocs.io/en/stable/code/api/pennylane.templates.layers.StronglyEntanglingLayers.html
8
对于这个练习,代码改编自 TensorFlow Quantum 文档: https://www.tensorflow.org/quantum/tutorials/mnist
9
根据 Apache 许可证 2.0 版许可(“许可证”)
**
九、QML:前方的路
预测未来的最好方法是创造未来。
—亚伯拉罕·林肯
量子机器学习(QML)是一个交叉学科,由两个最令人兴奋的研究领域组成:量子计算和经典机器学习。
到目前为止,我们已经探索了几种算法、概念和见解。我们可以用经典的计算机解决问题,无论是笔记本电脑还是 GPU 集群。用目前非常非常昂贵(几千万美元)的量子计算机来解决它没有什么价值。量子机器学习中有趣的问题是,机器学习和 AI 中是否存在与量子计算机天然契合但在经典硬件上具有挑战性的问题。这需要对机器学习和当代量子计算机都有很好的理解。
Note
本章重点讨论与量子机器学习相关的过程和应用的正在进行的研究领域,如量子行走、哈密顿模拟、量子 Boost、量子金融、量子化学和张量网络,包括两个动手练习。
量子计算和量子信息是出现在计算机科学各个领域的学科,如信息论、密码学、情感表示和图像处理,因为在经典计算机上看起来效率低下的任务可以通过利用量子计算的力量来实现[3] [233]、[234]、[235]、[236]。加速某些任务的新方法以及计算机科学和其他几个科学领域之间的跨学科研究已经吸引了对这个新兴领域的浓厚科学兴趣。
人们对量子计算和机器学习领域的承诺越来越有信心,这催生了许多受量子承诺推动的初创企业。除了众所周知的机构,如谷歌,IBM,Rigetti,世外桃源,D-Wave,不一而足。以下是最近量子科技初创企业生态系统中一些年轻有为的成员的例子。
-
TQuT Inc. (
http://tqut.co/
):由 Ritaban Chowdhury 创办,在美国注册,TQuT 是一家令人兴奋的量子初创公司。量子技术的新时代开启了材料发现的新可能性。需要一个现代的、基于云的、API 驱动的、可扩展的材料发现平台来有效地探索这些领域。它正在开发一个基于网络的材料发现平台,该平台利用云中的高性能计算和量子计算硬件,使材料发现管道开发变得可扩展、可重复使用和更容易。 -
夸库恩 (
https://quacoon.com
):一个基于量子人工智能的平台,为建立和管理弹性和可持续的供应链提供协作供应链智能,以及解决产品短缺、拥堵和其他因意外事件造成的中断。Quacoon 于 2020 年由蒂娜·安妮·塞巴斯蒂安领导的团队成立。 -
Quantropi 的技术为用户提供了实现无条件安全的选择,同时具有成本效益、可伸缩性和高效性。他们发表的工作包括解决保密[286]和量子公钥分配[287]的研究(和相关专利)。最近,他们被选为 2020 年科学初创企业类别柏林倒塌墙突破的决赛入围者之一,并获得了 2020 年 BOBs 最佳新(渥太华)商业奖。
-
Quantropi(
www.quantropi.com
):2018 年成立于加拿大渥太华,是量子通信领域的后起之秀。它利用量子物理的数学定律来加密传输中的数据,而不需要量子计算机的处理能力。他们的解决方案在当前的互联网上提供了真正安全的量子密钥分发(QKD),允许今天的用户用自己的计算机发送量子加密的数据。他们拥有三项独特的专利技术,形成了完整的端到端解决方案。-
量子熵扩展协议
-
伽罗瓦公钥(GPK)
-
量子公钥信封(QPKE)(专利申请中)
-
今天,在量子计算的所有应用中,大规模吸引注意力的是与原子、分子和其他生物化学系统的模拟相关的应用,这些应用独特地适合于量子计算。这是因为大型系统的基态能量、分子整体的动态行为或复杂的分子行为(如蛋白质折叠)通常很难计算,或者完全不可能通过经典计算或实验来确定[151][182]。
化学量子计算
对有用的量子计算机将很快实现的预期,激发了人们对开发量子算法的深入研究,这些算法可能会在经典的棘手计算问题上取得进展。虽然许多研究领域希望看到这种量子设备的发展带来变革,但计算化学将成为首批从这种新技术中受益的领域之一。由于随着轨道的增加,希尔伯特空间的大小呈指数增长,具有数十个量子位的量子计算机可能会超越经典算法[182]、[183]、[184]。实现这样的能力不仅取决于量子位的质量,还取决于算法的效率。
对于量子化学领域,根据精确的参考计算训练非线性回归模型(如高斯过程或神经网络)可以直接预测化学性质[174]、[175]、[176]。原子力的 ML 预测可以驱动分子动力学模拟,而不确定性估计和主动学习可以指导更多参考计算的获取,以改善之前训练的模型[179] [180]。直接获得这种化学性质的精确预测允许进行广泛、大规模的研究,这在传统的量子化学模拟中是不可行的。
具有所需性质的分子和材料的合理设计既需要计算精确微观性质的能力,例如能量、力和特定构型的静电多极,又需要对势能表面进行有效采样以获得相应的宏观性质。提供这一点的工具是分别植根于量子力学和统计力学的精确的第一性原理计算。所有这些都伴随着高计算成本,这阻碍了大型系统或采样密集型应用的计算,例如长时间尺度的分子动力学模拟,从而为搜索广阔的化学化合物空间带来了严重的瓶颈。为了克服这一挑战,人们越来越努力地用机器学习来加速量子计算。
在多电子系统中,用目前的数学方法不可能得到薛定谔方程的精确解。Hartree-Fock 方法,已经有广泛的 QML 算法,被开发用于近似求解与时间无关的薛定谔方程。多电子系统的总能量可以用单电子和双电子算符来表示。通过最小化总能量,薛定谔方程可以在数学上转化为单电子 Hartree-Fock 方程。本征值和波函数表示轨道能量和分子、原子轨道。
随着我们对量子计算机的理解不断成熟,有利于化学和分子模拟的新方法和新技术的发展也将不断成熟。就目前的情况而言,我们有信心量子计算机能够帮助那些需要明确表示波函数的量子化学计算,要么是因为对模拟性质的高精度要求,要么是因为系统中的高度纠缠。在这些情况下,波函数维数的指数增长使得在经典计算机上的操作和存储效率非常低。事实上,即使是中等大小的系统,也很难明确保持全波函数。
举个例子,一个包含 42 个原子的青霉素分子需要 10 个 86 个经典比特。电子组态的指数大参数空间的模拟将需要比宇宙中的原子更多的状态!与经典计算机所需的比特数相反,量子计算机需要大约 286 个量子比特。一个咖啡因分子需要大约 10 个 ?? 48 个经典比特,而在量子计算平台上大约需要 160 个量子比特。
随着量子硬件和软件社区继续取得快速进展,量子计算对量子化学的直接作用已经出现。量子化学量子算法的进步需要量子信息论和经典量子化学技术。
开放费米子
化学和材料的量子模拟预计将是近期和容错量子器件的重要应用。然而,开发和研究这些问题的算法可能是困难的,因为在化学和量子算法领域都需要大量的领域知识。为了帮助弥合这一差距,并向更多的研究人员开放这一领域,谷歌开发了 OpenFermion 软件包( www.openfermion.org
)。OpenFermion 是一个开源软件库,主要是在 Apache 2.0 许可下用 Python 编写的,用于在量子硬件上模拟费米子和玻色子模型以及量子化学问题。通用电子结构软件包的接口简化了分子规范和量子电路之间的转换,用于在量子计算机上解决或研究电子结构问题,最大限度地减少了进入该领域所需的领域专业知识的数量。
OpenFermion 可以在用户模式下安装,如下所示。
$ python -m pip install --user openfermion
Note
谷歌人工智能研究团队在 https://quantumai.google/openfermion/tutorials/intro_to_openfermion
有关于 OpenFermion 的全面在线教程。我们强烈建议您浏览它们,以获得更深入的见解。
化学系统的量子模拟是量子计算机最有前途的近期应用之一。最有前途的量子计算应用之一是能够有效地模拟自然界中经典计算机难以处理的量子系统。自从上个世纪电子计算机出现以来,计算在化学发展中发挥了重要作用。多年来,计算化学物质静态和动态性质的数值方法已经彻底改变了化学学科。随着量子计算的出现,类似的突破性进展已经被证明是有潜力的。
量子行走
量子行走[223]是众所周知的经典随机行走的量子力学模拟。在研究中已经确立了一段时间,量子行走在量子信息处理的各个领域中具有重要作用[198]、[199]、[200]。它们是管理数据库搜索[201]、图形同构[202]、[203]、[204]、网络分析和导航[205]、[206]、量子模拟[207]、[208]、[209]以及生物过程建模[210] [211]的量子算法的核心。量子行走的物理性质已经在各种系统中得到证明,如核磁共振[212] [213],体[214]和光纤[215] [216]光学,囚禁离子[216]、[217]、[218],囚禁中性原子[219]和光子学[221]、[222]。量子行走是最重要的哈密顿模拟方法之一。
传统上,随机游动的数学概念已经存在了一段时间,可以描述如下。这是一个随机的过程,涉及一个被放置在某个 n 维介质中的“步行者”(可能某人喝醉了,以至于事先不知道他/她下一步要去哪里)。然后,我们重复查询一些随机变量,并基于我们的测量结果,更新行走者的位置向量(即,图形或网格上的位置)。?? 1
让我们看一个非常基本的随机漫步的例子。我们从一个图的某个特定顶点 v 开始,重复下面的序列几次:验证 v 是否被标记,如果没有,那么随机选择它的一个邻居,并将 v 设为那个邻居。这表明随机漫步是一个具有随机演化时间系统的动态路径。这个过程也可以用一维图形来解释,我们可以考虑在一条数轴的原点上放置一个标记,在每个整数上做标记。
图 9-1 说明了一个经典的随机漫步,其中在时间 t = 0 时处于 v 的漫步有可能在时间 t = 1 时结束于( v + 1)或(v-1)。
图 9-1
经典随机漫步例子
看看经典的随机游走,乍一看可能会觉得是一个多余的算法。毕竟,它只需要一个空间复杂度为 O (log N )的空间,因为我们需要跟踪当前顶点 v ,也许还需要一个计数器来跟踪步行者已经走了多少步。但是,一点也不多余!相反,例如,该算法可以使用 O (log N )空间来决定是否存在从特定顶点 v 到特定顶点 u 的路径,这在处理统计学习和概率规则的非常低维度的实际量子物理时变得更加清晰和非常有用。行走将从 v 开始,只有 u 会被标记;可以看出,如果在 G 中存在一条从 v 到 u 的路径,那么在多项式 ( N )步中,行走器到达 u 。随机游走类似于格罗弗搜索和伊辛模型,在某种意义上,无论它们出现在哪里,你都可以尝试用它们的量子版本替换它们,并希望有所改进。
量子行走类似于经典的随机行走,除了决定随机行走的步数的函数和行走者的位置向量是使用量子位和酉变换编码的。换句话说,构造规则随机行走背后的思想被转化为量子模拟。
让我们在 pyQuil 中进行一次动手练习,以演示基于 Qiang,Lok 等人在 2016 年发表的题为“量子处理器上的高效量子行走”的论文的连续时间量子行走* (CTQW)。*【197】。
在经典的随机漫步中,具有边 E 和顶点 V 的图 G 的邻接矩阵 A 由下式给出
(9.1)
拉普拉斯 L 是二阶空间导数的二维各向同性度量,突出显示快速强度变化的区域,并用于边缘检测。方程 9.1 的图 G 的拉普拉斯由下式给出
(9.2)
拉普拉斯算子的定义有时不同于等式 9.2 中的定义。这里使用这个定义是因为它允许 L 是连续统中拉普拉斯算子∇ 2 的离散近似。
经典连续随机行走的行为由拉普拉斯算子确定,并由概率 p ( t )的长度向量| V 描述,其中 p ( t )是在时间 t 处于顶点 i 的概率,并由微分方程【200】、【201】给出。
(9.3)
方程 9.3 有如下解:p(t)=eLtp(0)。这可以被视为扩散方程的离散模拟,这在量子行走算法中是有帮助的,量子行走算法在物理系统中是重要的,例如俘获离子和光子学。
让事情回到原点:薛定谔方程,由给出,可以用来获得拉普拉斯。 2 我们之前遇到过拉普拉斯算子,尤其是在第八章中解决 NP 难的旅行售货员问题时。薛定谔方程左边的指数算符通常用
中对应的幂级数来定义。通过泛函微积分的性质,下面的算子描述了我们广为使用的著名酉算子:
。从数学和物理学的角度来看,这意味着拉普拉斯算子保持了系统状态的规范化。
因此,等式 9.3 可以用拉普拉斯项表示如下。
(9.4)
微分方程 9.4 决定了连续随机游走的量子模拟的行为。该解决方案由下式给出
我们不一定需要拉普拉斯算子来定义量子行走。它可以在任何遵守图 G 的结构的算子的帮助下被定义(即,仅允许过渡到图中的相邻顶点或保持静止[222,223])。
为了掌握量子行走的行为,我们首先来看一个在直线上连续时间量子行走的例子。在这种情况下,对于动量p∈[π, π ]来说,表示无限直线的图的拉普拉斯算子的本征态是本征值为 2(cosp—1)的动量态。动量状态根据位置状态∣ x ⟩给出。应用后,拉普拉斯算子由下式给出
拉普拉斯算子由下式给出
(9.5)
从方程 9.5 ,我们找到时间 t 的概率分布。
(9.6)
其中初始位置∣ ψ (0)⟩ = ∣ 0⟩)由下式给出
(9.7)
在这种情况下,经典量子行为类似于图 9-2 中的图解。
图 9-2
量子到经典随机漫步
经典连续时间随机游走的概率分布在高斯宽度为的 x = 0 处接近其峰值,而量子游走在极值处具有其最大峰值,随着接近开始位置的 x = 0 处,两者之间的振荡幅度减小。
Note
随机漫步可以有几种类型。经典随机游走的二项分布在 Cirq 教程 https://colab.research.google.com/github/quantumlib/Cirq/blob/master/docs/tutorials/quantum_walks.ipynb#scrollTo=yaKGvbmieSIL
中有说明。我们强烈建议您访问该网站,并通过 Cirq 版本的量子行走来更好地了解这个问题的多样性。
由于在经典情况下不会发生的不同相态之间的相消干涉,量子行走的行为是不同的。相反,经典行走的概率分布没有振荡,而是以 x = 0 为中心的单个峰值,其随着时间 t 的增加而变宽和变平。因此,以量子振幅取代机率,我们看到量子领域的干涉可以产生完全不同的结果。
类似图形的数值或矩阵表示如图 9-3 所示。
图 9-3
经典随机到量子行走
编码量子行走
在了解了 CTQW 的基本行为之后,我们根据 Qiang,Lok 等人的论文[197],从 Rigetti 的 QVM 和 pyQuil 开始动手练习。
从该书的网站打开名为quantum_walk_pyquil.ipynb
的 Jupyter 笔记本文件,启动三个不同的终端:用qvm -S
命令启动 QVM,另一个用quilc -S
命令启动 Quilc,第三个启动 Jupyter notebook
。
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
from scipy.linalg import expm
%matplotlib inline
from pyquil import Program
from pyquil.gates import H, X, CPHASE00
from pyquil.api import WavefunctionSimulator
from pyquil.api import ForestConnection
from pyquil.api import QVMConnection
qvm = QVMConnection()
wfn_sim = WavefunctionSimulator()
Listing 9-1aLibraries and QVM Connection quantum_walk_pyquil.ipynb
在下一步中,我们开始查看如何利用 NetworkX 图形库为四个节点的连续时间经典行走编码图形 G 。
G = nx.complete_graph(4)
nx.draw_networkx(G)
Listing 9-1bClassical Walk with Four Nodes quantum_walk_pyquil.ipynb
这个代码块产生一个四节点 K 4 图 G 图 9-4 用于经典行走。
图 9-4
具有四个节点的经典随机游走图(K4
完整图形的频谱需要一个等于(n-1)的特征值,其中𝑁是节点数,其余特征值等于 1。下一步,我们定义邻接矩阵 A 和相应的特征值。
A = nx.adjacency_matrix(G).toarray()
eigvals, _ = np.linalg.eigh(A)
print(eigvals)
Listing 9-1cAdjacency Matrices quantum_walk_pyquil.ipynb
这将给出以下矩阵作为输出。
对于 CTQW,通常的哈密顿量是邻接矩阵 A 。这在这里通过添加单位矩阵而被稍微修改;也就是我们取(请注意,这里我们改变了哈密顿量的字体,以区分哈密顿量的
和哈达玛门的 H )。这种修改减少了我们需要应用的门的数量,因为具有 0 个特征值的特征向量不获取相位。因此,接下来,我们使用矩阵 A 来计算哈密顿量,为此我们使用
NumPy kron
函数来生成两个数组的克罗内克乘积。
hamil = A + np.eye(4)
had = np.sqrt(1/2) * np.array([[1, 1], [1, -1]])
Q = np.kron(had, had)
Q.conj().T.dot(hamil).dot(Q)
Listing 9-1dHamiltonian and Adjacency Matrices quantum_walk_pyquil.ipynb
此代码块生成以下矩阵作为乘积。
这个输出表明 K n 图是哈达玛可对角化的。这允许我们写,其中 Q = * H * ⊗ H ,并且 H 表示哈达玛门。我们还看到,时间演化算符
也通过相同的变换对角化。
现在,是计算连续时间量子行走的时候了。为了实现这一点,我们首先定义一个函数,将矩阵改变为对角基,然后计算其时间演化,并最终将其改变回计算基。从参考文献[197]可知,我们的情况下 γ = 1。因此,模拟这些的电路如清单 9-1e 所示。
def k_4_ctqw(t):
# Change to diagonal basis
p = Program(H(0), H(1), X(0), X(1))
# Time evolve
p += CPHASE00(-4*t, 0, 1)
# Change back to computational basis
p += Program(X(0), X(1), H(0), H(1))
return p
Listing 9-1eFunctions for Matrices and Time Evolution quantum_walk_pyquil.ipynb
我们现在将量子漫步与经典的随机漫步进行比较。经典的时间演化算子是e??(τI)t,其中τ是图的转移矩阵。作为初始条件,我们选择∣ ψ (0)⟩ = ∣ 0⟩与等式 8 中相同。6 和 8。7 。这意味着 walker 从第一个节点开始。之后,由于对称性,除了∣0⟩,所有节点被占据的概率是相同的。
图 9-5
量子与经典随机漫步
T = A / np.sum(A, axis=0)
time = np.linspace(0, 4, 40)
quantum_probs = np.zeros((len(time), 4))
classical_probs = np.zeros((len(time), 4))
for i, t in enumerate(time):
p = k_4_ctqw(t)
wvf = wfn_sim.wavefunction(p)
vec = wvf.amplitudes
quantum_probs[i] = np.abs(vec)**2
classical_ev = expm((T-np.eye(4))*t)
classical_probs[i] = classical_ev[:, 0]
f, (ax1, ax2) = plt.subplots(2, sharex=True, sharey=True)
ax1.set_title("Quantum evolution")
ax1.set_ylabel('p')
ax1.plot(time, quantum_probs[:, 0], label='Initial node')
ax1.plot(time, quantum_probs[:, 1], label='Remaining nodes')
ax1.legend(loc='center left', bbox_to_anchor=(1, 0.5))
ax2.set_title("Classical evolution")
ax2.set_xlabel('t')
ax2.set_ylabel('p')
ax2.plot(time, classical_probs[:, 0], label='Initial node')
ax2.plot(time, classical_probs[:, 1], label='Remaining nodes')
Listing 9-1fTime Evolution quantum_walk_pyquil.ipynb
列表 9-1f 产生图 9-5 中的图,以比较 CTQW 和经典行走的时间相关概率演变。
正如预期的那样,量子行走表现出相干振荡,而经典行走收敛于的稳态分布
对于一个 K 4 图,CTQW 和经典行走之间的这种比较可以容易地推广到如下的任何图。
def k_2n_ctqw(n, t):
p = Program()
# Change to diagonal basis
for i in range(n):
p += Program(H(i), X(i))
# Create and apply CPHASE00
big_cphase00 = np.diag(np.ones(2**n)) + 0j
big_cphase00[0, 0] = np.exp(-1j*4*t)
p.defgate("BIG-CPHASE00", big_cphase00)
args = tuple(["BIG-CPHASE00"] + list(range(n)))
p.inst(args)
# Change back to computational basis
for i in range(n):
p += Program(X(i), H(i))
return p
def k_2n_crw(n, t):
G = nx.complete_graph(2**n)
A = nx.adjacency_matrix(G)
T = A / A.sum(axis=0)
classical_ev = expm((T-np.eye(2**n))*t)
return classical_ev[:, 0]
time = np.linspace(0, 4, 40)
quantum_probs = np.zeros((len(time), 8))
classical_probs = np.zeros((len(time), 8))
for i, t in enumerate(time):
p = k_2n_ctqw(3, t)
wvf = wfn_sim.wavefunction(p)
vec = wvf.amplitudes
quantum_probs[i] = np.abs(vec)**2
classical_probs[i] = k_2n_crw(3, t)
f, (ax1, ax2) = plt.subplots(2, sharex=True, sharey=True)
ax1.set_title("Quantum evolution")
ax1.set_ylabel('p')
ax1.plot(time, quantum_probs[:, 0], label='Initial node')
ax1.plot(time, quantum_probs[:, 1], label='Remaining nodes')
ax1.legend(loc='center left', bbox_to_anchor=(1, 0.5))
ax2.set_title("Classical evolution")
ax2.set_xlabel('t')
ax2.set_ylabel('p')
ax2.plot(time, classical_probs[:, 0], label='Initial node')
ax2.plot(time, classical_probs[:, 1], label='Remaining nodes')
Listing 9-1gTime Evolution quantum_walk_pyquil.ipynb
最后一个代码块产生了一个比较图,如下所示,这与图 9-5 非常相似,其中较大的分布导致了经典部分的较高平滑度,正如预期的那样。
多项式时间哈密顿模拟
在本书的整个旅程中,当处理量子系统的动力学时,我们已经健康地使用了酉变换。除了测量之外,振幅向量所描述的量子状态,可以藉由与酉矩阵相乘而改变:例如,一个两个量子位元的闸张量,与其他量子位元上的单位系在一起。然而,这种数学范式并没有阐明哪一种幺正出现在一个物理系统中。这个问题的答案由哈密顿系统决定,哈密顿系统是系统中总能量 E 对应的可观测量。这里
是含时态∣ * ψ * ( * t * )⟩.的能量 E 的期望值
我们可以将哈密顿量解释为描述系统的物理特性。这些特征并不决定系统的初始状态∣ψI(t)⟩),但它们确实决定了状态随时间的演化(即状态∣ψf(t*)⟩)作为时间参数 t 的函数,给定初始状态,例如∣ 这是由量子力学中最重要的方程决定的:薛定谔方程。*
主要的哈密顿模拟方法之一是量子行走。我们已经探讨了哈密顿量,并在各种编码练习和计算中引用了它们的性质。
当一个量子态随着时间从∣的初始n-量子位态ψIt)⟩演化到最终态∣ψf(t)⟩,我们可能希望知道哈密顿量最终态所包含的信息。反过来,我们也可能希望强加一个已知的哈密顿量这个实现给定哈密顿演化的过程被称为哈密顿模拟。哈密尔顿模拟的研究有两大类:模拟模拟和数字模拟,模拟模拟与模拟处于自然状态的哈密尔顿的量子系统有关,数字模拟将时间演化分解为量子门。
哈密顿量模拟的问题定义如下。给定一个哈密顿量,一个时间 t ,和一个误差容限 ϵ (例如,轨迹距离),找到一个量子电路,对一个未知量子态执行幺正运算
,误差至多为 ϵ 。作为一般结果,哈密顿量可以是依赖于时间的。哈密顿模拟的常见应用包括连续时间量子算法,如量子行走、绝热优化和线性方程。
如果我们有一个由几个其他哈密顿量之和组成的与时间无关的哈密顿量,使得那么这些“成员”哈密顿量中的每一个应该相对更容易模拟。至于不可交换的
,因式分解规则不适用。Seth Lloyd 在其 1996 年的论文[207]中使用了以下公式来实现这一点。
(9.8)
现在,如果我们将这个方程进行三重化(见第七章,方程 7)。24 ,其陈述了对于小的 t ,因式分解规则近似有效,我们可以将对于时间 t 的演变写成长度为δt的小时间步长的序列,如
(9.9)
图 7-9 显示了为便于阅读而复制的 t 灭菌。方程 9.9 左侧的表达式显示了每个时间步长δt的非平凡误差。然而,在这种情况下,等式 9.8 中的误差变得可以忽略不计。注意,随着时间步长δt的长度减小,序列必须重复的次数增加。考虑到序列数量和时间步长大小之间的权衡,这种方法允许我们通过操纵项来模拟哈密顿量。这种多项式时间哈密顿量模拟的方法表明,如果将哈密顿量分解为初等哈密顿量之和的方法是已知的,并且如果我们知道如何模拟这些初等哈密顿量,那么我们可以按照我们期望的方式近似地演化一个量子系统。
在离散变量量子位模型中,哈密尔顿模拟的有效方法已在文献中广泛讨论,提供了几种依赖于哈密尔顿性质的实现,并导致线性模拟时间[224,225]。哈密顿模拟的有效实现也存在于连续变量(CV)公式[226]中,具体应用于玻色-哈伯德哈密顿量,其描述了正交位置状态的晶格上的相互作用玻色子粒子系统[227]。这种方法非常适合光子量子计算和通信,这两者都是活跃研究的主题。
系综和 qboost
QBoost 由 Google 和 D-Wave 的研究人员在 2008 年和 2009 年提出[228]、[229]、[230],作为一种迭代训练算法,在每次迭代中通过解决一个硬优化问题来选择弱分类器的子集。通过连接弱分类器的子集来递增地构建强分类器。它作为一种新的离散优化方法被引入到大规模二元分类器的 boosting 框架中进行训练。主要目标是将机器学习训练问题转换为现有绝热量子硬件所需的格式。
单一的机器学习模型不太可能适合所有可能的场景,因为任何学习算法都有优点和缺点。集成将多个模型结合起来,以实现比任何组成模型更高的泛化性能。
基于使用多个学习器的机器学习算法属于更广泛的集成学习算法类别[231]、[232]。集成方法通过考虑一组训练模型来构造更好的分类器。训练模型(或分类器)的集合一起决定新的预测,这有助于组合其成员模型的个体优势。
集成中的组成模型也被称为基分类器或弱学习器,复合模型被称为强学习器。当基本分类器之间存在相当大的差异时,集成通常会产生更好的结果。当策略组合可以减少总误差时,基本分类器在存在足够多样性的情况下产生各种类型的误差,从而理想地提高性能。
集合方法的程序有两个主要步骤。
-
从训练数据开发一组基本分类器。
-
将它们组合起来形成合奏。
最简单的组合,基础学习者投票,标签预测基于多数。更复杂的方法衡量基础学习者的投票。
然而,这就给我们带来了一个挑战,那就是集合弱学习者以产生最大可能的效率。有几种方法可以实现这一点。例如,给定当前的模型集合,我们可以根据该模型表现良好的地方再添加一个。或者,我们可以查看所有模型之间预测的所有相关性,并优化最不相关的预测值。由于后一种方法是全局的,它默认映射到量子计算机。
直觉上,我们意识到,在用集成弄脏我们的手之前,我们需要洞察损失函数和正则化——机器学习中的两个关键概念——在我们能够足够自信地对各种模型的误差函数的集体性能做出判断之前。
这就是一些实践经验是有益的地方。因此,我们通过动手编码来研究集成方法和 QBoost。
全体
首先,我们从书的网站下载并打开名为qboost_ensemble.ipynb
的 Jupyter 笔记本文件。既然我们已经讨论了系综的基础,让我们导入一些包,并将我们的品质因数定义为平衡数据集中的精度。
import matplotlib.pyplot as plt
import numpy as np
import sklearn
import sklearn.datasets
import sklearn.metrics
%matplotlib inline
metric = sklearn.metrics.accuracy_score
Listing 9-2aLibraries qboost_ensemble.ipynb
接下来,我们生成一个由两个形成同心圆的类组成的随机数据集。
np.random.seed(0)
data, labels = sklearn.datasets.make_circles()
idx = np.arange(len(labels))
np.random.shuffle(idx)
# train on a random 2/3 and test on the remaining 1/3
idx_train = idx[:2*len(idx)//3]
idx_test = idx[2*len(idx)//3:]
X_train = data[idx_train]
X_test = data[idx_test]
y_train = 2 * labels[idx_train] - 1 # binary -> spin
y_test = 2 * labels[idx_test] - 1
scaler = sklearn.preprocessing.StandardScaler()
normalizer = sklearn.preprocessing.Normalizer()
X_train = scaler.fit_transform(X_train)
X_train = normalizer.fit_transform(X_train)
X_test = scaler.fit_transform(X_test)
X_test = normalizer.fit_transform(X_test)
plt.figure(figsize=(6, 6))
plt.subplot(111, xticks=[], yticks=[])
plt.scatter(data[labels == 0, 0], data[labels == 0, 1], color='navy')
plt.scatter(data[labels == 1, 0], data[labels == 1, 1], color='red');
Listing 9-2bGenerate Dataset qboost_ensemble.ipynb
此代码块生成以下循环数据集作为输出。
可以回忆一下,我们在第三章中讨论过经典感知器。
Note
如果你对量子感知机,在 https://qml.entropicalabs.io/
浏览教程。
在这个实验室里,让我们再次训练一个感知机。
from sklearn.linear_model import Perceptron
model_1 = Perceptron()
model_1.fit(X_train, y_train)
print('accuracy (train): %5.2f'%(metric(y_train, model_1.predict(X_train))))
print('accuracy (test): %5.2f'%(metric(y_test, model_1.predict(X_test))))
Listing 9-2cTrain a Perceptron qboost_ensemble.ipynb
这给出了下面的准确性。
感知器的决策表面是线性的,因此,我们得到的准确性很差。也许值得尝试一种具有非线性核的支持向量机(SVM ),看看会发生什么。
from sklearn.svm import SVC
model_2 = SVC(kernel='rbf')
model_2.fit(X_train, y_train)
print('accuracy (train): %5.2f'%(metric(y_train, model_2.predict(X_train))))
print('accuracy (test): %5.2f'%(metric(y_test, model_2.predict(X_test))))
Listing 9-2d
Apply SVM qboost_ensemble.ipynb
这一次我们得到了以下精度结果。
输出表明,SVM 在训练集上表现较好,但在测试数据上表现较差,因此不适合推广。
Boosting 是一种集成方法,它明确地寻找相互补充的模型。boosting 算法之间的差异在于它们如何组合弱学习者。
自适应增强(AdaBoost
)是一种流行的方法,它基于弱学习者各自的准确度顺序组合弱学习者。它有一个凸的目标函数,不会因为复杂而受到惩罚。AdaBoost
很可能包括最终集成中所有可用的弱学习者。清单 9-2e 是AdaBoost
与几个学习能力差的学员一起进行的训练练习。
from sklearn.ensemble import AdaBoostClassifier
model_3 = AdaBoostClassifier(n_estimators=3)
model_3.fit(X_train, y_train)
print('accuracy (train): %5.2f'%(metric(y_train, model_3.predict(X_train))))
print('accuracy (test): %5.2f'%(metric(y_test, model_3.predict(X_test))))
Listing 9-2eAdaBoost qboost_ensemble.ipynb
AdaBoost 产生以下输出,其精度也大致相同(与 SVM 相比只有非常微小的改进)。
QBoost
QBoost [230]的思想是量子计算机上的优化不限于凸目标函数。这允许我们添加任意的惩罚条款,并重新表述我们的目标[230]。QBoost 问题可以定义如下。
其中hk(xI)为训练实例 k 对弱学习者的预测。这个公式中的权重是二进制的。因此,这个目标函数默认映射到伊辛模型。正则化确保了稀疏性。它不是经典的正则化;在数字计算机上很难优化这一项。
扩展目标的二次部分,我们有
其中,yI2为常数。因此,优化简化为
这种形式告诉我们,我们将弱学习者的预测之间的所有相关性视为有一个总和hk(xI)hl(xI)。因为这一项有一个正号,我们惩罚相关性。另一方面,与真标签的相关性,hk(xI)yI)有负号,表示正则项不变。
让我们将前一节中的三个模型都视为弱学习者,计算它们的预测,并将其设置为 1。预测被缩放以反映目标中的平均值。
models = [model_1, model_2, model_3]
n_models = len(models)
predictions = np.array([h.predict(X_train) for h in models], dtype=np.float64)
# scale hij to [-1/N, 1/N]
predictions *= 1/n_models
λ = 1
Listing 9-2fModel Definition qboost_ensemble.ipynb
我们创建目标函数的二次二元优化(曲波)。
w = np.dot(predictions, predictions.T)
wii = len(X_train) / (n_models ** 2) + λ - 2 * np.dot(predictions, y_train)
w[np.diag_indices_from(w)] = wii
W = {}
for i in range(n_models):
for j in range(i, n_models):
W[(i, j)] = w[i, j]
Listing 9-2gDefine QUBO qboost_ensemble.ipynb
我们用模拟退火法求解二次二进制优化问题,并读出最优权重。
import dimod
sampler = dimod.SimulatedAnnealingSampler()
response = sampler.sample_qubo(W, num_reads=10)
weights = list(response.first.sample.values())
Listing 9-2hSolve QUBO qboost_ensemble.ipynb
我们定义了一个预测函数来帮助测量精度。
def predict(models, weights, X):
n_data = len(X)
T = 0
y = np.zeros(n_data)
for i, h in enumerate(models):
y0 = weights[i] * h.predict(X) # prediction of weak classifier
y += y0
T += np.sum(y0)
y = np.sign(y - T / (n_data*len(models)))
return y
print('accuracy (train): %5.2f'%(metric(y_train, predict(models, weights, X_train))))
print('accuracy (test): %5.2f'%(metric(y_test, predict(models, weights, X_test))))
Listing 9-2iPrediction Function qboost_ensemble.ipynb
这给出了以下输出精度。
精确度与我们最强的弱学习器一致:AdaBoost 模型。看看最优权重,这在weights
命令的输出中是显而易见的。
只有 AdaBoost 进入了最后的合奏。前两个模型表现不佳,它们的预测是相关的。然而,如果我们通过设置 λ = 0 来移除正则化,第二个模型也会进入集合,从而降低整体性能。这证明了正规化的重要性。
量子图像处理(QIMP)
量子图像处理是量子信息处理的一个子领域[3],[237],它利用量子并行性的特性来加速许多处理任务。量子图像处理的第一步是提出在量子计算机上捕捉和存储图像的方法。已经提出了量子计算机上图像的各种表示,例如量子位晶格,其中图像是量子位的二维阵列[239];真实 Ket,其中图像是具有灰度级作为状态系数的量子状态[239];网格量子位;其中几何形状以量子态编码[240];量子晶格,其中彩色像素通过量子位存储在量子系统量子位中[241];量子图像(FRQI)的灵活表示,其中图像是捕捉关于图像中每个点的基本信息的归一化状态(即,它的颜色和位置[237]、[242]、[243]);多通道量子图像(MCQI) [244],它是 FRQI 表示的扩展,包含用于处理颜色信息的 R、G 和 B 通道,以及数字图像的新型增强量子表示(NEQR),它与 QPU 中图像的内部表示一起工作[250]。
量子计算和量子信息是渗透到人类活动各个方面的学科,并出现在计算机科学的各个领域,如信息论、密码学、情感表达和图像处理,因为经典计算机上的低效任务可以通过利用量子计算的能力来克服[3]、[233]、[234]、[235]、[236]。加速某些任务的新方法以及计算机科学和其他几个科学领域之间的跨学科研究吸引了浓厚的科学兴趣。
从技术上讲,量子相关的图像处理工作可以分为三大类[63]。
-
量子辅助数字图像处理(QDIP) :这些应用旨在通过利用量子计算算法的一些有用属性来改善一些众所周知的数字或经典图像处理任务和应用【245】。
-
基于光学的量子成像(OQI) :这些应用通过利用光的量子性质和光信号的内在并行性,专注于量子水平的光学成像和并行信息处理技术[247],[248]。
-
量子图像处理(QIMP) :受即将实现的量子计算硬件的启发,这些应用专注于将经典图像处理任务和应用扩展到量子计算框架[245],[249]。
研究表明,量子计算机可以利用最大纠缠量子位来重建图像,而无需额外的信息[240],从而改善存储和检索。已经研究并建立了量子位阵列中的图像存储,但是检索和重建是量子计算改进的另一个重要方面。使用量子测量来探测顶点量子位之间共享的纠缠可以确定它们的位置。此外,量子系统固有的并行性已用于快速图像搜索[42]和图像重建。FRQI 和真实的 ket 图像模型可以同时处理图像的所有像素,展示了它们内在的并行性。
图像分割也是量子计算中图像处理的一个重要方面。图像分割是将图像划分成单独区域的过程,例如,在图片中查找人脸。当自动检测该区域时,这个概念对于机器学习尤其重要。
在传统的图像分割中,与图像中对象的亮度和空间位置相关联的复杂性使得这项任务具有挑战性。换句话说,图像分割在传统的计算机图像识别中失败,通常是因为缺少形成图像期望的先验信息。Venegas-Andraca 等人[240]进一步扩展了他们的技术,并相对于传统系统改进了图像分割。他们继续使用最大纠缠态来存储对应于图像中物体的点。然后,他们可以检测量子纠缠,通过了解哪些顶点对应于哪些对象来确定哪些像素属于哪些对象。然后,使用检测到的角来构建对应于对象形状的地理形状,然后使用数学形态学算子(用于分析几何结构的技术)来填充由这些形状界定的空间。结果是知道哪些像素属于哪些对象。
在所有领域中,研究最多的是[243]和 NEQR [250]。
FRQI,量子图像 FRQI【243】的柔性表示,试图通过角度对经典图像的颜色进行编码,类似于传统计算机上图像的像素表示。它捕捉了图像中每个点的颜色和位置的基本信息,并用公式将它们集成到一个量子态中。
其中,∣qj⟩= cosθj∣ 0⟩+辛θj∣ 1⟩、∣0⟩和∣1⟩为二维计算基态,∣ j ⟩为 2 2 n 维计算基态,为矢量图像的 FRQI 表示中的两部分,∣qj⟩和∣ * j * ⟩分别对图像中颜色和相应位置的信息进行编码。
FRQI 主要通过 Identity 和 Hadamard 门实现。在量子计算中,计算机通常在准备充分的状态下初始化。因此,需要一个准备过程来将量子计算机从初始状态转换到所需的量子图像状态。
在[244]中提出了一种用于量子图像(MCQI)[243]的多通道表示法,其使用 R、G 和 B 通道来表示关于图像的颜色信息,同时保持其归一化状态。MCQI 提案是通过将编码在 FRQI 图像中的灰度信息扩展到允许设计一些低复杂度颜色信息算子的颜色表示而创建的。MCQI 建议意味着相关算子的计算复杂度与图像大小无关。MCQI 和相关操作似乎还通过在量子电路的设计中隐藏秘密信息,为基于彩色图像的量子水印算法提供了有效的工具[252]。
针对数字图像的新型增强量子表示(NEQR)【250】在 FRQI 和 MCQI 的基础上有所改进。在 FRQI 和 MCQI 表示中,颜色信息通过一个和三个量子位的叠加分别编码。因此,这些量子图像可能需要多次测量来检索信息。新模型或 NEQR 使用量子位序列的基态来存储每个像素的灰度值。因此,在 NEQR 表示中使用代表所有像素的灰度和位置信息的两量子位序列来存储整个图像。
准备 NEQR 图像的计算复杂度显示出二次减少(即, O ( qn )。2 n )),对比 FRQI 和 MCQI 图像[250]。然而,要注意的是,NEQR 表示使用多个量子位来编码量子图像。从它的表示来看,需要( q + 2 n )个量子比特来构建一个灰度范围为 2 q 的 2n×2×2n图像的量子图像模型。然而,用于位置信息的 2 个 n 量子位与用于 FRQI 和 MCQI 表示的相同。NEQR 使用 q 量子位获取颜色信息,而 FRQI 和 MCQI 分别使用一个量子位和三个量子位。研究人员设计了改进的 NEQR (INEQR)和广义 QIR (GQIR),通过将量子图像调整到任意大小,以实现更广泛的应用【253】。
Note
在撰写本书时,一个合作研究团队刚刚更新了 Qiskit 文档网站,其中包含了一些针对 FRQI 和 NEQR 的优秀教程[254]。您可以在 https://qiskit.org/textbook/ch-applications/image-processing-frqi-neqr.html?utm_source=Medium&utm_medium=Social&utm_campaign=Community&utm_content=Textbook-CTA
获得更深入的见解。
张量网络
张量网络最初是为模拟量子物理而设计的,尤其是在低维情况下。它们现在越来越多地应用于解决图像识别等机器学习任务。一些最困难的科学问题,如理解空间和时间的真实性质或开发高温超导体,都涉及到处理量子系统的复杂性。在这些系统中,量子态的数量是指数级的大,否定了蛮力计算作为解决方案的可能途径。为了解决这个问题,使用了张量网络,它是一种数据结构。张量网络由于其灵活性而越来越受到机器学习研究者的关注。
尽管张量网络有明显的吸引力,但传统上,一些困难阻止了它在 ML 社区的广泛使用。
-
用于加速硬件的生产级张量网络库还不能大规模运行张量网络算法。
-
大多数张量网络文献都是面向物理应用的,并造成了一种错误的印象,即理解算法需要量子力学的专业知识。
牢记这一点,Google、周界理论物理研究所( www.perimeterinstitute.ca
)和 X ( https://x.company
)创建了 TensorNetwork 库,并于 2019 年在两个出版物的背面开源[257][258]。
对于感兴趣的人,建议他们在 https://github.com/google/TensorNetwork
访问 TensorNetwork 的 GitHub 网站。如果你对张量网络模拟感兴趣,一个叫做 TensorTrace(www.tensortrace.com
)【259】的工具可以让用户轻松设计和模拟张量网络。如图 9-6 所示。
图 9-6
TensorTrace(来源 www。tensortrace。com
量子金融
量子金融是金融工程与量子场论、经典金融理论、计算机科学和人工智能技术的交叉学科[260]。随着量子计算技术的最新进展和 QML 承诺的量子优势,研究人员已经考虑如何在工业中利用它们。一个主要的重点领域是金融方面(见[260]中的评述)。
由于金融机构在日常工作中执行大量的数值计算任务,量子计算机加速任务的前景太诱人了,不容忽视。其中一项任务就是金融衍生品的定价。 3 因此,衍生品的定价对他们来说是一个重要的问题。
量子金融的另一个重要方面是期权定价,与金融衍生品密切相关[261]。通过利用量子计算机和算法的概率性质,将量子机器学习与股票市场动态结合的努力一直在进行预测和风险分析;已经为此创建了网站;例如,参见 QFFC at http://qffc.uic.edu.hk/
。
诸如芝加哥量子交易所( https://quantum.uchicago.edu/about
)的合作已经形成,以研究和发展这一令人兴奋的跨学科课题。研究工作包括以下大学。
-
芝加哥大学
-
阿贡国家实验室
-
费米国家加速器实验室
-
伊利诺伊大学香槟分校
-
威斯康星大学麦迪逊分校
-
西北大学
多家创业公司发表了使用 QML 算法对股市投资组合建模和金融预测的研究论文,包括 Chicago Quantum(www.chicagoquantum.com
)【262】。瑞穗-DL 金融科技( www.mizuhobank.co.jp
)在日本提出将量子蒙特卡罗模拟的增强应用到金融衍生品的定价中[263]。量子有望成为一个令人兴奋的领域,为金融行业带来无限可能,无论是风险分析、投资组合优化、股价预测还是供应链,不一而足。使用的工具以软件库的形式存在(例如,D-Wave、Qiskit、TensorFlow Quantum、PennyLane、pyQuil 等。)、量子模拟器以及硬件(如果需要的话)。
量子通信
目前有一种萌芽但稳定的努力,要建立一个世界范围的量子网际网路,除了经典资料之外,还可以产生、发布和处理量子资讯。美国、英国、中国、欧盟等都在积极投资相关技术和相关研究。例如,2020 年 2 月,美国能源部(DOE)联合布鲁克海文国家实验室(Brookhaven National Laboratories)举办了关于构建世界范围量子互联网的研讨会,并于 2020 年 7 月发布了他们的报告(www.osti.gov/servlets/purl/1638794
)【264】。
量子通信研究人员正试图利用量子物理定律来连接用户和大规模保护数据。这些定律允许粒子——通常是光子——利用叠加原理沿着光缆传输数据。目前正在研究的技术解决了量子通信的一些最重要的方面,如 Guha 等人的安全私人投标拍卖[271]、多方共享秘密的生成[34]、[266]、分布式量子计算[267]、改进的传感[268]、[269]以及加密数据的量子计算(盲量子计算)[270]。
量子网络(相对于现有的经典网络)的一个根本区别在于,纠缠本质上存在于网络的物理层,其长距离生成是一个基本的网络功能。这与传统网络不同,在传统网络中,共享状态通常只在较高层建立。在这种情况下,必须找到解决方案,以保证网络设备的保真度能够支持纠缠分发和确定性隐形传态,以及能够补偿损耗并允许操作错误纠正的量子中继器方案。
当能够纠错的设备和级联的量子中继器可用时,量子通信网络的发展就到了最后一步。量子纠错(QEC)一直是量子计算通信领域的一个主要挑战。世界范围内的研究和行业机构正在广泛合作,努力应对 QEC 的挑战。一个重点领域是使用机器学习来优化近期量子系统中的误差;例如,见 Nautrup 等人[284]和 Colomer 等人[285]。
一个长期的挑战是超导量子计算机的联网。迄今为止,典型的方法是通过在发射器处转换成光学频率并在接收器处转换成微波频率来级联换能器。然而,小的微波-光耦合和增加的噪声已经被证明是难以克服的障碍。Krastanov 等人在 2020 年提出了一种绕过这一挑战的方法[276],其中他们通过预示一个检测到的光子的端到端纠缠和隐形传态来采用光学联网。该方案将低光-微波耦合效率吸收到预示步骤中,打破了速率-保真度的权衡,简化了量子网络中超导和其他物理设备之间的纠缠产生。
量子通信网络的一些最重要的方面是资源管理、可见性、测试网络的模拟和分析。与此相关,2020 年发表了一篇关于评估量子网络性能的最先进工具的伟大综述[277],重点关注信息论基准、分析工具和模拟。
没有安全协议的通信网络是不完整的。已经提出了某些安全解决方案,例如 QKD 协议、纠缠和基于隐形传态的安全,并且目前正在研究中。然而,在光学平台上实现这些协议以应对通信挑战,例如物理量子位噪声、距离相关的相干性、保真度、记忆和(距离挑战缓解)中继器的密钥再生[282]等等。2020 年 7 月在布鲁克海文国家实验室举行的美国能源部(DOE)量子互联网蓝图研讨会[264]的一些成员建议,在不久的将来,通过利用软件定义的网络 (SDN ) [281],绕过量子网络的内存要求。
在量子系统研究社区解决量子位噪声、内存和资源分配挑战的几种不同方法中,机器学习是最受欢迎的方法之一。随着时间、研究、资金和精力投入到持续的努力中。通过机器学习和物理之间的联盟,未来有望实现前所未有的技术优势。
摘要
机器学习方法已经有效地用于各种量子信息处理问题,包括量子计量、哈密顿量估计、量子信号处理、使用量子行走算法的量子位映射、量子控制问题以及许多其他问题。包括量子计算机在内的先进量子设备的构建,使用了量子机器学习和人工智能技术。自动化机器可以控制复杂的过程,例如量子计算中使用的一系列简单门的执行。
可靠地训练经典计算模型所需的数据量不断增长,并达到普通计算设备能够处理的极限。在这种情况下,量子计算可以帮助用大量数据进行持续训练。量子机器学习旨在设计比经典算法更有效的学习算法。经典的机器学习是在数据中寻找模式,并使用这些模式来预测未来的事件。另一方面,量子系统产生经典系统无法产生的非典型模式,从而假设量子计算机可以在机器学习任务上超越经典计算机。
当我们更深入地探索二十一世纪时,一个激动人心的未来正等待着我们,它将在金融、科学、生物、化学、物理以及很有可能在我们今天想都想不到的应用领域取得前所未有的进步。
Footnotes 1
通过查看其邻接矩阵的特征值来分析图被称为代数图论或谱图论。
2
比如 en。维基百科。org/ wiki/ Hamiltonian_(量子力学)
3
金融衍生工具,或简称为衍生工具,是一种在某些固定时间参考基础资产价格确定收益的合同。