前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >下(应用篇)| 推荐几款较流行的量子算法

下(应用篇)| 推荐几款较流行的量子算法

作者头像
量子发烧友
发布于 2023-02-24 07:26:06
发布于 2023-02-24 07:26:06
2.2K00
代码可运行
举报
文章被收录于专栏:量子发烧友量子发烧友
运行总次数:0
代码可运行

1. 典型的量子算法

量子算法是量子计算机的必要软件支撑,同时量子算法的研究也是推动量子计算发展的强大动力。以下将对各个发展阶段的典型量子算法进行比较分析。

其中,探索阶段选择的量子算法是Simon算法;质变阶段选择的量子算法有两个,分别是Shor算法和Grover算法(量子算法中最著名的算法);繁荣发展阶段选择的量子算法是VQE变分量子特征值求解算法;AI探索阶段选择的量子算法是Google提出的Tensorflow Quantum(TFQ)框架。

1.1 Shor算法

Simon算法是由丹尼尔·西蒙20年前提出,认为这种算法能够挖掘量子计算机的加速潜力。Simon算法的目的,是为了解决量子黑箱问题,即将执行计算任务的一段程序或者一个公式看作黑箱,看黑箱是否对每一个可能的输入给出一个唯一的输出。

重要性:实现了从指数级复杂度到多项式加速。

主要应用:主要应用于硬件或软件条件受限(例如:芯片面积要求小、微处理器、低功耗等),同时对安全有一定需求的低端设备。

为了适应不同的场合,Simon提供了不同的方案

图:Simon密码族

图:Simon轮函数结构图

其中, block size : 明文块大小,比特位;

    key size : 初始密钥大小,比特位;

    word size : "字"大小,比特位;

    key words : 初始密钥包含"字"的个数;

    const seq : 计算轮密钥应该使用的z的值;

    rounds : 加解密的轮数。

以下是Simon算法流程:(以加解密轮函数和密钥编排算法为例)

轮加密

每一轮的操作如上图“Simon轮函数结构图”。明文被分成两个"字",每个"字"的二进制位数都为n(即word size),x_(i+1)和x_i分别表示高位部分和低位部分(个人认为,这个没有特别要求,x_(i+1)也可以表示低位、x_i表示高位部分,只要加解密按照同样的顺序即可。为了叙述统一,本文按照x_(i+1)表示高位、x_i表示低位)。

每轮的加密主要涉及到3种操作,分别是异或、按位与和循环左移(如果j是负数则表示循环右移)。每轮加解密的过程用公式表示,其中x对应x_(i+1)、y对应x_i、k为轮密钥。

Simon运算符号:

Simon轮加解密公式:

在C++实现中,按位异或和与都有直接的操作符,对于循环移位可以按照如下方法实现。将x循环左移i(i>=0)位,假设x对应的二进制位数为n,则可以表示为: (x<>(n-i))。当然,x应该是无符号的数,不然会出错。

代码语言:javascript
代码运行次数:0
运行
复制
 /   
   加密后的低32位是明文的高32/    
 tempCipherLower  = plainText[];    
 tempCipherHigher = plainText[] ^ keys[i] ^    
                 ( ((plainText[]<<)|(plainText[]>>(SIMON_WORD_SIZE-))) & ((plainText[]<<)|(plainText[]>>(SIMON_WORD_SIZE-))) ) ^    
                 ((plainText[]<<)|(plainText[]>>(SIMON_WORD_SIZE-)));    
 /   
   重新将加密的结果复制到plainText中   
  /    
 plainText[]     = tempCipherHigher;    
 plainText[]     = tempCipherLower;

密钥编排

密钥编排算法如下,其中m表示的是原始密钥中"字"的个数。

c为一个常数,它的二进制位数为n,最低两位为0,其余高位为1。

z是一个常数数组,值见下图,在每种情况下z的取值都是固定的,每轮加解密时只取一个比特位参与运算。

ki、ki+1、ki+2等都是轮密钥。

I表示不进行移位。

C++代码实现如下(只包含block size为64,key size为96和128的两种情况):

