基于 MindQuantum 实现对含有自定义量子门且损失函数涉及多个哈密顿量的量子线路的训练

前面文章 如何利用 MindQuantum 中自定义的量子门,实现对多个哈密顿量求期望值和梯度? 中已经提到了,采用 Projectq 后端的 MindQuantum 0.7.0 及之前的版本不支持对损失函数涉及多个哈密顿量的自定义量子门组成的量子线路求梯度,我们在那篇文章中就采用中心差分,自己动手编了一个函数来完成该任务。在本文中,我们更进一步,综合起之前的几篇文章(如何利用 MindQuantum 中自定义的量子门,实现对多个哈密顿量求期望值和梯度? ,MindQuantum 中 get_exceptation_with_grad 和 grad_ops 之间的关系,MindQuantum自定义损失函数和目标标签训练部分量子线路等)来实现一个更高级的任务:构建框架,实现对含有自定义量子门且损失函数涉及多个哈密顿量的量子线路的训练。我们希望随着 MindQuantum 下个版本推出的新的自研后端,能天然地解决这个问题,而不必像现在这样麻烦。

我们先导入依赖库:

import mindspore as ms
import numpy as np
from mindspore import context, nn
from mindspore.ops import operations
from mindquantum import *
from mindspore.nn import Adam, TrainOneStepCell, LossBase
from mindspore.common.initializer import initializer
from mindspore.common.parameter import Parameter
ms.context.set_context(mode=ms.context.PYNATIVE_MODE, device_target="CPU")
import copy

自定义量子门。此处 gate_xgate_z 实际就是 MindQuantum 中的 RXRZ,但采用自定义的方式。虽然本质是一样的,但因为当前的后端 Projectq 不支持自定义的量子门,所以才出现了本文要解决的这个问题。

def matrix_x(theta):return np.array([[np.cos(theta / 2), -1j * np.sin(theta / 2)],[-1j * np.sin(theta / 2), np.cos(theta / 2)]])def diff_matrix_x(theta):return 0.5 * np.array([[-np.sin(theta / 2), -1j * np.cos(theta / 2)],[-1j * np.cos(theta / 2), -np.sin(theta / 2)]])def matrix_z(theta):return np.array([[np.exp(-1j * theta / 2), 0], [0, np.exp(1j * theta / 2)]])def diff_matrix_z(theta):return 0.5j * np.array([[-np.exp(-1j * theta / 2), 0], [0, np.exp(1j * theta / 2)]])gate_x = gene_univ_parameterized_gate('gete_x', matrix_x, diff_matrix_x) # 自定义量子门
gate_z = gene_univ_parameterized_gate('gete_z', matrix_z, diff_matrix_z) # 自定义量子门

仿照 MindQuantum 中 Simulator 搭建自定义的模拟器类,但只有求期望值和梯度的功能,且梯度的计算使用差分法。

class my_simulator: def get_expectation_with_grad(self, hams, circ): # 输入为 hams, circ_right, simulator_left 等,这里就只用 hams 代替。sim = Simulator('projectq', 1) def grad_ops(inputs): # 输入为各量子门的参数h = 1e-4grad = []sim.reset()sim.apply_circuit(circ, inputs)exceptation = [sim.get_expectation(ham).real for ham in hams]for i in range(inputs.size):params_p, params_n = copy.deepcopy(inputs), copy.deepcopy(inputs)params_p[i] += hparams_n[i] -= hsim.reset()sim.apply_circuit(circ, params_p)g_p = [sim.get_expectation(ham) for ham in hams]sim.reset()sim.apply_circuit(circ, params_n)g_n = [sim.get_expectation(ham) for ham in hams]grad.append([(p.real - n.real)/(2*h) for p, n in zip(g_p, g_n)])sim.reset()return exceptation, np.array(grad).T # 运行结果为期望值和梯度return grad_ops # MindQuantum 中,这里返回的是一个封装了 hams, grad_ops 等的一个封装器,这里简化为单独的 grad_ops

仿照 MindQuantum 中的 AnsatzOnlyOps 搭建的一个 ops

class ansatz_only_ops(nn.Cell):def __init__(self, expectation_with_grad):super().__init__()self.expectation_with_grad = expectation_with_gradself.shape_ops = operations.Shape()self.g = None def construct(self, arg):fval, g_ans = self.expectation_with_grad(arg.asnumpy())self.g = np.real(g_ans)return ms.Tensor(np.real(fval), dtype=ms.float32)def bprop(self, arg, out, dout): dout = dout.asnumpy()grad = dout @ self.greturn ms.Tensor(grad, dtype=ms.float32)

