> 文章列表 > 基于tensorflow和tensorflow-quantum的量子机器学习环境搭建, Mac环境下

基于tensorflow和tensorflow-quantum的量子机器学习环境搭建, Mac环境下

基于tensorflow和tensorflow-quantum的量子机器学习环境搭建, Mac环境下

量子神经网络(Quantum neural networks, QNN)及其变体量子卷积神经网络(Quantum convolutional networks, QCNN),在内存和速度方面都有着高效的优势,能将经典向量由n维编码到log2^n个量子位,同时量子具有多个状态进行并行叠加运算。
这里给出一个经典结构的量子神经网络模型,如下图所示:
在这里插入图片描述
结构类似一个全连接神经网络,特征映射当作输入层进行量子态的准备,量子变换作为隐藏层将经典信息变换为量子信息,量子测量和输出相当于全连接神经网络的输出层。θ作为权重在优化器优化后进行更新。

本次搭建使用到的软件为:Anaconda、JupterNotebook
在Anaconda中新建环境为tensorflowq,选择Python版本为3.8.16,在终端激活环境:
在这里插入图片描述

把路径换到我们新建的环境,然后输入

pip install tensorflow==2.7.0

下载2.7.0版本的tensorflow,这里我已经下载过了,得到结果:
在这里插入图片描述
安装成功!下面安装要用到的quantum库,输入

pip install tensorflow-quantum==0.7.2

输入pip list查看安装好的库,安装成功:
在这里插入图片描述

下面找到官网:https://tensorflow.google.cn/quantum/tutorials/hello_many_worlds 给出的案例hello_many_world
复制代码到JupyterNotebook中:

import cirq
import sympy
import numpy as np
# visualization tools
import matplotlib.pyplot as plt
from cirq.contrib.svg import SVGCircuit
a, b = sympy.symbols('a b')
# 创建两个量子比特
q0, q1 = cirq.GridQubit.rect(1, 2)# 使用上面创建的参数在这些量子位上创建一个电路。
circuit = cirq.Circuit(cirq.rx(a).on(q0),cirq.ry(b).on(q1), cirq.CNOT(control=q0, target=q1))SVGCircuit(circuit)

使用设置的参数得到一个二量子电路:
在这里插入图片描述
在pycharm下调试代码观察参数内容如下:
在这里插入图片描述
可以使用criq评估电路,使用特定的数字替换电路中的自由参数对象,下面计算参数化电路的原始状态向量输出:

# 计算 a = 0.5和 b = -0.5的状态向量。
resolver = cirq.ParamResolver({a: 0.5, b: -0.5})
output_state_vector = cirq.Simulator().simulate(circuit, resolver).final_state_vector

在这里插入图片描述得到量子的四个状态向量,这里用复数表示,由于状态向量在模拟之外不能直接访问。实际中需要指定一个度量值,它将状态向量转换为经典计算机能够理解的实数。如下代码:

z0 = cirq.Z(q0)
qubit_map={q0: 0, q1: 1}
z_real = z0.expectation_from_state_vector(output_state_vector, qubit_map).real
print(z_real)

得到结果如下:

在这里插入图片描述

z0x1 = 0.5 * z0 + cirq.X(q1)z0x1.expectation_from_state_vector(output_state_vector, qubit_map).real

得到结果如下:
在这里插入图片描述
TensorFlow Quantum提供了将criq对象转化为张量的函数,这使得可以将criq对象发送到量子层并进行量子操作,具体操作如下,该函数可以在Criq Circuit和Cirq Paulis的列表或数组上调用:

# 一阶张量包含一个电路
circuit_tensor = tfq.convert_to_tensor([circuit])
print(circuit_tensor.shape)
print(circuit_tensor.dtype)

在这里插入图片描述
将criq对象编码为tf.string张量,并根据需要进行解码:

# 包含两个泡利算子的一阶张量
pauli_tensor = tfq.convert_to_tensor([z0, z0x1])
pauli_tensor.shape

在这里插入图片描述
计算期望值的最高级接口是tfq.layers.Expectation层,即tf.keras.Layer。以最简单的形式,该层相当于在cirq.ParamResolvers上模拟参数化电路;然而,TFQ允许按照TensorFlow语义进行批处理,并使用高效的C++代码模拟电路。

下面创造一批值来代替a和b参数。

batch_vals = np.array(np.random.uniform(0, 2 * np.pi, (5, 2)), dtype=float)

在Cirq中对参数值进行电路执行需要一个循环:

cirq_results = []
cirq_simulator = cirq.Simulator()for vals in batch_vals:resolver = cirq.ParamResolver({a: vals[0], b: vals[1]})final_state_vector = cirq_simulator.simulate(circuit, resolver).final_state_vectorcirq_results.append([z0.expectation_from_state_vector(final_state_vector, {q0: 0,q1: 1}).real])print('cirq batch results: \\n {}'.format(np.array(cirq_results)))

结果如下:
在这里插入图片描述
在TFQ中简化了相同的操作:

tfq.layers.Expectation()(circuit,symbol_names=[a, b],symbol_values=batch_vals,operators=z0)

结果如下:
在这里插入图片描述