代码语言:javascript
代码运行次数:0
运行
复制
  / 
   Simon:计算密钥,字大小为32
   inputKey:初始的密钥 
   keys:计算后得到的每轮密钥 
  /   
 void setSimonKeys32 ( unsigned int * inputKey, unsigned int * keys ) {   
   
     / 
       算法中的常数c,大小为2^n - 4,其中n是字的长度,即SIMON_WORD_SIZE 
       转化为二进制,即最低两位为0,其它位全为1 
      /   
     unsigned int c = 0xfffffffc;   
   
     int i;   
     ; i < SIMON_KEY_WORDS; i++ )  {   
         keys[i] = inputKey[i];   
     }   
   
     /*
       求解后面轮的密钥 
       先求其它的异或,最后求Zji,如果为1则对最低位进行修改,否则不变 
      /   
      ) {   
         ; i < SIMON_ROUNDS-SIMON_KEY_WORDS; i++ ) {   
             keys[i+SIMON_KEY_WORDS] = c ^ keys[i] ^   
                             ((keys[i+]>>) | (keys[i+]<<(SIMON_WORD_SIZE-))) ^   
                             ((keys[i+]>>) | (keys[i+]<<(SIMON_WORD_SIZE-)));   
             // SIMON_WORD_SIZE为32时,无论SIMON_KEY_WORDS为3还是4,周期都是62   
             ] ==  ) {   
                 keys[i+SIMON_KEY_WORDS] ^=  0x1;   
             }   
         }   
     }  ) {   
         // int cycle = (SIMON_SEQUENCE_NUMBER == 0 || SIMON_SEQUENCE_NUMBER == 1)?31:62;   
         unsigned int temp = 0x00000000;   
         ; i < SIMON_ROUNDS-SIMON_KEY_WORDS; i++ ) {   
             temp = ((keys[i+]>>) | (keys[i+]<<(SIMON_WORD_SIZE-))) ^ keys[i+];   
             keys[i+SIMON_KEY_WORDS] = c ^ keys[i] ^ temp ^ ((temp>>) | (temp<<(SIMON_WORD_SIZE-)));   
             ] ==  ) {   
                 keys[i+SIMON_KEY_WORDS] ^=  0x00000001;   
             }   
         }   
     }   
    
 }  

参考:

[1] Beaulieu R, Shors D, Smith J, et al. The SIMON and SPECK Families of Lightweight Block Ciphers[J]. IACR Cryptology ePrint Archive, 2013, 2013: 404.

[2] bbsmax网站《Simon简介》,原文链接:https://www.bbsmax.com/A/pRdBoA69zn/

1.2 Shor算法

shor算法也称秀尔算法,以数学家彼得·秀尔命名,是一个在1994年提出的一种大数质因子分解的量子多项式算法。Shor量子计算将NP问题变为了P问题,和用数论中的一些定理将大数因子分解转化为求某个函数的周期,由于在量子环境下可以提高效率实现量子傅立叶变换,从而可以对大数质因子进行化简。

在一个量子计算机上面,要分解整数N,shor算法的运作需要多项式时间,质因数分解问题可以使用量子计算机以多项式时间解出,因此在复杂度类BQP里面,比起传统已知最快的因数分解算法(普通数域筛选法)还要快了一个指数的差异。

重要性:Shor算法利用了量子力学的多种特性显示出在RSA加密技术破解方面的优势。它代表使用量子计算机的话可以用来破解已被广泛使用的公开密钥加密方法(RSA加密算法)。

主要应用: 在量子密码学、量子通信方面、shor算法后续研究、模拟实现的参考具有一定辅助作用。

大数质因子分解问题为:N为已知大奇数,N = pq,求 p和q。

(1)随机抽取正整数y,y < N,且与N互质,即gcd(y,N)=1 。

(2)定义f(x)= y^xmod < N,可看出f(x)是一个周期函数,若周期是r,则:

故:

(3)求p和q。

用辗转相除法求y^(r/2)+1 和N的最大公约数,设为p。

上面各步中的主要计算是辗转相除、计算f(x)和求f(x)的周期。辗转相除的时间复杂度为O(n^2)。计算f(x)时间复杂度为O(n^2 (lgn)(lglgn))。求f(x)的周期需要进行傅立叶变换,量子傅立叶变换的时间复杂度为O(lgn),所以,shor量子算法的时间复杂度为O(n^2 (lgn)(lglgn))。

Shor算法的关键之处是利用量子傅立叶变换求f(x)的周期。

量子傅立叶变换QFT(Quantum Fourier Transform)的定义:

可以看出QFT是么正变换,QFT可由两种量子门实现,所用的门的数量为m(m+1)/2。这两种门是H门,另一种是2个量子位的相移门,其算符如下:

S_jk是幺正矩阵。

参考:彭卫丰,江南大学信息学院,孙力,江南大学网络教育学院,Shor量子算法的优化及应用研究。

1.3 Grover算法

Grover算法(Quantum Search Algorithm)是量子计算领域的主要算法之一,由Grover于1996年提出的平方根加速的随机数据库量子搜索算法,旨在利用量子计算机进行比经典计算机更快的数据搜索。在数据库足够混乱且没有具体的数据结构限定的条件下,Grover算法可以快速解决从N个未分类的客体中寻找出某个特定个体的问题。除搜索时间远短于经典计算外,其强大之处还在于Grover算法的公式可适用于很多问题,比如:密码学、矩阵和图形问题、优化以及量子机器学习等。

Grover算法搜寻目标对象的逻辑大致为在无序的数据集合中寻找X,首先制备全部量子态的叠加态,然后循环进行操作使得目标态的符号反向(Oracle算符)且态的符号也反向(Grover算符);在执行次操作后,量子态被旋转至目标态;最后测量所得结果概率发现X出现的概率趋近于1,此时即可通过Grover算法找到目标X。一般地,如果想要在N个信息找到对应信息,进行4/pie*√N次操作,进行测量得到的概率趋于1。因此,Grover算法进行无序搜索主要步骤有三个:制备量子态、G迭代、测量。

重要性:Grover算法的重要性,一是因为Grover算法解决的无序数据库搜索问题就是一个很重要的问题;二是因为,Grover量子算法的提出,和Shor质因子分解算法提出一样,给了研究者们用量子算法解决经典算法无法有效解决的问题的希望,极大提高了人们对于量子算法研究的热情;三是,从Grover算法衍生出了一系列利用了幅度放大思想的算法,是现今量子算法研究中的一个重要部分。

Grover算法步骤

Grover算法总体分为三大步骤:制备量子态、标记目标进行相位翻转并放大概率振幅、测量。Grover算法利用量子特性将目标值与其余值进行区分,采用验证是否符合条件的方式而不是线性查找的方式逼近正确答案。

复杂度:Grover搜索算法需要O(√N)次查询,其中N表示搜索空间元素的个数,相较于经典搜索 O(N) 具有多项式量级的加速。

量子线路

为了便于分析,定义两个量子态

“Good”态

“Bad”态

其中 t就是满足x_i=1的个数。

算法步骤如下:

1.设置初始量子态

2.令ε=t/N,应用k=O(1/ε)次如下变换:

3.测量寄存器的状态,并检查测量结果i是否是解。

其中,算法第2步理解如下:

量子态从状态∣U⟩出发,通过不断的“反射+反射”,不断向目标态∣G⟩靠近。而目标态∣G⟩就是满足∣i⟩的叠加态。

QuTrunk Grover算法部分代码示例

QuTrunk基于python提供量子编程API,对量子编程涉及到的基本概念做了代码层面的抽象封装和实现。QuTrunk通过接入启科自主研发的量子计算后端设备QuBox可实现量子算法运行。以下为QuTrunk实现Grover算法部分代码示例:

步骤1:首先在QuIDE中导入随机数模块和QuTrunk中的部分模块

代码语言:javascript
代码运行次数:0
运行
复制
 import math   
 import random   
    
 from numpy import pi   
    
 from QuTrunk.core.circuit import QCircuit, InitState   
 from QuTrunk.core.gates import H, X, C, Z   
 from QuTrunk.core.calculator import Calculator   9. from QuTrunk.core.counter import Counter  

步骤2: 调用Oracle门和Diffuser函数,将量子态进行相位翻转和放大(部分代码省略)

代码语言:javascript
代码运行次数:0
运行
复制
def apply_oracle(qr, num_qubits, sol_elem)...   
   
 def apply_diffuser(qr, num_qubits)...  

步骤3:运行Grover算法,不断进行G迭代直至搜索出目标值

代码语言:javascript
代码运行次数:0
运行
复制
def run_grover():   
 num_qubits = 15   
 num_elems = 2 ** num_qubits   
 num_reps = math.ceil(pi / 4 * math.sqrt(num_elems))   
 print("num_qubits:", num_qubits, "num_elems:", num_elems, "num_reps:", num_reps)

步骤4:输出运行结果

从结果中可观察到搜索的量子比特数为15Qubit、量子门数为11726个、总的运行时间为10.8659s(其中QuBox运行时间为10.6309s,QuTrunk运行时间仅为0.2350s)。

代码语言:javascript
代码运行次数:0
运行
复制
 Counter(quit=15)   
     qubits = 15   
     quantum_gates = 11726   
     total_time = 10.865945100784302   
     qubox_time = 10.630940914154053   
     qutrunk_time = 0.23500418663024902  

以上Grover算法中生成随机数目标为17560,最终搜索结果概率峰值为0.999986接近于1。在搜索过程中,当此概率出现峰值且第一次下降时即停止搜索,认为已经找到目标值即为17560。

1.4 VQE变分量子特征值求解算法

变分量子本征求解器(variational quantum eigensolver, VQE)指利用经典优化器训练一个含参量子线路,用于求解矩阵本征值和本征矢的算法。VQE 是第一种被提出来的 VQA,目标是寻找一个哈密顿量H的基态和低激发态。下文以基态为例介绍。

对于基态,损失函数就是能量的期望

在经典计算机上我们可以将|ψ(θ)〉表示出来(一个 quantum circuit 直接对应一个 tensor network),然后测出能量,但是它消耗的存储容量随着需要计算的物理系统大小指数增长。

而对于一台量子计算机,我们只需要重复地将|ψ(θ)〉制备出来,测量取平均得到哈密顿量中相加的每一项的期望值。后者消耗的计算资源随需要计算的物理系统大小呈多项式增长,于此体现出相较于纯经典算法的优越性。

以求基态为例,VQE 的整体流程如下:

1.选定一个含参的试探波函数(trial wave function)以及初始参数θ_0;

2.利用量子计算机测量出|ψ(θ)〉的能量期望C(θ)= <ψ(θ)|H|ψ(θ)〉;

3.为不断降低能量,利用经典优化器更新参数θ_0 〖→θ〗_1,返回第 2 步,直至收敛。

以下将通过量桨的量子化学工具包(基于 psi4 和 openfermion)为例,寻找氢分子H2基态能量。

构造电子哈密顿量

代码语言:javascript
代码运行次数:0
运行
复制
  import paddle   
 import paddle_quantum.qchem as qchem   
 from paddle_quantum.loss import ExpecVal   
 from paddle_quantum import Hamiltonian   
 from paddle_quantum.state import zero_state, State   
 from paddle_quantum.ansatz import Circuit   
 from paddle_quantum.linalg import dagger   
 from paddle_quantum import Backend   
    
 import os   
 import matplotlib.pyplot as plt   
    
 import numpy   
 from numpy import pi as PI   
 from numpy import savez, zeros   
    
 # 无视警告   
 import warnings   
 warnings.filterwarnings("ignore")  

通过量桨的量子化学工具包将分子的哈密顿量提取出来并储存为 paddle quantum 的 Hamiltonian 类

代码语言:javascript
代码运行次数:0
运行
复制
 geo = qchem.geometry(structure=[['H', [-0., 0., 0.0]], ['H', [-0., 0., 0.74]]])   
 # geo = qchem.geometry(file='h2.xyz')   
    
 # 将分子信息存储在 molecule 里,包括单体积分(one-body integrations),双体积分(two-body integrations),分子的哈密顿量等   
 molecule = qchem.get_molecular_data(   
     geometry=geo,   
     basis='sto-3g',   
     charge=0,   
     multiplicity=1,   
     method="fci",   
     if_save=True,   
     if_print=True   
 )   
 # 提取哈密顿量   
 molecular_hamiltonian = qchem.spin_hamiltonian(molecule=molecule,   
                                                filename=None,   
                                                multiplicity=1,    
                                                mapping_method='jordan_wigner',)   
 # 打印结果   
 print("\nThe generated h2 Hamiltonian is \n", molecular_hamiltonian)  

设计量子神经网络QNN(也可以理解为参数化量子电路)来准备试探波函数 |Ψ(θ)⟩。

根据上图中的电路设计,通过 Paddle Quantum 的 Circuit 类和内置的 real_entangled_layer() 电路模板来高效搭建量子神经网络。

代码语言:javascript
代码运行次数:0
运行
复制
  def U_theta(num_qubits: int, depth: int) -> Circuit:   
     """  
     Quantum Neural Network  
     """   
        
     # 按照量子比特数量/网络宽度初始化量子神经网络   
     cir = Circuit(num_qubits)   
        
     # 内置的 {R_y + CNOT} 电路模板   
     cir.real_entangled_layer(depth = depth)   
        
     # 铺上最后一列 R_y 旋转门   
     cir.ry()   
            
     return cir  

进一步定义训练参数、模型和损失函数。

代码语言:javascript
代码运行次数:0
运行
复制
  class StateNet(paddle.nn.Layer):   
     """ 
     Construct the model net 
     """   
   
     def __init__(self, num_qubits: int, depth: int):   
         super(StateNet, self).__init__()   
           
         self.depth = depth   
         self.num_qubits = num_qubits   
         self.cir = U_theta(self.num_qubits, self.depth)   
           
     # 定义损失函数和前向传播机制   
     def forward(self):   
           
         # 运行电路   
         state = self.cir(init_state)   
         # 计算损失函数   
         loss = loss_func(state)        
    
         return loss, self.cir

进行一些训练的参数设置,主要是学习速率(LR, learning rate)、迭代次数(ITR, iteration)和量子神经网络计算模块的深度(D, Depth)。

代码语言:javascript
代码运行次数:0
运行
复制
 ITR = 80  # 设置训练的总迭代次数   
 LR = 0.4   # 设置学习速率   
 D = 2      # 设置量子神经网络中重复计算模块的深度 Depth   
 N = molecular_hamiltonian.n_qubits # 设置参与计算的量子比特数

将数据转化为 Paddle 中的张量,进而进行量子神经网络的训练。

代码语言:javascript
代码运行次数:0
运行
复制
 # 确定网络的参数维度   
 net = StateNet(N, D)   
   
 # 一般来说,利用Adam优化器来获得相对好的收敛,   
 opt = paddle.optimizer.Adam(learning_rate=LR, parameters=net.parameters())   
   
 # 定义初始态   
 init_state = zero_state(N)   
   
 # 定义损失函数   
 loss_func = ExpecVal(molecular_hamiltonian)   
   
 # 记录优化结果   
 summary_iter, summary_loss = [], []   
   
 # 优化循环   
 for itr in range(1, ITR + 1):   
   
     # 前向传播计算损失函数   
     loss, cir = net()   
   
     # 在动态图机制下,反向传播极小化损失函数   
     loss.backward()   
     opt.minimize(loss)   
     opt.clear_grad()   
   
     # 更新优化结果   
     summary_loss.append(loss.numpy())   
     summary_iter.append(itr)   
   
     # 打印结果   
     if itr % 20 == 0:   
         print("iter:", itr, "loss:", "%.4f" % loss.numpy())   
         print("iter:", itr, "Ground state energy:", "%.4f Ha"   
                                             % loss.numpy())   
     if itr == ITR:   
         print("\n训练后的电路:")   
         print(cir)   
   
 # 储存训练结果到 output 文件夹   
 os.makedirs("output", exist_ok=True)   
 savez("./output/summary_data", iter = summary_iter,   
                                energy=summary_loss)

通过 VQE 得到的基态能量的估计值

代码语言:javascript
代码运行次数:0
运行
复制
result = numpy.load('./output/summary_data.npz')  
   
 eig_val, eig_state = numpy.linalg.eig(   
                      molecular_hamiltonian.construct_h_matrix())   
 min_eig_H = numpy.min(eig_val.real)   
 min_loss = numpy.ones([len(result['iter'])]) * min_eig_H   
   
 plt.figure(1)   
 func1, = plt.plot(result['iter'], result['energy'],   
                   alpha=0.7, marker='', linestyle="-", color='r')   
 func_min, = plt.plot(result['iter'], min_loss,   
                   alpha=0.7, marker='', linestyle=":", color='b')   
 plt.xlabel('Number of iteration')   
 plt.ylabel('Energy (Ha)')   
   
 plt.legend(handles=[   
     func1,   
     func_min   
 ],   
     labels=[   
         r'$\left\langle {\psi \left( {\theta } \right)} '   
         r'\right|H\left| {\psi \left( {\theta } \right)} \right\rangle $',   
         'Ground-state energy',   
     ], loc='best')   
 plt.text(-15.5, -1.145, f'{min_eig_H:.5f}', fontsize=10, color='b')   
 #plt.savefig("vqe.png", bbox_inches='tight', dpi=300)   
 plt.show()  

1.5 Tensorflow Quantum(TFQ)框架

TensorFlow Quantum (TFQ) 是一个用于混合量子经典机器学习的 Python 框架,主要为解决NISQ时代的量子机器学习问题而设计。它将量子计算基元(如构建量子电路)引入 TensorFlow 生态系统。使用 TensorFlow 构建的模型和运算使用这些基元来创建功能强大的量子经典混合系统。其允许量子算法研究员和 ML 应用研究员在 TensorFlow 内充分利用 Google 的量子计算框架。

TensorFlow Quantum 实现了将 TensorFlow 与量子计算硬件集成所需的组件。为此,TensorFlow Quantum 引入了两个数据类型基元:

(1)量子电路 - 表示 TensorFlow 中 Cirq 定义的量子电路。创建大小不同的电路批次,类似于不同的实值数据点的批次。

(2)Pauli 和 - 表示 Cirq 中定义的 Pauli 算子张量积的线性组合。像电路一样,创建大小不同的算子批次。

利用这些基元来表示量子电路,TensorFlow Quantum 提供以下运算:

(1)从电路批次的输出分布中采样。

(2)基于电路批次计算 Pauli 和批次的期望值。TFQ 实现了与反向传播兼容的梯度计算。

(3)模拟电路和状态批次。虽然在现实世界中直接检查整个量子电路的所有量子态振幅的效率极低,但状态模拟可以帮助研究员了解量子电路如何将状态映射到接近精确的精度水平。

以上是TensorFlow Quantum 的软件堆栈图,它展示了 TensorFlow 和 Cirq 之间的交互。

TensorFlow Quantum 在 TensorFlow 的基础上增加了处理量子数据的能力。这些量子数据包括量子线路和量子算符。

TensorFlow Quantum 的核心原则是与 TensorFlow,特别是 Keras 模型和优化器的集成,因此,TF Keras Models 横跨了堆栈图的左右。

第三层包含 TensorFlow Quantum 的量子层和微分器,当和经典张量流连接时,可以实现混合量子经典的自动微分。

Ops 层实现了张量流图的实例化。

量子线路可以通过调用 qsim 或 Cirq 模拟运行,或最终在 QPU 上运行。

其操作流程如下:

(1)制备量子数据集:一般而言,量子数据集应当由一个黑盒产生。然而,由于当前的量子计算机无法从外部源导入量子数据,用户需要构造生成数据的量子线路。

(2)量子模型估计:参数化量子模型通过量子计算,来提取量子数据集中隐藏在量子子空间或子系统中的信息。

(3)采样或求平均值:量子态的测量从经典随机变量中以样本的形式提取经典信息。这个随机变量的值的分布通常取决于量子态本身和被测的可观测值。许多变分算法依赖于测量值的平均值,TFQ提供了对前两个步骤的多个运行结果求平均值的方法。

(4)经典模型估计:经典信息被提取出来后,可以进一步做经典后处理,以提取测量期望值之间的关联信息。这一过程可以通过经典深度神经网络实现。

(5)代价函数 (cost function) 估计:得到经典后处理结果后,需要对代价函数进行估计。例如估计监督分类的准确度。

(6)梯度估计和参数更新:完成代价函数的估计之后,整个模型中的自由参数应当向代价降低的方向更新。比较常见的是梯度下降更新。

以下为如何使用 TensorFlow Quantum 构建一个混合的量子经典神经网络。

准备工作:

设置

代码语言:javascript
代码运行次数:0
运行
复制
pip install tensorflow==2.7.0

安装TensorFlow Quantum

代码语言:javascript
代码运行次数:0
运行
复制
pip install tensorflow-quantum

导入 TensorFlow 和模块依赖项

代码语言:javascript
代码运行次数:0
运行
复制
 import tensorflow as tf   
 import tensorflow_quantum as tfq   
   
 import cirq   
 import sympy   
 import numpy as np   
   
 # visualization tools   
 %matplotlib inline   
 import matplotlib.pyplot as plt   
 from cirq.contrib.svg 
 import SVGCircuit

使用 TensorFlow Quantum 构建一个混合的量子经典神经网络。以下为其架构图:

架构分为 3 个部分:

(1)输入电路或数据点电路:前三个大门。

(2)控制电路:其他三个大门。

(3)控制器:设置受控电路参数的经典神经网络。

操作流程:

步骤1:定义一个可学习的单比特旋转

代码语言:javascript
代码运行次数:0
运行
复制
 # Parameters that the classical NN will feed values into.   
 control_params = sympy.symbols('theta_1 theta_2 theta_3')   
   
 # Create the parameterized circuit.   
 qubit = cirq.GridQubit(0, 0)   
 model_circuit = cirq.Circuit(   
     cirq.rz(control_params[0])(qubit),   
     cirq.ry(control_params[1])(qubit),   
     cirq.rx(control_params[2])(qubit))   
   
 SVGCircuit(model_circuit)  

步骤2: 定义控制器网络

代码语言:javascript
代码运行次数:0
运行
复制
 # The classical neural network layers.   
 controller = tf.keras.Sequential([   
     tf.keras.layers.Dense(10, activation='elu'),   
     tf.keras.layers.Dense(3)   
 ])  
代码语言:javascript
代码运行次数:0
运行
复制
controller(tf.constant([[0.0],[1.0]])).numpy()

步骤3: 将控制器连接到受控电路

代码语言:javascript
代码运行次数:0
运行
复制
 # This input is the simulated miscalibration that the model will learn to correct.   
 circuits_input = tf.keras.Input(shape=(),   
                                 # The circuit-tensor has dtype `tf.string`   
                                 dtype=tf.string,   
                                 name='circuits_input')   
   
 # Commands will be either `0` or `1`, specifying the state to set the qubit to.   
 commands_input = tf.keras.Input(shape=(1,),   
                                 dtype=tf.dtypes.float32,   
                                 name='commands_input')

步骤4: 对这些输入应用操作,以定义计算

代码语言:javascript
代码运行次数:0
运行
复制
 dense_2 = controller(commands_input)   
   
 # TFQ layer for classically controlled circuits.   
 expectation_layer = tfq.layers.ControlledPQC(model_circuit,   
                                              # Observe Z   
                                              operators = cirq.Z(qubit))   
 expectation = expectation_layer([circuits_input, dense_2])

步骤5: 将此计算打包为tf.keras.Model

代码语言:javascript
代码运行次数:0
运行
复制
 # The full Keras model is built from our layers.   
 model = tf.keras.Model(inputs=[circuits_input, commands_input],   
                        outputs=expectation)  

步骤6: 将模型图与架构图进行比较以验证正确性。

代码语言:javascript
代码运行次数:0
运行
复制
tf.keras.utils.plot_model(model, show_shapes=True, dpi=70)

步骤7:该模型试图输出正确的正确测量值对于每个命令。

代码语言:javascript
代码运行次数:0
运行
复制
 # The command input values to the classical NN.   
 commands = np.array([[0], [1]], dtype=np.float32)   
   
 # The desired Z expectation value at output of quantum circuit.   
 expected_outputs = np.array([[1], [-1]], dtype=np.float32)  

步骤8: 输入电路定义模型将学习纠正的随机错误校准

代码语言:javascript
代码运行次数:0
运行
复制
random_rotations = np.random.uniform(0, 2 * np.pi, 3)   
 noisy_preparation = cirq.Circuit(   
   cirq.rx(random_rotations[0])(qubit),   
   cirq.ry(random_rotations[1])(qubit),   
   cirq.rz(random_rotations[2])(qubit)   
 )   
 datapoint_circuits = tfq.convert_to_tensor([   
   noisy_preparation   
 ] * 2)  # Make two copied of this circuit  

步骤9:测试运行tfq模型

代码语言:javascript
代码运行次数:0
运行
复制
model([datapoint_circuits, commands]).numpy()

步骤10: 运行一个标准训练过程,将这些值调整为expected_outputs

代码语言:javascript
代码运行次数:0
运行
复制
optimizer = tf.keras.optimizers.Adam(learning_rate=0.05)   
 loss = tf.keras.losses.MeanSquaredError()   
 model.compile(optimizer=optimizer, loss=loss)   4. history = model.fit(x=[datapoint_circuits, commands],   
                     y=expected_outputs,   
                     epochs=30,   
                     verbose=0)  
代码语言:javascript
代码运行次数:0
运行
复制
 plt.plot(history.history['loss'])   
 plt.title("Learning to Control a Qubit")   
 plt.xlabel("Iterations")   
 plt.ylabel("Error in Control")   
 plt.show()  

步骤11: 使用经过训练的模型来纠正量子比特校准错误。

代码语言:javascript
代码运行次数:0
运行
复制
def check_error(command_values, desired_values):   
 """Based on the value in `command_value` see how well you could prepare 
 the full circuit to have `desired_value` when taking expectation w.r.t. Z."""   
   params_to_prepare_output = controller(command_values).numpy()   
   full_circuit = noisy_preparation + model_circuit  
    
   # Test how well you can prepare a state to get expectation the expectation   
   # value in `desired_values`   
   for index in [0, 1]:   
     state = cirq_simulator.simulate(   
         full_circuit,   
         {s:v for (s,v) in zip(control_params, params_to_prepare_output[index])}   
     ).final_state_vector   
     expt = cirq.Z(qubit).expectation_from_state_vector(state, {qubit: 0}).real   
     print(f'For a desired output (expectation) of {desired_values[index]} with'   
           f' noisy preparation, the controller\nnetwork found the following '   
           f'values for theta: {params_to_prepare_output[index]}\nWhich gives an'   
           f' actual expectation of: {expt}\n')   
    
    
 check_error(commands, expected_outputs)  
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 量子发烧友 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
利用 AI 解放双手:把“贾维斯”带进现实 | 开源专题 No.64
小柒
2024/04/01
3370
利用 AI 解放双手:把“贾维斯”带进现实 | 开源专题 No.64
让照片开口说话!基于音频生成动画 | 开源日报 No.253
SadTalker 是一个基于音频驱动的单幅图像对话头像动画生成项目。它可以将单幅人像图像与音频结合,生成逼真的视频对话头像。该项目的主要功能和核心优势包括:
小柒
2024/05/10
2460
让照片开口说话!基于音频生成动画 | 开源日报 No.253
精准视频切片与 AI 智能剪辑工具 | 开源日报 No.311
FunClip 是一个开源、精准、方便的视频切片工具,集成了大语言模型 AI 智能剪辑功能。 该项目的主要功能、关键特性和核心优势包括:
小柒
2024/07/31
6100
精准视频切片与 AI 智能剪辑工具 | 开源日报 No.311
Cloudflare CDN 速度测试:找到最快的 IP 段 | 开源日报 No.257
CloudflareSpeedTest 是一个用于测试 Cloudflare CDN 延迟和速度的工具。 该项目的主要功能、关键特性、核心优势包括:
小柒
2024/05/10
7240
Cloudflare CDN 速度测试:找到最快的 IP 段 | 开源日报 No.257
WeChatMsg: 导出微信聊天记录 | 开源日报 No.108
llamafile 是一个开源项目,旨在通过将 lama.cpp 与 Cosmopolitan Libc 结合成一个框架,将 LLM (Large Language Models) 的复杂性折叠到单个文件可执行程序中,并使其能够在大多数计算机上本地运行而无需安装。该项目的主要功能和核心优势包括:
小柒
2023/12/12
1.3K0
WeChatMsg: 导出微信聊天记录 | 开源日报 No.108
daisyUI:最受欢迎的 Tailwind CSS 组件库 | 开源日报 No.181
daisyUI 是 Tailwind CSS 的最受欢迎、免费且开源的组件库,主要功能包括提供各种组件和工具来简化使用 Tailwind CSS 进行网页设计。其核心优势和关键特性包括:
小柒
2024/02/26
1.3K0
daisyUI:最受欢迎的 Tailwind CSS 组件库 | 开源日报 No.181
比 md5 更快更安全:全新的哈希函数 | 开源日报 No.294
BLAKE3 是 BLAKE3 密码哈希函数的官方 Rust 和 C 实现。具有以下特点和优势:
小柒
2024/07/10
3240
比 md5 更快更安全:全新的哈希函数 | 开源日报 No.294
使用大型语言模型的指南: 提高效率及安全性的技巧和策略 | 开源日报 0913
Prompt Engineering Guide,提供了与大型语言模型(LLM)相关的技巧和窍门。该指南基于Brex公司在生产用例中研究和创建LLM提示时所学到的经验教训,并涵盖了有关使用和构建程序化系统以及安全性方面的策略、准则和建议。它解释了什么是大型语言模型,如何进行预测并生成文本序列,并介绍了一些修剪方法来改变其行为和性能。
小柒
2023/09/14
2900
使用大型语言模型的指南: 提高效率及安全性的技巧和策略 | 开源日报 0913
Langchain-Chatchat:离线运行的大模型知识库 | 开源日报 No.182
基于 ChatGLM 等大语言模型与 Langchain 等应用框架实现的开源、可离线部署的检索增强生成 (RAG) 大模型知识库项目。该项目是一个可以实现完全本地化推理的知识库增强方案,重点解决数据安全保护和私域化部署的企业痛点,并支持市面上主流的本地大预言模型和 Embedding 模型,无需付费使用。其核心优势包括:
小柒
2024/02/26
1K0
Langchain-Chatchat:离线运行的大模型知识库 | 开源日报 No.182
C++ 算法宝库:多领域覆盖,注释详细 | 开源日报 No.153
Algorithms-C++ 是一个收集了数学、机器学习、计算机科学和物理等领域的各种算法的开源项目,用 C++ 实现,旨在供教育目的使用。该项目提供了以下特点:
小柒
2024/01/14
3740
C++ 算法宝库:多领域覆盖,注释详细 | 开源日报 No.153
中国领先工业级深度学习框架:支持超大规模训练 | 开源日报 No.304
Paddle 是中国首个独立自主研发的深度学习平台,提供高性能单机、分布式训练和跨平台部署。
小柒
2024/07/22
2370
中国领先工业级深度学习框架:支持超大规模训练 | 开源日报 No.304
能够解析任何编程语言的开源语法解析树 | 开源日报 No.171
tree-sitter 是一个用于编程工具的增量解析系统。该项目的主要功能、关键特性、核心优势包括:
小柒
2024/01/31
7660
能够解析任何编程语言的开源语法解析树 | 开源日报 No.171
Cypress.io:快速简单可靠的浏览器测试工具 | 开源日报 No.142
Cypress.io 是一个快速、简单和可靠的浏览器测试工具,可以用于任何在浏览器中运行的内容。它支持 Mac、Linux 和 Windows 系统,并提供了安装指南。
小柒
2024/01/03
3560
Cypress.io:快速简单可靠的浏览器测试工具 | 开源日报 No.142
谷歌开源的跨平台高效序列化库:极速访问,内存高效 | 开源日报 No.289
flatbuffers 是一个跨平台的序列化库,旨在实现最大内存效率。它允许您直接访问序列化数据而无需先进行解析/拆包,同时具有很好的向前/向后兼性。以下是 flatbuffers 项目的主要功能、关键特性核心优势:
小柒
2024/07/10
1680
谷歌开源的跨平台高效序列化库:极速访问,内存高效 | 开源日报 No.289
性能与效率比拼:开源大语言模型竞逐 | 开源专题 No.76
ChatGLM3 是智谱 AI 和清华大学 KEG 实验室联合发布的新一代对话预训练模型。其主要功能包括更强大的基础模型、更完整的功能支持以及全面开源序列。具体特点如下:
小柒
2024/05/17
2560
性能与效率比拼:开源大语言模型竞逐 | 开源专题 No.76
金融预测、生成代码、聊天对话:大语言模型的无穷妙用 | 开源专题 No.97
基于 ChatGLM 等大语言模型与 Langchain 等应用框架实现的开源、可离线部署的检索增强生成 (RAG) 大模型知识库项目。该项目是一个可以实现完全本地化推理的知识库增强方案,重点解决数据安全保护和私域化部署的企业痛点,并支持市面上主流的本地大预言模型和 Embedding 模型,无需付费使用。其核心优势包括:
小柒
2024/07/10
2110
金融预测、生成代码、聊天对话:大语言模型的无穷妙用 | 开源专题 No.97
打包成 WASM 的 Postgres:可在浏览器运行 | 开源日报 No.206
pglite 将轻量级的 Postgres 打包成 WASM,并封装为 TypeScript 库,可在浏览器、Node.js、Bun 和 Deno 中运行。
小柒
2024/03/07
2520
打包成 WASM 的 Postgres:可在浏览器运行 | 开源日报 No.206
探索高效智能:AI 模型的优化工具盘点 | 开源专题 No.43
OpenAI Evals 是一个用于评估 LLMs (大型语言模型) 或使用 LLMs 作为组件构建的系统的框架。它还包括一个具有挑战性 evals 的开源注册表。Evals 现在支持通过 Completion Function Protocol 评估任何系统,包括 prompt chains 或 tool-using agents 的行为。通过 Evals,我们旨在尽可能简单地构建 eval,并编写尽量少的代码。“Eval” 是用于评估系统行为质量的任务。
小柒
2023/11/14
4540
探索高效智能:AI 模型的优化工具盘点 | 开源专题 No.43
Ventoy:打造你的万能启动 U 盘 | 开源日报 No.146
Ventoy 是一个开源工具,用于创建支持 ISO/WIM/IMG/VHD(x)/EFI 文件的可启动 USB 驱动器。其主要功能包括将镜像文件复制到 USB 驱动器并进行引导、一次性复制多个镜像文件并提供引导菜单选择以及在本地磁盘中浏览和引导 ISO/WIM/IMG/VHD(x)/EFI 文件等。该项目的核心优势和关键特点包括:
小柒
2024/01/07
3930
Ventoy:打造你的万能启动 U 盘 | 开源日报 No.146
PaddleOCR 高精度文字识别:丰富多样的前沿算法 | 开源日报 No.187
PaddleOCR 是一个丰富、领先和实用的 OCR 工具库,旨在帮助开发者训练更好的模型并将其应用到实际场景中。该项目具有以下特点和优势:
小柒
2024/02/26
5020
PaddleOCR 高精度文字识别:丰富多样的前沿算法 | 开源日报 No.187
推荐阅读
利用 AI 解放双手:把“贾维斯”带进现实 | 开源专题 No.64
3370
让照片开口说话!基于音频生成动画 | 开源日报 No.253
2460
精准视频切片与 AI 智能剪辑工具 | 开源日报 No.311
6100
Cloudflare CDN 速度测试:找到最快的 IP 段 | 开源日报 No.257
7240
WeChatMsg: 导出微信聊天记录 | 开源日报 No.108
1.3K0
daisyUI:最受欢迎的 Tailwind CSS 组件库 | 开源日报 No.181
1.3K0
比 md5 更快更安全:全新的哈希函数 | 开源日报 No.294
3240
使用大型语言模型的指南: 提高效率及安全性的技巧和策略 | 开源日报 0913
2900
Langchain-Chatchat:离线运行的大模型知识库 | 开源日报 No.182
1K0
C++ 算法宝库:多领域覆盖,注释详细 | 开源日报 No.153
3740
中国领先工业级深度学习框架:支持超大规模训练 | 开源日报 No.304
2370
能够解析任何编程语言的开源语法解析树 | 开源日报 No.171
7660
Cypress.io:快速简单可靠的浏览器测试工具 | 开源日报 No.142
3560
谷歌开源的跨平台高效序列化库:极速访问,内存高效 | 开源日报 No.289
1680
性能与效率比拼:开源大语言模型竞逐 | 开源专题 No.76
2560
金融预测、生成代码、聊天对话:大语言模型的无穷妙用 | 开源专题 No.97
2110
打包成 WASM 的 Postgres:可在浏览器运行 | 开源日报 No.206
2520
探索高效智能:AI 模型的优化工具盘点 | 开源专题 No.43
4540
Ventoy:打造你的万能启动 U 盘 | 开源日报 No.146
3930
PaddleOCR 高精度文字识别:丰富多样的前沿算法 | 开源日报 No.187
5020
相关推荐
利用 AI 解放双手:把“贾维斯”带进现实 | 开源专题 No.64
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档