仿照 MindQuantum 中的 AnsatzOnlyLayer 搭建的一个 Layer,用于封装量子线路,就可以和 MindSpore 的参数优化功能完美融合在一起了。

class ansatz_only_layer(nn.Cell):def __init__(self, expectation_with_grad, weight='ones'):super().__init__()self.evolution = ansatz_only_ops(expectation_with_grad)weight_size = len(circ.params_name)self.weight = Parameter(initializer(weight, weight_size, dtype=ms.float32), name='ansatz_weight')def construct(self):return self.evolution(self.weight)

损失函数,为展示此工程功能,这里的损失函数设定为两个哈密顿量的和,即 Z0 + X0

class MyLoss(LossBase):def __init__(self, reduction='mean'):super(MyLoss, self).__init__(reduction)def construct(self, logits):out = logits[0] + logits[1] return self.get_loss(out)

将量子网络和损失函数合并起来。

class MyWithLossCell(nn.Cell):def __init__(self, backbone, loss_fn):super(MyWithLossCell, self).__init__(auto_prefix=False)self._backbone = backboneself._loss_fn = loss_fndef construct(self):out = self._backbone()return self._loss_fn(out)@propertydef backbone_network(self):return self._backbone

包含有自定义量子门的量子线路和构建损失函数哈密顿量。其中,量子线路采用 ZXZ 分解,而损失函数涉及多个哈密顿量(Z0X0)。

circ = Circuit()
circ += gate_z('a').on(0)
circ += gate_x('b').on(0)
circ += gate_z('c').on(0)
circ.as_ansatz()hams = [Hamiltonian(QubitOperator('Z0')),Hamiltonian(QubitOperator('X0'))] # 多个哈密顿量

实例化自定义的类,且将量子网络和损失函数整合起来。

my_sim = my_simulator()
grad_ops = my_sim.get_expectation_with_grad(hams, circ)qnet = ansatz_only_layer(grad_ops)
loss = MyLoss()
net_with_criterion = MyWithLossCell(qnet, loss)
opti = Adam(qnet.trainable_params(), learning_rate=0.5)
net = TrainOneStepCell(net_with_criterion, opti)

训练并得到最终结果:

for i in range(100):res = net()if i % 10 == 0:print(f'当前训练次数为:{i}, 损失函数值为:{res}')
当前训练次数为:0, 损失函数值为:1.2483757
当前训练次数为:10, 损失函数值为:-1.0459888
当前训练次数为:20, 损失函数值为:-1.3248273
当前训练次数为:30, 损失函数值为:-1.4057021
当前训练次数为:40, 损失函数值为:-1.4104203
当前训练次数为:50, 损失函数值为:-1.4127097
当前训练次数为:60, 损失函数值为:-1.4128952
当前训练次数为:70, 损失函数值为:-1.4132676
当前训练次数为:80, 损失函数值为:-1.4137471
当前训练次数为:90, 损失函数值为:-1.4141047

验证结果:

sim = Simulator('projectq', 1)sim.apply_circuit(circ, pr=qnet.weight.asnumpy())
print('\n最终的量子态为:\n', sim.get_qs(ket=True))z0 = sim.get_expectation(Hamiltonian(QubitOperator('Z0')))
x0 = sim.get_expectation(Hamiltonian(QubitOperator('X0')))
print('\n最终损失函数值为:', (z0+x0).real)
最终的量子态为:(0.36679647134390286+0.10726773357418498j)¦0⟩
(-0.8864696281552857-0.2610087743769323j)¦1⟩最终损失函数值为: -1.4142114663496177

基于 MindQuantum 实现对含有自定义量子门且损失函数涉及多个哈密顿量的量子线路的训练相关推荐

  1. 量子笔记:单比特量子门、泡利矩阵

    目录 0. 概要 1. 量子门基本性质 1.1 量子门与布洛赫球面的关系 1.2 量子门与幺正矩阵的关系 2. 泡利矩阵: 量子X,Y,Z,ID门 2.1 量子X门(量子非门) 2.2 量子Z门 2. ...

  2. 量子计算 3 量子门与测量

    量子计算 3 量子门与测量 1 经典门与量子门 (Quantum gate) 1.1 什么是量子门 1.2 单比特门操作 NOT/X (Pauli-X or NOT) NOT\sqrt{\text{N ...

  3. plotly基于dataframe数据绘制股票自定义K线图

    plotly基于dataframe数据绘制股票自定义K线图 #  绘制蜡烛图并自定义可视化形式: import plotly as py import plotly.graph_objs as go ...

  4. 智能门禁(4)---基于face++和Onenet平台的人脸门禁系统

    基于face++和Onenet平台的人脸门禁系统 前言 第一次见识人脸解锁是在iPhoneX,前两天安卓8.0的小米6把我的手机也可以做到人脸结果.各大公司都推出了自己的人脸识别Api,因为个人兴趣, ...

  5. 将含有自定义代码的Infopath模板发布到Sharepoint表单库中

    最近一好友通过msn曰:"ocean最近没有写点什么?".想想也确实应该写点什么了.从实际的项目经验来说,也确实有很多东西可以写,至少也能写个小册子,但是始终没有静下心来写.上次去 ...

  6. 走进量子计算的大门——使用量桨PaddleQuantum创建单量子比特门

    使用量桨PaddleQuantum创建单量子比特门 一.量子计算概述 量子计算机为什么能同时存储0和1? 如何测量量子计算的结果 量子计算背后的哲学原理 二.量子计算的数学基础 1.量子比特 2.量子 ...

  7. android 横向滚轮控件,Android滚轮控件,基于ListView实现,可以自定义样式。

    Android滚轮控件,基于ListView实现,可以自定义样式. Features 支持自定义滚轮样式 支持common和holo两种皮肤 支持文本和图文混排两中数据模版 支持循环显示数据 支持选中 ...

  8. php 微信分享功能_基于thinkPHP实现的微信自定义分享功能

    这篇文章主要介绍了基于thinkPHP实现的微信自定义分享功能,结合实例形式分析了thinkPHP调用微信接口实现自定义分享功能的相关操作技巧,需要的朋友可以参考下 本文实例讲述了基于thinkPHP ...

  9. java自定义配置文件_基于java读取并引用自定义配置文件

    基于java读取并引用自定义配置文件 首先在resources目录创建自定义的配置文件 配置文件的格式: 写工具类,得到配置参数 import java.io.IOException; import ...

最新文章

  1. php中js代码放在哪,JavaScript
  2. Xamarin.iOS模拟器调试找不到资源文件
  3. python【力扣LeetCode算法题库】104-二叉树的最大深度
  4. 从mysqldump整库备份文件中恢复单表
  5. C#中5步完成word文档打印的方法
  6. java jvm 加载_Jvm是如何加载Java类的?
  7. Yum (yellow dog update manager)
  8. Toolbox的Ajax Extensions Tab不见了
  9. 老男孩shell实战读书笔记 (6-10章节)
  10. 微信公众号-注册最全6种类型接口权限,注册哪个好?
  11. android radiogroup 底部菜单,Android底部菜单栏(RadioGroup+Fragment)美化
  12. 2019美赛备战日记1/18
  13. 奇虎360 php t5级别,奇虎360凭什么估值3800亿?核心价值只是他而已!
  14. 公众号引用js sdk ios兼容问题 报 permission value is offline verifying
  15. 卷积操作中的group
  16. 运用HTML制作简单效果
  17. with dlz mysql 条件_Bind-DLZ with MySQL
  18. HDU 5514 容斥原理
  19. 使用CDN实现应用的缓存和加速
  20. 华为服务器网口显示down,[已解决]华为三层交换机新建vlan后端口总是down的状态[已解决]~有好心人帮忙看看吗?谢谢~ - 华为技术论坛 - 51CTO技术论坛_中国领先的IT技术社区...

热门文章

  1. Nat. Microbiol. | 功能选择揭示大肠杆菌泛基因组中未被发现的抗噬菌体防御系统...
  2. IE0新特性归纳及JavaScript 功能增强分析
  3. 详解使用Ghost安装Win7系统步骤
  4. java工资高还是php_为什么java比php工资高啊?
  5. 《Android源码设计模式解析与实战》读书笔记(十七)——中介者模式
  6. python网络安全论文题目_计算机科学与技术专业毕业论文参考题目.doc
  7. linux下匹配字符串,linux上强大的字符串匹配工具详解-grep
  8. 知识图谱学习笔记——(二)知识图谱的表示
  9. 关于安装完fedora后的一些美化
  10. 教育小程序能给机构带来什么招生优势?