提交 f9646c83 编写于 作者: Q Quleaf

update tutorials

上级 7b61f772
...@@ -2,31 +2,57 @@ ...@@ -2,31 +2,57 @@
"cells": [ "cells": [
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"# 旅行商问题\n", "# 旅行商问题\n",
"\n", "\n",
"<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>" "<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>"
] ],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## 概览\n", "## 概览\n",
"\n", "\n",
"旅行商问题(travelling salesman problem, TSP)是组合优化中最经典的 NP–困难的问题之一,它指的是以下这个问题:\"已知一系列的城市和它们之间的距离,这个旅行商想造访所有城市各一次,并最后返回出发地,求他的最短路线规划。\"\n", "旅行商问题(travelling salesman problem, TSP)是组合优化中最经典的 NP–困难的问题之一,它指的是以下这个问题:\"已知一系列的城市和它们之间的距离,这个旅行商想造访所有城市各一次,并最后返回出发地,求他的最短路线规划。\"\n",
"\n", "\n",
"这个问题也可以用图论的语言来描述。已知一个有权重的完全图 $G = (V,E)$。它的每个顶点 $i \\in V$ 都对应一个城市 $i$,并且每一条边 $(i,j) \\in E$ 的权重 $w_{i,j}$ 对应城市 $i$ 和城市 $j$ 的距离。需要注意的是,$G$ 是个无向图,所以权重是对称的,即 $w_{i,j}= w_{j,i}$。根据以上定义,旅行商问题可以转化为找这个图中最短的哈密顿回路(Hamiltonian cycle)的问题。哈密顿回路为一个通过且仅通过每一个顶点一次的回路。 " "这个问题也可以用图论的语言来描述。已知一个有权重的完全图 $G = (V,E)$。它的每个顶点 $i \\in V$ 都对应一个城市 $i$,并且每一条边 $(i,j) \\in E$ 的权重 $w_{i,j}$ 对应城市 $i$ 和城市 $j$ 的距离。需要注意的是,$G$ 是个无向图,所以权重是对称的,即 $w_{i,j}= w_{j,i}$。根据以上定义,旅行商问题可以转化为找这个图中最短的哈密顿回路(Hamiltonian cycle)的问题。哈密顿回路为一个通过且仅通过每一个顶点一次的回路。 "
] ],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"## 使用量子神经网络解旅行商问题\n",
"\n",
"使用量子神经网络方法解决旅行商问题,需要首先将该问题编码为量子形式。\n",
"具体的包括以下两部分:\n",
"\n",
"1. 旅行商经过城市的顺序将编码进量子态 —— ${\\rm qubit}_{i,t} = |1\\rangle$ 对应于在时间 $t$ 经过城市$i$。\n",
" 1. 以两城市$\\{A,B\\}$举例。先经过$A$再经过$B$ 将由$|1001\\rangle$表示,对应于旅行商在时间 $1$ 经过城市$A$,在时间 $2$ 经过城市$B$。\n",
" 2. 类似的 $|0110\\rangle$对应于先经过$B$再经过$A$.\n",
" 3. 注意:$|0101\\rangle$意味着在时间 $2$ 同时经过城市 $A$、$B$,而这是不可能的。为避免此类量子态,我们会通过引入代价函数的方式 (具体见下一节)。\n",
"\n",
"2. 总距离被编码进损失函数: \n",
"\n",
"$$\n",
"L(\\psi(\\vec{\\theta})) = \\langle\\psi(\\vec{\\theta})|H_C|\\psi(\\vec{\\theta})\\rangle \\, ,\n",
"\\tag{1}\n",
"$$\n",
"其中 $|\\psi(\\vec{\\theta})\\rangle$ 对应于参数化量子电路的输出。\n",
"\n",
"在下一节中将详细介绍如何编码旅行商问题为对应量子问题。通过优化损失函数,我们将得到对应最优量子态。再通过解码,将得到最终的路线规划"
],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## 编码旅行商问题\n", "### 编码旅行商问题\n",
"\n",
"为了将旅行商问题转化成一个参数化量子电路(parameterized quantum circuits, PQC)可解的问题,我们首先需要编码旅行商问题的哈密顿量。\n",
"\n", "\n",
"为了将旅行商问题转化成一个参数化量子电路(parameterized quantum circuits, PQC)可解的问题,我们首先需要编码旅行商问题的哈密顿量。我们先将此问题转化为一个整数规划问题:假设图形 $G$ 的顶点数量为 $|V| = n$ 个,那么对于每个顶点 $i \\in V$,我们定义 $n$ 个二进制变量 $x_{i,t}$,$t \\in [0,n-1]$:\n", "我们先将此问题转化为一个整数规划问题:假设图形 $G$ 的顶点数量为 $|V| = n$ 个,那么对于每个顶点 $i \\in V$,我们定义 $n$ 个二进制变量 $x_{i,t}$,$t \\in [0,n-1]$:\n",
"\n", "\n",
"$$\n", "$$\n",
"x_{i, t}=\n", "x_{i, t}=\n",
...@@ -34,28 +60,28 @@ ...@@ -34,28 +60,28 @@
"1, & \\text{如果在最后的哈密顿回路中,顶点 } i \\text { 的顺序为 $t$,即在时间 $t$ 的时候被旅行商访问}\\\\\n", "1, & \\text{如果在最后的哈密顿回路中,顶点 } i \\text { 的顺序为 $t$,即在时间 $t$ 的时候被旅行商访问}\\\\\n",
"0, & \\text{其他情况}\n", "0, & \\text{其他情况}\n",
"\\end{cases}.\n", "\\end{cases}.\n",
"\\tag{1}\n", "\\tag{2}\n",
"$$\n", "$$\n",
"\n", "\n",
"因为 $G$ 有 $n$ 个顶点,所以我们共有 $n^2$ 个变量 $x_{i,t}$,所有这些变量的取值我们用 $x=x_{1,1}x_{1,2}\\dots x_{n,n}$ 来表示。现在我们假设 $x$ 对应了一条哈密顿回路,那么对于图中的每一条边 $(i,j,w_{i,j}) \\in E$,条件 $x_{i,t} = x_{j,t+1} = 1$(也可以等价地写成 $x_{i,t}\\cdot x_{j,t+1} = 1$)成立当且仅当该哈密顿回路中的第 $t$ 个顶点是顶点 $i$ 并且第 $t+1$ 个顶点是顶点 $j$;否则,$x_{i,t}\\cdot x_{j,t+1} = 0$。所以我们可以用下式计算哈密顿回路的长度\n", "因为 $G$ 有 $n$ 个顶点,所以我们共有 $n^2$ 个变量 $x_{i,t}$,所有这些变量的取值我们用 $x=x_{1,1}x_{1,2}\\dots x_{n,n}$ 来表示。现在我们假设 $x$ 对应了一条哈密顿回路,那么对于图中的每一条边 $(i,j,w_{i,j}) \\in E$,条件 $x_{i,t} = x_{j,t+1} = 1$(也可以等价地写成 $x_{i,t}\\cdot x_{j,t+1} = 1$)成立当且仅当该哈密顿回路中的第 $t$ 个顶点是顶点 $i$ 并且第 $t+1$ 个顶点是顶点 $j$;否则,$x_{i,t}\\cdot x_{j,t+1} = 0$。所以我们可以用下式计算哈密顿回路的长度\n",
"\n", "\n",
"$$\n", "$$\n",
"D(x) = \\sum_{i,j} w_{i,j} \\sum_{t} x_{i,t} x_{j,t+1}.\n", "D(x) = \\sum_{i,j} w_{i,j} \\sum_{t} x_{i,t} x_{j,t+1}.\n",
"\\tag{2}\n", "\\tag{3}\n",
"$$\n", "$$\n",
"\n", "\n",
"根据哈密顿回路的定义,$x$ 如果对应一条哈密顿回路需要满足如下的限制:\n", "根据哈密顿回路的定义,$x$ 如果对应一条哈密顿回路需要满足如下的限制:\n",
"\n", "\n",
"$$\n", "$$\n",
"\\sum_t x_{i,t} = 1 \\quad \\forall i \\in [0,n-1] \\quad \\text{ 和 } \\quad \\sum_i x_{i,t} = 1 \\quad \\forall t \\in [0,n-1],\n", "\\sum_t x_{i,t} = 1 \\quad \\forall i \\in [0,n-1] \\quad \\text{ 和 } \\quad \\sum_i x_{i,t} = 1 \\quad \\forall t \\in [0,n-1],\n",
"\\tag{3}\n", "\\tag{4}\n",
"$$\n", "$$\n",
"\n", "\n",
"其中第一个式子用来保证找到的 $x$ 所代表的路线中每个顶点仅出现一次,第二个式子保证在每个时间只有一个顶点可以出现。这两个式子共同保证了参数化量子电路找到的 $x$ 是个哈密顿回路。所以,我们可以定义在此限制下的代价函数:\n", "其中第一个式子用来保证找到的 $x$ 所代表的路线中每个顶点仅出现一次,第二个式子保证在每个时间只有一个顶点可以出现。这两个式子共同保证了参数化量子电路找到的 $x$ 是个哈密顿回路。所以,我们可以定义在此限制下的代价函数:\n",
"\n", "\n",
"$$\n", "$$\n",
"C(x) = D(x)+ A\\left( \\sum_{i} \\left(1-\\sum_t x_{i,t}\\right)^2 + \\sum_{t} \\left(1-\\sum_i x_{i,t}\\right)^2 \\right).\n", "C(x) = D(x)+ A\\left( \\sum_{i} \\left(1-\\sum_t x_{i,t}\\right)^2 + \\sum_{t} \\left(1-\\sum_i x_{i,t}\\right)^2 \\right).\n",
"\\tag{4}\n", "\\tag{5}\n",
"$$\n", "$$\n",
"\n", "\n",
"其中 $A$ 是惩罚参数,它保证了上述的限制被遵守。因为我们想要在找哈密顿回路的长度 $D(x)$ 的最小值的同时保证 $x$ 确实表示一个哈密顿回路,所以我们需要设置一个大一点的 $A$,最起码大过图 $G$ 中边的最大的权重,从而保证不遵守限制的路线不会成为最终的路线。\n", "其中 $A$ 是惩罚参数,它保证了上述的限制被遵守。因为我们想要在找哈密顿回路的长度 $D(x)$ 的最小值的同时保证 $x$ 确实表示一个哈密顿回路,所以我们需要设置一个大一点的 $A$,最起码大过图 $G$ 中边的最大的权重,从而保证不遵守限制的路线不会成为最终的路线。\n",
...@@ -65,79 +91,74 @@ ...@@ -65,79 +91,74 @@
"我们现在将二进制变量映射到泡利 $Z$ 矩阵上,从而使 $C(x)$ 转化成哈密顿矩阵:\n", "我们现在将二进制变量映射到泡利 $Z$ 矩阵上,从而使 $C(x)$ 转化成哈密顿矩阵:\n",
"\n", "\n",
"$$\n", "$$\n",
"x_{i,t} \\mapsto \\frac{I-Z_{i,t}}{2}, \\tag{5}\n", "x_{i,t} \\mapsto \\frac{I-Z_{i,t}}{2}, \\tag{6}\n",
"$$\n", "$$\n",
"\n", "\n",
"这里 $Z_{i,t} = I \\otimes I \\otimes \\ldots \\otimes Z \\otimes \\ldots \\otimes I$,也就是说 $Z$ 作用在位置在 $(i,t)$ 的量子比特上。通过这个映射,如果一个编号为 $(i,t)$ 的量子比特的量子态为 $|1\\rangle$,那么对应的二进制变量的取值为 $x_{i,t} |1\\rangle = \\frac{I-Z_{i,t}}{2} |1\\rangle = 1 |1\\rangle$,也就是说顶点 $i$ 在最短哈密顿回路中的位置是 $t$。同样地,对于量子态为 $|0\\rangle$的量子比特 $(i,t)$,它所对应的二进制变量的取值为 $x_{i,t} |0\\rangle = \\frac{I-Z_{i,t}}{2} |0\\rangle = 0 |0\\rangle$。\n", "这里 $Z_{i,t} = I \\otimes I \\otimes \\ldots \\otimes Z \\otimes \\ldots \\otimes I$,也就是说 $Z$ 作用在位置在 $(i,t)$ 的量子比特上。通过这个映射,如果一个编号为 $(i,t)$ 的量子比特的量子态为 $|1\\rangle$,那么对应的二进制变量的取值为 $x_{i,t} |1\\rangle = \\frac{I-Z_{i,t}}{2} |1\\rangle = 1 |1\\rangle$,也就是说顶点 $i$ 在最短哈密顿回路中的位置是 $t$。同样地,对于量子态为 $|0\\rangle$的量子比特 $(i,t)$,它所对应的二进制变量的取值为 $x_{i,t} |0\\rangle = \\frac{I-Z_{i,t}}{2} |0\\rangle = 0 |0\\rangle$。\n",
"\n", "\n",
"我们用上述映射将 $C(x)$ 转化成量子比特数为 $n^2$ 的系统的哈密顿矩阵 $H_C$,从而实现了旅行商问题的量子化。这个哈密顿矩阵 $H_C$ 的基态即为旅行商问题的最优解。在接下来的章节中,我们将展示怎么用参数化量子电路找到这个矩阵的基态,即对应最小本征值的本征态。" "我们用上述映射将 $C(x)$ 转化成量子比特数为 $n^2$ 的系统的哈密顿矩阵 $H_C$,从而实现了旅行商问题的量子化。这个哈密顿矩阵 $H_C$ 的基态即为旅行商问题的最优解。在接下来的章节中,我们将展示怎么用参数化量子电路找到这个矩阵的基态,即对应最小本征值的本征态。"
] ],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## Paddle Quantum 实现\n", "## Paddle Quantum 实现\n",
"\n", "\n",
"要在量桨上实现用参数化量子电路解决旅行商问题,首先要做的便是加载需要用到的包。其中 `networkx` 包可以帮助我们方便地处理图。" "要在量桨上实现用参数化量子电路解决旅行商问题,首先要做的便是加载需要用到的包。其中 `networkx` 包可以帮助我们方便地处理图。"
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": 1,
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:00:15.901429Z",
"start_time": "2021-05-17T08:00:12.708945Z"
}
},
"outputs": [],
"source": [ "source": [
"# 加载量桨、飞桨的相关模块\n", "# 加载量桨、飞桨的相关模块\n",
"import paddle\n", "import paddle\n",
"from paddle_quantum.circuit import UAnsatz\n", "from paddle_quantum.circuit import UAnsatz\n",
"from paddle_quantum.QAOA.tsp import tsp_hamiltonian # 构造旅行商问题哈密顿量的函数\n", "\n",
"from paddle_quantum.QAOA.tsp import solve_tsp_brute_force\n", "# 旅行商问题相关函数\n",
"from paddle_quantum.QAOA.tsp import tsp_hamiltonian # 构造旅行商问题哈密顿量的函数\n",
"from paddle_quantum.QAOA.tsp import solve_tsp_brute_force # 暴力求解旅行商问题\n",
"\n",
"# 用于生成图\n",
"import networkx as nx\n",
"\n", "\n",
"# 加载额外需要用到的包\n", "# 加载额外需要用到的包\n",
"from numpy import pi as PI\n", "from numpy import pi as PI\n",
"import matplotlib.pyplot as plt\n", "import matplotlib.pyplot as plt\n",
"import networkx as nx\n", "import random\n",
"import random" "import time"
] ],
"outputs": [],
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:00:15.901429Z",
"start_time": "2021-05-17T08:00:12.708945Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"### 生成该旅行商问题中的图 "
],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"接下来,我们生成该旅行商问题中的图 $G$。为了运算方便,图中的顶点从0开始计数。" "接下来,我们生成该旅行商问题中的图 $G$。为了运算方便,图中的顶点从0开始计数。"
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 2,
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:00:16.212260Z",
"start_time": "2021-05-17T08:00:15.918792Z"
}
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [ "source": [
"# n 代表图形 G 的顶点数量\n", "# n 代表图形 G 的顶点数量\n",
"n = 4\n", "n = 4\n",
"E = [(0, 1, 3), (0, 2, 2), (0, 3, 10), (1, 2, 6), (1, 3, 2), (2, 3, 6)]\n", "E = [(0, 1, 3), (0, 2, 2), (0, 3, 10), (1, 2, 6), (1, 3, 2), (2, 3, 6)] # 线段参数(顶点1, 顶点2, 权重(距离))\n",
"G = nx.Graph()\n", "G = nx.Graph()\n",
"G.add_weighted_edges_from(E)\n", "G.add_weighted_edges_from(E)\n",
"\n", "\n",
...@@ -156,249 +177,272 @@ ...@@ -156,249 +177,272 @@
"ax.margins(0.20)\n", "ax.margins(0.20)\n",
"plt.axis(\"off\")\n", "plt.axis(\"off\")\n",
"plt.show()" "plt.show()"
] ],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
],
"image/png": "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"
},
"metadata": {}
}
],
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:00:16.212260Z",
"start_time": "2021-05-17T08:00:15.918792Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"### 编码哈密顿量\n", "### 编码哈密顿量\n",
"\n", "\n",
"量桨中,哈密顿量可以以 ``list`` 的形式输入。这里我们将式(4)中的二进制变量用式(5)替换,从而构建哈密顿量 $H_C$。\n", "量桨中,哈密顿量可以以 ``list`` 的形式输入。这里我们将式(4)中的二进制变量用式(5)替换,从而构建哈密顿量 $H_C$。具体的形式可以通过内置函数 tsp_hamiltonian(G, A, n)直接得到。\n",
"\n", "\n",
"为了节省量子比特数,我们改进了上述哈密顿量的构造:因为哈密顿回路的性质,顶点 $n-1$ 一定会被包括在其中,同时因为顶点的绝对顺序并不重要,所以我们可以**固定顶点 $n-1$ 在最短哈密顿回路的最后一个,即它所代表的城市最后一个被旅行商到访。** 这也就是说,对所有的 $t$ 和所有的 $i$,我们固定 $x_{n-1,t} = \\delta_{n-1,t}$ 和 $x_{i,n-1} = \\delta_{i,n-1}$(如果 $i=j$,那么$\\delta_{i,j} = 1$,反之则为 $0$)。\n", "**注意:** 对于旅行商问题,由于我们总可以选定某一个城市为第一个抵达的城市,故实际所需量子比特数可以从 $n^2$ 降到了 $(n-1)^2$。在我们接下来的实现当中都会使用改进过的哈密顿量来计算。"
"\n", ],
"这种改进将解决旅行商问题所需要的量子比特数从 $n^2$ 降到了 $(n-1)^2$,在我们接下来的实现当中都会使用改进过的哈密顿量来计算。" "metadata": {}
]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 3,
"source": [
"# 以 list 的形式构建哈密顿量 H_C -- 通过内置函数tsp_hamiltonian(G, A, n)\n",
"A = 20 # 惩罚参数\n",
"H_C_list = tsp_hamiltonian(G, A, n)"
],
"outputs": [],
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-17T08:00:16.237497Z", "end_time": "2021-05-17T08:00:16.237497Z",
"start_time": "2021-05-17T08:00:16.219567Z" "start_time": "2021-05-17T08:00:16.219567Z"
} }
}, }
"outputs": [],
"source": [
"# 以 list 的形式构建哈密顿量 H_C\n",
"A = 20 # 惩罚参数\n",
"H_C_list = tsp_hamiltonian(G, A, n)"
]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"### 计算损失函数\n", "### 计算损失函数\n",
"\n", "\n",
"在最大割问题([Max-Cut 教程](./MAXCUT_CN.ipynb))中,我们用 QAOA 构建了我们的参数化量子电路,但除了 QAOA 电路,其他的电路也可以用来解决组合优化问题。对于旅行商问题,我们将使用 $U_3(\\vec{\\theta})$ 和 $\\text{CNOT}$ 门构造的参数化量子电路。这可以通过调用量桨内部的 [`complex entangled layer`](https://qml.baidu.com/api/paddle_quantum.circuit.uansatz.html) 来实现。\n", "在最大割问题([Max-Cut 教程](./MAXCUT_CN.ipynb))中,我们用 QAOA 构建了我们的参数化量子电路,但除了 QAOA 电路,其他的电路也可以用来解决组合优化问题。对于旅行商问题,我们将使用 $U_3(\\vec{\\theta})$ 和 $\\text{CNOT}$ 门构造的参数化量子电路。这可以通过调用量桨内部的 [`complex entangled layer`](https://qml.baidu.com/api/paddle_quantum.circuit.uansatz.html) 来实现。\n",
"\n", "\n",
"上述电路会给出一个输出态 $|\\vec{\\theta}\\rangle$,由此输出态,我们可以计算最大割问题的目标函数,也就是旅行商问题的损失函数:\n", "<img src=\"./figures/tsp-fig-circuit.png\" width=\"900px\" /> \n",
"<center> 图 1: 旅行商问题使用的参数化电路 </center>\n",
"\n",
"上述电路会给出一个输出态 $|\\psi(\\vec{\\theta})\\rangle$,由此输出态,我们可以计算最大割问题的目标函数,也就是旅行商问题的损失函数:\n",
"\n", "\n",
"$$\n", "$$\n",
"L(\\vec{\\theta}) = \\langle\\vec{\\theta}|H_C|\\vec{\\theta}\\rangle.\n", "L(\\psi(\\vec{\\theta})) = \\langle\\psi(\\vec{\\theta})|H_C|\\psi(\\vec{\\theta})\\rangle.\n",
"\\tag{6}\n", "\\tag{7}\n",
"$$\n", "$$\n",
"\n", "\n",
"然后我们利用经典的优化算法寻找最优参数 $\\vec{\\theta}^*$。下面的代码给出了通过量桨和飞桨搭建的完整网络:" "然后我们利用经典的优化算法寻找最优参数 $\\vec{\\theta}^*$。下面的代码给出了通过量桨和飞桨搭建的完整网络:"
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 4,
"metadata": { "source": [
"ExecuteTime": { "# 此处使用内置量子电路:complex_entangled_layer()\n",
"end_time": "2021-05-17T08:00:16.258893Z", "def cir_TSP(N, DEPTH, theta):\n",
"start_time": "2021-05-17T08:00:16.241066Z" " cir = UAnsatz(N)\n",
} " cir.complex_entangled_layer(theta, DEPTH)\n",
}, " return cir"
],
"outputs": [], "outputs": [],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 5,
"source": [ "source": [
"class Net(paddle.nn.Layer):\n", "class Opt_TSP(paddle.nn.Layer):\n",
" def __init__(self, g, p, H_ls, dtype=\"float64\",):\n", " def __init__(self, G, DEPTH, H_ls, dtype=\"float64\",):\n",
" super(Net, self).__init__()\n", " # 输入:图G, PQC层数DEPTH, 哈密顿量泡利list形式\n",
" self.p = p\n", " super(Opt_TSP, self).__init__()\n",
" self.theta = self.create_parameter(shape=[self.p, (len(g.nodes) - 1) ** 2, 3],\n", " self.DEPTH = DEPTH\n",
" self.theta = self.create_parameter(shape=[self.DEPTH, (len(G.nodes) - 1) ** 2, 3],\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2 * PI),\n", " default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2 * PI),\n",
" dtype=dtype, is_bias=False)\n", " dtype=dtype, is_bias=False)\n",
" self.H_ls = H_ls\n", " self.H_ls = H_ls\n",
" self.num_qubits = (len(g) - 1) ** 2\n", " self.num_qubits = (len(G) - 1) ** 2 # 总qubit数取为:(城市数-1)**2\n",
"\n", "\n",
" def forward(self):\n", " def forward(self):\n",
" # 定义 complex entangled layer\n", " # 定义 complex entangled layer\n",
" cir = UAnsatz(self.num_qubits)\n", " cir = cir_TSP(self.num_qubits, self.DEPTH, self.theta)\n",
" cir.complex_entangled_layer(self.theta, self.p)\n",
" # 运行该量子电路\n", " # 运行该量子电路\n",
" cir.run_state_vector()\n", " cir.run_state_vector()\n",
" # 计算损失函数\n", " # 计算损失函数\n",
" loss = cir.expecval(self.H_ls)\n", " loss = cir.expecval(self.H_ls)\n",
"\n", "\n",
" return loss, cir" " return loss, cir"
] ],
"outputs": [],
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:00:16.258893Z",
"start_time": "2021-05-17T08:00:16.241066Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"### 训练量子神经网络\n", "### 训练量子神经网络\n",
"\n", "\n",
"定义好了量子神经网络后,我们使用梯度下降的方法来更新其中的参数,使得式(6)的期望值最小。" "定义好了量子神经网络后,我们使用梯度下降的方法来更新其中的参数,使得式(7)的期望值最小。"
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 6,
"source": [
"DEPTH = 2 # 量子电路的层数\n",
"ITR = 120 # 训练迭代的次数\n",
"LR = 0.5 # 基于梯度下降的优化方法的学习率\n",
"SEED = 1000 #设置随机数种子"
],
"outputs": [],
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-17T08:00:16.274144Z", "end_time": "2021-05-17T08:00:16.274144Z",
"start_time": "2021-05-17T08:00:16.264684Z" "start_time": "2021-05-17T08:00:16.264684Z"
} }
}, }
"outputs": [],
"source": [
"p = 2 # 量子电路的层数\n",
"ITR = 120 # 训练迭代的次数\n",
"LR = 0.5 # 基于梯度下降的优化方法的学习率\n",
"SEED = 1000 #设置随机数种子"
]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"这里,我们在飞桨中优化上面定义的网络。" "这里,我们在飞桨中优化上面定义的网络。"
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 7,
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:02:14.495970Z",
"start_time": "2021-05-17T08:00:16.496407Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"循环数: 10 损失: 46.0238\n",
"循环数: 20 损失: 22.6651\n",
"循环数: 30 损失: 16.6195\n",
"循环数: 40 损失: 14.3719\n",
"循环数: 50 损失: 13.5548\n",
"循环数: 60 损失: 13.1736\n",
"循环数: 70 损失: 13.0661\n",
"循环数: 80 损失: 13.0219\n",
"循环数: 90 损失: 13.0035\n",
"循环数: 100 损失: 13.0032\n",
"循环数: 110 损失: 13.0008\n",
"循环数: 120 损失: 13.0004\n"
]
}
],
"source": [ "source": [
"# 固定 paddle 随机种子\n", "# 固定 paddle 随机种子\n",
"paddle.seed(SEED)\n", "paddle.seed(SEED)\n",
"# 记录运行时间\n",
"time_start = time.time()\n",
"\n", "\n",
"net = Net(G, p, H_C_list)\n", "myLayer = Opt_TSP(G, DEPTH, H_C_list)\n",
"# 使用 Adam 优化器\n", "# 使用 Adam 优化器\n",
"opt = paddle.optimizer.Adam(learning_rate=LR, parameters=net.parameters())\n", "opt = paddle.optimizer.Adam(learning_rate=LR, parameters=myLayer.parameters())\n",
"# 梯度下降循环\n", "# 梯度下降循环\n",
"for itr in range(1, ITR + 1):\n", "for itr in range(1, ITR + 1):\n",
" # 运行上面定义的网络\n", " # 运行上面定义的网络\n",
" loss, cir = net()\n", " loss, cir = myLayer()\n",
" # 计算梯度并优化\n", " # 计算梯度并优化\n",
" loss.backward()\n", " loss.backward()\n",
" opt.minimize(loss)\n", " opt.minimize(loss)\n",
" opt.clear_grad()\n", " opt.clear_grad()\n",
" # 输出迭代中performance\n",
" if itr % 10 == 0:\n", " if itr % 10 == 0:\n",
" print(\"循环数:\", itr, \"损失:\", \"%.4f\"% loss.numpy())" " print(\"循环数:\", itr, \"损失:\", \"%.4f\"% loss.numpy(), \"用时:\", time.time()-time_start)\n",
] "\n",
"# 显示QNN得到最小路程\n",
"print('得到最小路程:', loss.numpy())"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"循环数: 10 损失: 46.0232 用时: 5.425132751464844\n",
"循环数: 20 损失: 22.6648 用时: 11.279906749725342\n",
"循环数: 30 损失: 16.6194 用时: 19.115557432174683\n",
"循环数: 40 损失: 14.3719 用时: 26.60259699821472\n",
"循环数: 50 损失: 13.5547 用时: 34.130993127822876\n",
"循环数: 60 损失: 13.1736 用时: 41.717233657836914\n",
"循环数: 70 损失: 13.0661 用时: 50.04284143447876\n",
"循环数: 80 损失: 13.0219 用时: 58.36803317070007\n",
"循环数: 90 损失: 13.0035 用时: 66.84098410606384\n",
"循环数: 100 损失: 13.0032 用时: 75.09722661972046\n",
"循环数: 110 损失: 13.0008 用时: 84.32974600791931\n",
"循环数: 120 损失: 13.0004 用时: 94.5128538608551\n",
"得到最小路程: [13.00038342]\n"
]
}
],
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:02:14.495970Z",
"start_time": "2021-05-17T08:00:16.496407Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"最理想的情况是我们使用的量子神经网络可以找到最短哈密顿回路,同时最后的损失值应该等于这条回路上的权重之和,即旅行商所需要走的最短长度。但如果最后的情况不是这样,读者可以通过调整参数化量子电路的参数值,即 $p$,ITR 和 LR,来获得更好的训练效果。" "最理想的情况是我们使用的量子神经网络可以找到最短哈密顿回路,同时最后的损失值应该等于这条回路上的权重之和,即旅行商所需要走的最短长度。但如果最后的情况不是这样,读者可以通过调整参数化量子电路的参数值,即 DEPTH,ITR 和 LR,来获得更好的训练效果。"
] ],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"### 解码量子答案\n", "### 解码量子答案\n",
"\n", "\n",
"当求得损失函数的最小值以及相对应的一组参数 $\\vec{\\theta}^*$后,我们的任务还没有完成。为了进一步求得旅行商问题的近似解,需要从电路输出的量子态 $|\\vec{\\theta}^*\\rangle$ 中解码出经典优化问题的答案。物理上,解码量子态需要对量子态进行测量,然后统计测量结果的概率分布(我们的测量结果是表示旅行商问题答案的比特串):\n", "当求得损失函数的最小值以及相对应的一组参数 $\\vec{\\theta}^*$后,我们的任务还没有完成。为了进一步求得旅行商问题的近似解,需要从电路输出的量子态 $|\\psi(\\vec{\\theta})^*\\rangle$ 中解码出经典优化问题的答案。物理上,解码量子态需要对量子态进行测量,然后统计测量结果的概率分布(我们的测量结果是表示旅行商问题答案的比特串):\n",
"\n", "\n",
"$$\n", "$$\n",
"p(z) = |\\langle z|\\vec{\\theta}^*\\rangle|^2.\n", "p(z) = |\\langle z|\\psi(\\vec{\\theta})^*\\rangle|^2.\n",
"\\tag{7}\n", "\\tag{8}\n",
"$$\n", "$$\n",
"\n", "\n",
"通常情况下,某个比特串出现的概率越大,意味着其对应旅行商问题最优解的可能性越大。\n", "通常情况下,某个比特串出现的概率越大,意味着其对应旅行商问题最优解的可能性越大。\n",
"\n", "\n",
"量桨提供了查看参数化量子电路输出状态的测量结果概率分布的函数:" "量桨提供了查看参数化量子电路输出状态的测量结果概率分布的函数:"
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 8,
"metadata": { "source": [
"ExecuteTime": { "# 模拟重复测量电路输出态 1024 次\n",
"end_time": "2021-05-17T08:02:14.554317Z", "prob_measure = cir.measure(shots=1024)\n",
"start_time": "2021-05-17T08:02:14.500593Z" "reduced_salesman_walk = max(prob_measure, key=prob_measure.get)\n",
} "print(\"利用改进后的哈密顿量找到的解的比特串形式:\", reduced_salesman_walk)"
}, ],
"outputs": [ "outputs": [
{ {
"name": "stdout",
"output_type": "stream", "output_type": "stream",
"name": "stdout",
"text": [ "text": [
"利用改进后的哈密顿量找到的解的比特串形式: 010001100\n" "利用改进后的哈密顿量找到的解的比特串形式: 010001100\n"
] ]
} }
], ],
"source": [ "metadata": {
"# 模拟重复测量电路输出态 1024 次\n", "ExecuteTime": {
"prob_measure = cir.measure(shots=1024)\n", "end_time": "2021-05-17T08:02:14.554317Z",
"reduced_salesman_walk = max(prob_measure, key=prob_measure.get)\n", "start_time": "2021-05-17T08:02:14.500593Z"
"print(\"利用改进后的哈密顿量找到的解的比特串形式:\", reduced_salesman_walk)" }
] }
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"因为我们之前为了减少所需要的量子比特数改进了一下旅行商问题对应的哈密顿量,上面显示的比特串缺少了顶点 $n-1$ 的信息,以及所有顶点在时间 $t =n-1$ 的时候的信息。所以我们需要将这些信息加回找到的比特串中。\n", "因为我们之前为了减少所需要的量子比特数改进了一下旅行商问题对应的哈密顿量,上面显示的比特串缺少了顶点 $n-1$ 的信息,以及所有顶点在时间 $t =n-1$ 的时候的信息。所以我们需要将这些信息加回找到的比特串中。\n",
"\n", "\n",
"首先为了加上对于 $i \\in [0,n-2]$, $x_{i,n-1} = 0$ 这一信息,我们需要在每 $(n-1)$ 个比特之后加上一个 $0$。接着在比特串的最后,我们为了加上顶点 $n-1$在每个时间的状态,我们加上包含 $n-1$ 个 '0' 的 '00...01',用来表示对于$t \\in [0,n-2]$来说,$x_{n-1,t} = 0$,同时 $x_{n-1,n-1} = 0$。\n", "首先为了加上对于 $i \\in [0,n-2]$, $x_{i,n-1} = 0$ 这一信息,我们需要在每 $(n-1)$ 个比特之后加上一个 $0$。接着在比特串的最后,我们为了加上顶点 $n-1$在每个时间的状态,我们加上包含 $n-1$ 个 '0' 的 '00...01',用来表示对于$t \\in [0,n-2]$来说,$x_{n-1,t} = 0$,同时 $x_{n-1,n-1} = 0$。\n",
"\n", "\n",
"以下代码通过测量,找到了出现几率最高的比特串,每一个比特都包含了式(1)定义的 $x_{i,t}$ 的信息。我们将找到的比特串映射回经典解,即转化成了 ``dictionary`` 的形式。其中 ``key`` 代表顶点编号,``value`` 代表顶点在哈密顿回路中的顺序,即访问城市的顺序。在以下代码中,我们还将量子电路找到的最优解和暴力算法找到的相比较,从而说明量子算法的正确性。" "以下代码通过测量,找到了出现几率最高的比特串,每一个比特都包含了式(1)定义的 $x_{i,t}$ 的信息。我们将找到的比特串映射回经典解,即转化成了 ``dictionary`` 的形式。其中 ``key`` 代表顶点编号,``value`` 代表顶点在哈密顿回路中的顺序,即访问城市的顺序。在以下代码中,我们还将量子电路找到的最优解和暴力算法找到的相比较,从而说明量子算法的正确性。"
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 9,
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:02:14.571954Z",
"start_time": "2021-05-17T08:02:14.559634Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"参数化量子电路找到的最优解: {0: 1, 1: 2, 2: 0, 3: 3} ,最短距离为: 13\n",
"经典暴力算法找到的最优解: {0: 0, 1: 1, 2: 3, 3: 2} ,最短距离为: 13\n"
]
}
],
"source": [ "source": [
"# 参数化量子电路找到的最优解\n", "# 参数化量子电路找到的最优解\n",
"str_by_vertex = [reduced_salesman_walk[i:i + n - 1] for i in range(0, len(reduced_salesman_walk) + 1, n - 1)]\n", "str_by_vertex = [reduced_salesman_walk[i:i + n - 1] for i in range(0, len(reduced_salesman_walk) + 1, n - 1)]\n",
...@@ -413,39 +457,37 @@ ...@@ -413,39 +457,37 @@
"salesman_walk_brute_force, distance_brute_force = solve_tsp_brute_force(G)\n", "salesman_walk_brute_force, distance_brute_force = solve_tsp_brute_force(G)\n",
"solution_brute_force = {i:salesman_walk_brute_force.index(i) for i in range(n)}\n", "solution_brute_force = {i:salesman_walk_brute_force.index(i) for i in range(n)}\n",
"print(\"经典暴力算法找到的最优解:\", solution_brute_force, \",最短距离为:\", distance_brute_force)" "print(\"经典暴力算法找到的最优解:\", solution_brute_force, \",最短距离为:\", distance_brute_force)"
] ],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"参数化量子电路找到的最优解: {0: 1, 1: 2, 2: 0, 3: 3} ,最短距离为: 13\n",
"经典暴力算法找到的最优解: {0: 0, 1: 1, 2: 3, 3: 2} ,最短距离为: 13\n"
]
}
],
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:02:14.571954Z",
"start_time": "2021-05-17T08:02:14.559634Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"以下的代码将字典形式的经典解用图的形式展示了出来:\n", "以下的代码将字典形式的经典解用图的形式展示了出来:\n",
"* 顶点中的第一个数字代表城市编号\n", "* 顶点中的第一个数字代表城市编号\n",
"* 顶点中的第二个数字代表旅行商访问此城市的顺序\n", "* 顶点中的第二个数字代表旅行商访问此城市的顺序\n",
"* 红色的边表示找到的最佳路线" "* 红色的边表示找到的最佳路线"
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 10,
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:02:14.864346Z",
"start_time": "2021-05-17T08:02:14.576418Z"
}
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1080x288 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [ "source": [
"label_dict = {i: str(i) + \", \" + str(t) for i, t in solution.items()}\n", "label_dict = {i: str(i) + \", \" + str(t) for i, t in solution.items()}\n",
"edge_color = [\"red\" if solution[u] == (solution[v] + 1) % n\n", "edge_color = [\"red\" if solution[u] == (solution[v] + 1) % n\n",
...@@ -467,18 +509,35 @@ ...@@ -467,18 +509,35 @@
"nx.drawing.nx_pylab.draw_networkx_edge_labels(G, pos=pos, ax=ax[1], edge_labels=nx.get_edge_attributes(G, 'weight'))\n", "nx.drawing.nx_pylab.draw_networkx_edge_labels(G, pos=pos, ax=ax[1], edge_labels=nx.get_edge_attributes(G, 'weight'))\n",
"plt.axis(\"off\")\n", "plt.axis(\"off\")\n",
"plt.show()" "plt.show()"
] ],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 1080x288 with 2 Axes>"
],
"image/png": "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"
},
"metadata": {}
}
],
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:02:14.864346Z",
"start_time": "2021-05-17T08:02:14.576418Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"上面给出的左图展示了参数化量子电路找到的旅行商问题的最优解,右图展示了经典暴力算法找到的最优解。我们不难看出,即使旅行商访问每个城市的绝对顺序不一样,但路线是一致的,即相对顺序一样。这说明在这个例子中,参数化量子电路找到了旅行商问题的最优解。" "上面给出的左图展示了参数化量子电路找到的旅行商问题的最优解,右图展示了经典暴力算法找到的最优解。我们不难看出,即使旅行商访问每个城市的绝对顺序不一样,但路线是一致的,即相对顺序一样。这说明在这个例子中,参数化量子电路找到了旅行商问题的最优解。"
] ],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## 实际应用\n", "## 实际应用\n",
"\n", "\n",
...@@ -489,11 +548,11 @@ ...@@ -489,11 +548,11 @@
"同时作为最著名的组合优化问题之一,旅行商问题为很多用于解决组合问题的通用算法提供了测试平台。它经常被作为研究者测试他们提出的新的算法的首选例子。\n", "同时作为最著名的组合优化问题之一,旅行商问题为很多用于解决组合问题的通用算法提供了测试平台。它经常被作为研究者测试他们提出的新的算法的首选例子。\n",
"\n", "\n",
"对于旅行商问题更多的应用和解法,详见 [6]。" "对于旅行商问题更多的应用和解法,详见 [6]。"
] ],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"_______\n", "_______\n",
"\n", "\n",
...@@ -510,7 +569,8 @@ ...@@ -510,7 +569,8 @@
"[5] Klanšek, Uroš. \"Using the TSP solution for optimal route scheduling in construction management.\" [Organization, technology & management in construction: an international journal 3.1 (2011): 243-249.](https://www.semanticscholar.org/paper/Using-the-TSP-Solution-for-Optimal-Route-Scheduling-Klansek/3d809f185c03a8e776ac07473c76e9d77654c389)\n", "[5] Klanšek, Uroš. \"Using the TSP solution for optimal route scheduling in construction management.\" [Organization, technology & management in construction: an international journal 3.1 (2011): 243-249.](https://www.semanticscholar.org/paper/Using-the-TSP-Solution-for-Optimal-Route-Scheduling-Klansek/3d809f185c03a8e776ac07473c76e9d77654c389)\n",
"\n", "\n",
"[6] Matai, Rajesh, Surya Prakash Singh, and Murari Lal Mittal. \"Traveling salesman problem: an overview of applications, formulations, and solution approaches.\" [Traveling salesman problem, theory and applications 1 (2010).](https://www.sciencedirect.com/topics/computer-science/traveling-salesman-problem)" "[6] Matai, Rajesh, Surya Prakash Singh, and Murari Lal Mittal. \"Traveling salesman problem: an overview of applications, formulations, and solution approaches.\" [Traveling salesman problem, theory and applications 1 (2010).](https://www.sciencedirect.com/topics/computer-science/traveling-salesman-problem)"
] ],
"metadata": {}
} }
], ],
"metadata": { "metadata": {
...@@ -529,7 +589,7 @@ ...@@ -529,7 +589,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.8" "version": "3.7.11"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
...@@ -547,4 +607,4 @@ ...@@ -547,4 +607,4 @@
}, },
"nbformat": 4, "nbformat": 4,
"nbformat_minor": 4 "nbformat_minor": 4
} }
\ No newline at end of file
...@@ -2,31 +2,59 @@ ...@@ -2,31 +2,59 @@
"cells": [ "cells": [
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"# Travelling Salesman Problem\n", "# Travelling Salesman Problem\n",
"\n", "\n",
"<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>" "<em> Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>"
] ],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## Overview\n", "## Overview\n",
"\n", "\n",
"One of the most famous NP-hard problems in combinatorial optimization, the travelling salesman problem (TSP) considers the following question: \"Given a list of cities and the distances between each pair of cities, what is the shortest possible route that visits each city exactly once and returns to the origin city?\" \n", "One of the most famous NP-hard problems in combinatorial optimization, the travelling salesman problem (TSP) considers the following question: \"Given a list of cities and the distances between each pair of cities, what is the shortest possible route that visits each city exactly once and returns to the origin city?\" \n",
"\n", "\n",
"This question can also be formulated in the language of graph theory. Given a weighted undirected complete graph $G = (V,E)$, where each vertex $i \\in V$ corresponds to city $i$ and the weight $w_{i,j}$ of each edge $(i,j,w_{i,j}) \\in E$ represents the distance between cities $i$ and $j$, the TSP is to find the shortest Hamiltonian cycle in $G$, where a Hamiltonian cycle is a closed loop on a graph in which every vertex is visited exactly once. Note that because $G$ is an undirected graph, weights are symmetric, i.e., $w_{i,j} = w_{j,i}$. " "This question can also be formulated in the language of graph theory. Given a weighted undirected complete graph $G = (V,E)$, where each vertex $i \\in V$ corresponds to city $i$ and the weight $w_{i,j}$ of each edge $(i,j,w_{i,j}) \\in E$ represents the distance between cities $i$ and $j$, the TSP is to find the shortest Hamiltonian cycle in $G$, where a Hamiltonian cycle is a closed loop on a graph in which every vertex is visited exactly once. Note that because $G$ is an undirected graph, weights are symmetric, i.e., $w_{i,j} = w_{j,i}$. "
] ],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"## Use QNN to solve TSP\n",
"\n",
"To use QNN to solve travelling salesman problem, we need to first encode the classical problem to quantum. \n",
"The encoding consists of two parts:\n",
"\n",
"1. The route how the salesman visits each city is encoded in quantum states -- ${\\rm qubit}_{i,t} = |1\\rangle$ corresponds to salesman visiting city $i$ at time $t$. \n",
" 1. As an example, if there are two cities $\\{A,B\\}$, visiting $A$ then $B$ will be in state $|1001\\rangle$, as the salesman visits the city $A$ at time $1$ and the city $B$ at time $2$.\n",
" 2. Similary, $|0110\\rangle$ means visiting $B$ then $A$.\n",
" 3. Note: $|0101\\rangle$ means visiting $A$ and $B$ both at time $2$, so it is infeasible. To aviod such states, a penalty function will be used (see the next section for details.)\n",
"\n",
"2. The total distance is encoded in a loss function: \n",
"\n",
"$$\n",
"L(\\psi(\\vec{\\theta})) = \\langle\\psi(\\vec{\\theta})|H_C|\\psi(\\vec{\\theta})\\rangle,\n",
"\\tag{1}\n",
"$$\n",
"\n",
"where $|\\psi(\\vec{\\theta})\\rangle$ is the output state from a parameterized quantum circuit. \n",
"\n",
"The details about how to encode the classical problem to quantum is given in detail in the next section. \n",
"After optimizing the loss function, we will obtain the optimal quantum state. Then a decoding process will be performed to get the final route."
],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## Encoding the TSP\n", "### Encoding the TSP\n",
"\n", "\n",
"To transform the TSP into a problem applicable for parameterized quantum circuits, we need to encode the TSP into a Hamiltonian. We realize the encoding by first constructing an integer programming problem. Suppose there are $n=|V|$ vertices in graph $G$. Then for each vertex $i \\in V$, we define $n$ binary variables $x_{i,t}$, where $t \\in [0,n-1]$, such that\n", "To transform the TSP into a problem applicable for parameterized quantum circuits, we need to encode the TSP into a Hamiltonian. \n",
"\n",
"We realize the encoding by first constructing an integer programming problem. Suppose there are $n=|V|$ vertices in graph $G$. Then for each vertex $i \\in V$, we define $n$ binary variables $x_{i,t}$, where $t \\in [0,n-1]$, such that\n",
"\n", "\n",
"$$\n", "$$\n",
"x_{i, t}=\n", "x_{i, t}=\n",
...@@ -34,28 +62,28 @@ ...@@ -34,28 +62,28 @@
"1, & \\text {if in the resulting Hamiltonian cycle, vertex } i \\text { is visited at time } t\\\\\n", "1, & \\text {if in the resulting Hamiltonian cycle, vertex } i \\text { is visited at time } t\\\\\n",
"0, & \\text{otherwise}\n", "0, & \\text{otherwise}\n",
"\\end{cases}.\n", "\\end{cases}.\n",
"\\tag{1}\n", "\\tag{2}\n",
"$$\n", "$$\n",
"\n", "\n",
"As there are $n$ vertices, we have $n^2$ variables in total, whose value we denote by a bit string $x=x_{1,1}x_{1,2}\\dots x_{n,n}$. Assume for now that the bit string $x$ represents a Hamiltonian cycle. Then for each edge $(i,j,w_{i,j}) \\in E$, we will have $x_{i,t} = x_{j,t+1}=1$, i.e., $x_{i,t}\\cdot x_{j,t+1}=1$, if and only if the Hamiltonian cycle visits vertex $i$ at time $t$ and vertex $j$ at time $t+1$; otherwise, $x_{i,t}\\cdot x_{j,t+1}$ will be $0$. Therefore the length of a Hamiltonian cycle is\n", "As there are $n$ vertices, we have $n^2$ variables in total, whose value we denote by a bit string $x=x_{1,1}x_{1,2}\\dots x_{n,n}$. Assume for now that the bit string $x$ represents a Hamiltonian cycle. Then for each edge $(i,j,w_{i,j}) \\in E$, we will have $x_{i,t} = x_{j,t+1}=1$, i.e., $x_{i,t}\\cdot x_{j,t+1}=1$, if and only if the Hamiltonian cycle visits vertex $i$ at time $t$ and vertex $j$ at time $t+1$; otherwise, $x_{i,t}\\cdot x_{j,t+1}$ will be $0$. Therefore the length of a Hamiltonian cycle is\n",
"\n", "\n",
"$$\n", "$$\n",
"D(x) = \\sum_{i,j} w_{i,j} \\sum_{t} x_{i,t} x_{j,t+1}.\n", "D(x) = \\sum_{i,j} w_{i,j} \\sum_{t} x_{i,t} x_{j,t+1}.\n",
"\\tag{2}\n", "\\tag{3}\n",
"$$\n", "$$\n",
"\n", "\n",
"For $x$ to represent a valid Hamiltonian cycle, the following constraint needs to be met:\n", "For $x$ to represent a valid Hamiltonian cycle, the following constraint needs to be met:\n",
"\n", "\n",
"$$\n", "$$\n",
"\\sum_t x_{i,t} = 1 \\quad \\forall i \\in [0,n-1] \\quad \\text{ and } \\quad \\sum_i x_{i,t} = 1 \\quad \\forall t \\in [0,n-1],\n", "\\sum_t x_{i,t} = 1 \\quad \\forall i \\in [0,n-1] \\quad \\text{ and } \\quad \\sum_i x_{i,t} = 1 \\quad \\forall t \\in [0,n-1],\n",
"\\tag{3}\n", "\\tag{4}\n",
"$$\n", "$$\n",
"\n", "\n",
"where the first equation guarantees that each vertex is only visited once and the second guarantees that only one vertex is visited at each time $t$. Then the cost function under the constraint can be formulated below, with $A$ being the penalty parameter set to ensure that the constraint is satisfied:\n", "where the first equation guarantees that each vertex is only visited once and the second guarantees that only one vertex is visited at each time $t$. Then the cost function under the constraint can be formulated below, with $A$ being the penalty parameter set to ensure that the constraint is satisfied:\n",
"\n", "\n",
"$$\n", "$$\n",
"C(x) = D(x)+ A\\left( \\sum_{i} \\left(1-\\sum_t x_{i,t}\\right)^2 + \\sum_{t} \\left(1-\\sum_i x_{i,t}\\right)^2 \\right).\n", "C(x) = D(x)+ A\\left( \\sum_{i} \\left(1-\\sum_t x_{i,t}\\right)^2 + \\sum_{t} \\left(1-\\sum_i x_{i,t}\\right)^2 \\right).\n",
"\\tag{4}\n", "\\tag{5}\n",
"$$\n", "$$\n",
"\n", "\n",
"Note that as we would like to minimize the length $D(x)$ while ensuring $x$ represents a valid Hamiltonian cycle, we had better set $A$ large, at least larger than the largest weight of edges.\n", "Note that as we would like to minimize the length $D(x)$ while ensuring $x$ represents a valid Hamiltonian cycle, we had better set $A$ large, at least larger than the largest weight of edges.\n",
...@@ -65,80 +93,75 @@ ...@@ -65,80 +93,75 @@
"Now we would like to consider the mapping\n", "Now we would like to consider the mapping\n",
"\n", "\n",
"$$\n", "$$\n",
"x_{i,t} \\mapsto \\frac{I-Z_{i,t}}{2}, \\tag{5}\n", "x_{i,t} \\mapsto \\frac{I-Z_{i,t}}{2}, \\tag{6}\n",
"$$\n", "$$\n",
"\n", "\n",
"where $Z_{i,t} = I \\otimes I \\otimes \\ldots \\otimes Z \\otimes \\ldots \\otimes I$ with $Z$ operates on the qubit at position $(i,t)$. Under this mapping, if a qubit $(i,t)$ is in state $|1\\rangle$, then $x_{i,t}|1\\rangle = \\frac{I-Z_{i,t}}{2} |1\\rangle = 1 |1\\rangle$, which means vertex $i$ is visited at time $t$. Also, for a qubit $(i,t)$ in state $|0\\rangle$, $x_{i,t} |0\\rangle= \\frac{I-Z_{i,t}}{2} |0\\rangle = 0|0\\rangle$.\n", "where $Z_{i,t} = I \\otimes I \\otimes \\ldots \\otimes Z \\otimes \\ldots \\otimes I$ with $Z$ operates on the qubit at position $(i,t)$. Under this mapping, if a qubit $(i,t)$ is in state $|1\\rangle$, then $x_{i,t}|1\\rangle = \\frac{I-Z_{i,t}}{2} |1\\rangle = 1 |1\\rangle$, which means vertex $i$ is visited at time $t$. Also, for a qubit $(i,t)$ in state $|0\\rangle$, $x_{i,t} |0\\rangle= \\frac{I-Z_{i,t}}{2} |0\\rangle = 0|0\\rangle$.\n",
"\n", "\n",
"Thus using the above mapping, we can transform the cost function $C(x)$ into a Hamiltonian $H_C$ for the system of $n^2$ qubits and realize the quantumization of the TSP. Then the ground state of $H_C$ is the optimal solution to the TSP. In the following section, we will show how to use a parametrized quantum circuit to find the ground state, i.e., the eigenvector with the smallest eigenvalue.\n", "Thus using the above mapping, we can transform the cost function $C(x)$ into a Hamiltonian $H_C$ for the system of $n^2$ qubits and realize the quantumization of the TSP. Then the ground state of $H_C$ is the optimal solution to the TSP. In the following section, we will show how to use a parametrized quantum circuit to find the ground state, i.e., the eigenvector with the smallest eigenvalue.\n",
"\n" "\n"
] ],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## Paddle Quantum Implementation\n", "## Paddle Quantum Implementation\n",
"\n", "\n",
"To investigate the TSP using Paddle Quantum, there are some required packages to import, which are shown below. The ``networkx`` package is the tool to handle graphs." "To investigate the TSP using Paddle Quantum, there are some required packages to import, which are shown below. The ``networkx`` package is the tool to handle graphs."
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": 1,
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:24:17.197426Z",
"start_time": "2021-05-17T08:24:12.896488Z"
}
},
"outputs": [],
"source": [ "source": [
"# Import related modules from Paddle Quantum and PaddlePaddle\n", "# Import related modules from Paddle Quantum and PaddlePaddle\n",
"import paddle\n", "import paddle\n",
"from paddle_quantum.circuit import UAnsatz\n", "from paddle_quantum.circuit import UAnsatz\n",
"from paddle_quantum.QAOA.tsp import tsp_hamiltonian\n", "\n",
"from paddle_quantum.QAOA.tsp import solve_tsp_brute_force\n", "# Functions for Salesman Problem\n",
"from paddle_quantum.QAOA.tsp import tsp_hamiltonian # Get the Hamiltonian for salesman problem\n",
"from paddle_quantum.QAOA.tsp import solve_tsp_brute_force # Solve the salesman problem by brute force\n",
"\n",
"# Create Graph\n",
"import networkx as nx\n",
"\n", "\n",
"# Import additional packages needed\n", "# Import additional packages needed\n",
"from numpy import pi as PI\n", "from numpy import pi as PI\n",
"import matplotlib.pyplot as plt\n", "import matplotlib.pyplot as plt\n",
"import networkx as nx\n", "import random\n",
"import random" "import time"
] ],
"outputs": [],
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:24:17.197426Z",
"start_time": "2021-05-17T08:24:12.896488Z"
}
}
},
{
"cell_type": "markdown",
"source": [
"### Generate a weighted complete graph"
],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"Next, we generate a weighted complete graph $G$ with four vertices. For the convenience of computation, the vertices here are labeled starting from $0$." "Next, we generate a weighted complete graph $G$ with four vertices. For the convenience of computation, the vertices here are labeled starting from $0$."
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 2,
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:24:24.302458Z",
"start_time": "2021-05-17T08:24:24.060967Z"
}
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [ "source": [
"# n is the number of vertices in the graph G\n", "# n is the number of vertices in the graph G\n",
"n = 4\n", "n = 4\n",
"E = [(0, 1, 3), (0, 2, 2), (0, 3, 10), (1, 2, 6), (1, 3, 2), (2, 3, 6)]\n", "E = [(0, 1, 3), (0, 2, 2), (0, 3, 10), (1, 2, 6), (1, 3, 2), (2, 3, 6)] # Parameters for edges: (vertex1, vertex2, weight(distance))\n",
"G = nx.Graph()\n", "G = nx.Graph()\n",
"G.add_weighted_edges_from(E)\n", "G.add_weighted_edges_from(E)\n",
"\n", "\n",
...@@ -157,220 +180,259 @@ ...@@ -157,220 +180,259 @@
"ax.margins(0.20)\n", "ax.margins(0.20)\n",
"plt.axis(\"off\")\n", "plt.axis(\"off\")\n",
"plt.show()" "plt.show()"
] ],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
],
"image/png": "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"
},
"metadata": {}
}
],
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:24:24.302458Z",
"start_time": "2021-05-17T08:24:24.060967Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"### Encoding Hamiltonian\n", "### Encoding Hamiltonian\n",
"\n", "\n",
"In Paddle Quantum, a Hamiltonian can be input in the form of ``list``. Here we construct the Hamiltonian $H_C$ of Eq. (4) with the replacement in Eq. (5). \n", "In Paddle Quantum, a Hamiltonian can be input in the form of ``list``. Here we construct the Hamiltonian $H_C$ of Eq. (4) with the replacement in Eq. (5). It can be realized with a build-in function \"tsp_hamiltonian(G, A, n)\".\n",
"\n", "\n",
"To save the number of qubits needed, we observe the following fact: it is clear that vertex $n-1$ must always be included in the Hamiltonian cycle, and without loss of generality, we can set $x_{n-1,t} = \\delta_{n-1,t}$ for all $t$ and $x_{i,n-1} = \\delta_{i,n-1}$ for all $i$. **This just means that the overall ordering of the cycle is chosen so that vertex $n-1$ comes last.** This reduces the number of qubits to $(n-1)^2$. We adopt this slight modification of the TSP Hamiltonian in our implementation." "**Note:** For the salesman problem, the number of qubits can be reduced to $(n-1)^2$ since we can always select city $0$ to be the first city."
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 3,
"source": [
"# Construct the Hamiltonian H_C in the form of list -- with build-in function tsp_hamiltonian(G, A, n)\n",
"A = 20 # Penalty parameter\n",
"H_C_list = tsp_hamiltonian(G, A, n)"
],
"outputs": [],
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-17T08:24:25.956145Z", "end_time": "2021-05-17T08:24:25.956145Z",
"start_time": "2021-05-17T08:24:25.950463Z" "start_time": "2021-05-17T08:24:25.950463Z"
} }
}, }
"outputs": [],
"source": [
"# Construct the Hamiltonian H_C in the form of list\n",
"A = 20 # Penalty parameter\n",
"H_C_list = tsp_hamiltonian(G, A, n)"
]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"### Calculating the loss function \n", "### Calculating the loss function \n",
"\n", "\n",
"In the [Max-Cut tutorial](./MAXCUT_EN.ipynb), we use a circuit given by QAOA to find the ground state, but we can also use other circuits to solve combinatorial optimization problems. For the TSP, we adopt a parametrized quantum circuit constructed by $U_3(\\vec{\\theta})$ and $\\text{CNOT}$ gates, which we call the [`complex entangled layer`](https://qml.baidu.com/api/paddle_quantum.circuit.uansatz.html).\n", "In the [Max-Cut tutorial](./MAXCUT_EN.ipynb), we use a circuit given by QAOA to find the ground state, but we can also use other circuits to solve combinatorial optimization problems. For the TSP, we adopt a parametrized quantum circuit constructed by $U_3(\\vec{\\theta})$ and $\\text{CNOT}$ gates, which we call the [`complex entangled layer`](https://qml.baidu.com/api/paddle_quantum.circuit.uansatz.html).\n",
"\n", "\n",
"After running the quantum circuit, we ontain the output circuit $|\\vec{\\theta}\\rangle$. From the output state of the circuit we can calculate the objective function, and also the loss function of the TSP:\n", "<img src=\"./figures/tsp-fig-circuit.png\" width=\"900px\" /> \n",
"<center> Figure 1: Parametrized Quantum Circuit used for TSM Problem </center>\n",
"\n",
"After running the quantum circuit, we obtain the output state $|\\psi(\\vec{\\theta})\\rangle$. From the output state of the circuit we can calculate the objective function, and also the loss function of the TSP:\n",
"\n", "\n",
"$$\n", "$$\n",
"L(\\vec{\\theta}) = \\langle\\vec{\\theta}|H_C|\\vec{\\theta}\\rangle.\n", "L(\\psi(\\vec{\\theta})) = \\langle\\psi(\\vec{\\theta})|H_C|\\psi(\\vec{\\theta})\\rangle.\n",
"\\tag{6}\n", "\\tag{7}\n",
"$$\n", "$$\n",
"\n", "\n",
"We then use a classical optimization algorithm to minimize this function and find the optimal parameters $\\vec{\\theta}^*$. The following code shows a complete network built with Paddle Quantum and PaddlePaddle." "We then use a classical optimization algorithm to minimize this function and find the optimal parameters $\\vec{\\theta}^*$. The following code shows a complete network built with Paddle Quantum and PaddlePaddle."
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 4,
"metadata": { "source": [
"ExecuteTime": { "# In this tutorial we use build-in PQC: complex_entangled_layer()\n",
"end_time": "2021-05-17T08:24:26.790290Z", "def cir_TSP(N, DEPTH, theta):\n",
"start_time": "2021-05-17T08:24:26.768068Z" " cir = UAnsatz(N)\n",
} " cir.complex_entangled_layer(theta, DEPTH)\n",
}, " return cir"
],
"outputs": [], "outputs": [],
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 5,
"source": [ "source": [
"class Net(paddle.nn.Layer):\n", "class Opt_TSP(paddle.nn.Layer):\n",
" def __init__(self, g, p, H_ls, dtype=\"float64\",):\n", " def __init__(self, G, DEPTH, H_ls, dtype=\"float64\",):\n",
" super(Net, self).__init__()\n", " # Input: Graph, G; PQC Layer number, DEPTH; Hamiltonian in Pauli list form, H_ls\n",
" self.p = p\n", " super(Opt_TSP, self).__init__()\n",
" self.theta = self.create_parameter(shape=[self.p, (len(g.nodes) - 1) ** 2, 3],\n", " self.DEPTH = DEPTH\n",
" self.theta = self.create_parameter(shape=[self.DEPTH, (len(G.nodes) - 1) ** 2, 3],\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2 * PI),\n", " default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2 * PI),\n",
" dtype=dtype, is_bias=False)\n", " dtype=dtype, is_bias=False)\n",
" self.H_ls = H_ls\n", " self.H_ls = H_ls\n",
" self.num_qubits = (len(g) - 1) ** 2\n", " self.num_qubits = (len(G) - 1) ** 2 # Total qubits number: (city number-1)**2\n",
"\n", "\n",
" def forward(self):\n", " def forward(self):\n",
" # Define a circuit with complex entangled layers\n", " # Define a circuit with complex entangled layers\n",
" cir = UAnsatz(self.num_qubits)\n", " cir = cir_TSP(self.num_qubits, self.DEPTH, self.theta)\n",
" cir.complex_entangled_layer(self.theta, self.p)\n",
" # Run the quantum circuit\n", " # Run the quantum circuit\n",
" cir.run_state_vector()\n", " cir.run_state_vector()\n",
" # Calculate the loss function\n", " # Calculate the loss function\n",
" loss = cir.expecval(self.H_ls)\n", " loss = cir.expecval(self.H_ls)\n",
"\n", "\n",
" return loss, cir" " return loss, cir"
] ],
"outputs": [],
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:24:26.790290Z",
"start_time": "2021-05-17T08:24:26.768068Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"### Training the quantum neural network\n", "### Training the quantum neural network\n",
"\n", "\n",
"After defining the quantum neural network, we use gradient descent method to update the parameters to minimize the expectation value in Eq. (6). " "After defining the quantum neural network, we use gradient descent method to update the parameters to minimize the expectation value in Eq. (7). "
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 6,
"source": [
"DEPTH = 2 # Number of layers in the quantum circuit\n",
"ITR = 120 # Number of training iterations\n",
"LR = 0.5 # Learning rate of the optimization method based on gradient descent\n",
"SEED = 1000 # Set a global RNG seed "
],
"outputs": [],
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-05-17T08:24:27.958085Z", "end_time": "2021-05-17T08:24:27.958085Z",
"start_time": "2021-05-17T08:24:27.952965Z" "start_time": "2021-05-17T08:24:27.952965Z"
} }
}, }
"outputs": [],
"source": [
"p = 2 # Number of layers in the quantum circuit\n",
"ITR = 120 # Number of training iterations\n",
"LR = 0.5 # Learning rate of the optimization method based on gradient descent\n",
"SEED = 1000 # Set a global RNG seed "
]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"Here, we optimize the network defined above in PaddlePaddle." "Here, we optimize the network defined above in PaddlePaddle."
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 7,
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:26:08.098742Z",
"start_time": "2021-05-17T08:24:28.741155Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"iter: 10 loss: 46.0238\n",
"iter: 20 loss: 22.6651\n",
"iter: 30 loss: 16.6195\n",
"iter: 40 loss: 14.3719\n",
"iter: 50 loss: 13.5548\n",
"iter: 60 loss: 13.1736\n",
"iter: 70 loss: 13.0661\n",
"iter: 80 loss: 13.0219\n",
"iter: 90 loss: 13.0035\n",
"iter: 100 loss: 13.0032\n",
"iter: 110 loss: 13.0008\n",
"iter: 120 loss: 13.0004\n"
]
}
],
"source": [ "source": [
"# Fix paddle random seed\n", "# Fix paddle random seed\n",
"paddle.seed(SEED)\n", "paddle.seed(SEED)\n",
"# Record run time\n",
"time_start = time.time()\n",
"\n", "\n",
"net = Net(G, p, H_C_list)\n", "myLayer = Opt_TSP(G, DEPTH, H_C_list)\n",
"# Use Adam optimizer\n", "# Use Adam optimizer\n",
"opt = paddle.optimizer.Adam(learning_rate=LR, parameters=net.parameters())\n", "opt = paddle.optimizer.Adam(learning_rate=LR, parameters=myLayer.parameters())\n",
"# Gradient descent iteration\n", "# Gradient descent iteration\n",
"for itr in range(1, ITR + 1):\n", "for itr in range(1, ITR + 1):\n",
" # Run the network defined above\n", " # Run the network defined above\n",
" loss, cir = net()\n", " loss, cir = myLayer()\n",
" # Calculate the gradient and optimize\n", " # Calculate the gradient and optimize\n",
" loss.backward()\n", " loss.backward()\n",
" opt.minimize(loss)\n", " opt.minimize(loss)\n",
" opt.clear_grad()\n", " opt.clear_grad()\n",
" if itr % 10 == 0:\n", " if itr % 10 == 0:\n",
" print(\"iter:\", itr, \" loss:\", \"%.4f\"% loss.numpy())" " print(\"iter:\", itr, \" loss:\", \"%.4f\"% loss.numpy(), \"run time:\", time.time()-time_start)\n",
] " \n",
"# The final minimum distance from QNN\n",
"print('The final minimum distance from QNN:', loss.numpy())"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"iter: 10 loss: 46.0232 run time: 7.641107082366943\n",
"iter: 20 loss: 22.6648 run time: 15.020977258682251\n",
"iter: 30 loss: 16.6194 run time: 22.464542627334595\n",
"iter: 40 loss: 14.3719 run time: 30.163496732711792\n",
"iter: 50 loss: 13.5547 run time: 38.4432737827301\n",
"iter: 60 loss: 13.1736 run time: 46.77324390411377\n",
"iter: 70 loss: 13.0661 run time: 55.22942876815796\n",
"iter: 80 loss: 13.0219 run time: 63.490843057632446\n",
"iter: 90 loss: 13.0035 run time: 72.72753691673279\n",
"iter: 100 loss: 13.0032 run time: 82.62676620483398\n",
"iter: 110 loss: 13.0008 run time: 91.19076180458069\n",
"iter: 120 loss: 13.0004 run time: 99.36567878723145\n",
"The final minimum distance from QNN: [13.00038342]\n"
]
}
],
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:26:08.098742Z",
"start_time": "2021-05-17T08:24:28.741155Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"Note that ideally the training network will find the shortest Hamiltonian cycle, and the final loss above would correspond to the total weights of the optimal cycle, i.e. the distance of the optimal path for the salesman. If not, then one should adjust parameters of the parameterized quantum circuits above for better training performance." "Note that ideally the training network will find the shortest Hamiltonian cycle, and the final loss above would correspond to the total weights of the optimal cycle, i.e. the distance of the optimal path for the salesman. If not, then one should adjust parameters of the parameterized quantum circuits above for better training performance."
] ],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"### Decoding the quantum solution\n", "### Decoding the quantum solution\n",
"\n", "\n",
"After obtaining the minimum value of the loss function and the corresponding set of parameters $\\vec{\\theta}^*$, our task has not been completed. In order to obtain an approximate solution to the TSP, it is necessary to decode the solution to the classical optimization problem from the quantum state $|\\vec{\\theta}^*\\rangle$ output by the circuit. Physically, to decode a quantum state, we need to measure it and then calculate the probability distribution of the measurement results, where a measurement result is a bit string that represents an answer for the TSP: \n", "After obtaining the minimum value of the loss function and the corresponding set of parameters $\\vec{\\theta}^*$, our task has not been completed. In order to obtain an approximate solution to the TSP, it is necessary to decode the solution to the classical optimization problem from the quantum state $|\\psi(\\vec{\\theta})^*\\rangle$ output by the circuit. Physically, to decode a quantum state, we need to measure it and then calculate the probability distribution of the measurement results, where a measurement result is a bit string that represents an answer for the TSP: \n",
"\n", "\n",
"$$\n", "$$\n",
"p(z) = |\\langle z|\\vec{\\theta}^*\\rangle|^2.\n", "p(z) = |\\langle z|\\psi(\\vec{\\theta})^*\\rangle|^2.\n",
"\\tag{7}\n", "\\tag{8}\n",
"$$\n", "$$\n",
"\n", "\n",
"Usually, the greater the probability of a certain bit string, the greater the probability that it corresponds to an optimal solution of the TSP.\n", "Usually, the greater the probability of a certain bit string, the greater the probability that it corresponds to an optimal solution of the TSP.\n",
"\n", "\n",
"Paddle Quantum provides a function to read the probability distribution of the measurement results of the state output by the quantum circuit:" "Paddle Quantum provides a function to read the probability distribution of the measurement results of the state output by the quantum circuit:"
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 8,
"metadata": { "source": [
"ExecuteTime": { "# Repeat the simulated measurement of the circuit output state 1024 times\n",
"end_time": "2021-05-17T08:26:08.152206Z", "prob_measure = cir.measure(shots=1024)\n",
"start_time": "2021-05-17T08:26:08.103516Z" "reduced_salesman_walk = max(prob_measure, key=prob_measure.get)\n",
} "print(\"The reduced bit string form of the walk found:\", reduced_salesman_walk)"
}, ],
"outputs": [ "outputs": [
{ {
"name": "stdout",
"output_type": "stream", "output_type": "stream",
"name": "stdout",
"text": [ "text": [
"The reduced bit string form of the walk found: 010001100\n" "The reduced bit string form of the walk found: 010001100\n"
] ]
} }
], ],
"source": [ "metadata": {
"# Repeat the simulated measurement of the circuit output state 1024 times\n", "ExecuteTime": {
"prob_measure = cir.measure(shots=1024)\n", "end_time": "2021-05-17T08:26:08.152206Z",
"reduced_salesman_walk = max(prob_measure, key=prob_measure.get)\n", "start_time": "2021-05-17T08:26:08.103516Z"
"print(\"The reduced bit string form of the walk found:\", reduced_salesman_walk)" }
] }
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"As we have slightly modified the TSP Hamiltonian to reduce the number of qubits used, the bit string found above has lost the information for our fixed vertex $n-1$ and the status of other vertices at time $n-1$. So we need to extend the found bit string to include these information.\n", "As we have slightly modified the TSP Hamiltonian to reduce the number of qubits used, the bit string found above has lost the information for our fixed vertex $n-1$ and the status of other vertices at time $n-1$. So we need to extend the found bit string to include these information.\n",
"\n", "\n",
...@@ -379,27 +441,12 @@ ...@@ -379,27 +441,12 @@
"After measurement, we have found the bit string with the highest probability of occurrence, the optimal walk in the form of the bit string. Each qubit contains the information of $x_{i,t}$ defined in Eq. (1). The following code maps the bit string back to the classic solution in the form of `dictionary`, where the `key` represents the vertex labeling and the `value` represents its order, i.e. when it is visited. \n", "After measurement, we have found the bit string with the highest probability of occurrence, the optimal walk in the form of the bit string. Each qubit contains the information of $x_{i,t}$ defined in Eq. (1). The following code maps the bit string back to the classic solution in the form of `dictionary`, where the `key` represents the vertex labeling and the `value` represents its order, i.e. when it is visited. \n",
"\n", "\n",
"Also, we have compared it with the solution found by the brute-force algorithm, to verify the correctness of the quantum algorithm." "Also, we have compared it with the solution found by the brute-force algorithm, to verify the correctness of the quantum algorithm."
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 9,
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:26:08.169372Z",
"start_time": "2021-05-17T08:26:08.156656Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The walk found by parameterized quantum circuit: {0: 1, 1: 2, 2: 0, 3: 3} with distance 13\n",
"The walk found by the brute-force algorithm: {0: 0, 1: 1, 2: 3, 3: 2} with distance 13\n"
]
}
],
"source": [ "source": [
"# Optimal walk found by parameterized quantum circuit\n", "# Optimal walk found by parameterized quantum circuit\n",
"str_by_vertex = [reduced_salesman_walk[i:i + n - 1] for i in range(0, len(reduced_salesman_walk) + 1, n - 1)]\n", "str_by_vertex = [reduced_salesman_walk[i:i + n - 1] for i in range(0, len(reduced_salesman_walk) + 1, n - 1)]\n",
...@@ -414,39 +461,37 @@ ...@@ -414,39 +461,37 @@
"salesman_walk_brute_force, distance_brute_force = solve_tsp_brute_force(G)\n", "salesman_walk_brute_force, distance_brute_force = solve_tsp_brute_force(G)\n",
"solution_brute_force = {i:salesman_walk_brute_force.index(i) for i in range(n)}\n", "solution_brute_force = {i:salesman_walk_brute_force.index(i) for i in range(n)}\n",
"print(\"The walk found by the brute-force algorithm:\", solution_brute_force, \"with distance\", distance_brute_force)" "print(\"The walk found by the brute-force algorithm:\", solution_brute_force, \"with distance\", distance_brute_force)"
] ],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"The walk found by parameterized quantum circuit: {0: 1, 1: 2, 2: 0, 3: 3} with distance 13\n",
"The walk found by the brute-force algorithm: {0: 0, 1: 1, 2: 3, 3: 2} with distance 13\n"
]
}
],
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:26:08.169372Z",
"start_time": "2021-05-17T08:26:08.156656Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"Here, we draw the corresponding optimal walk in the form of graph representation suggested to the salesman:\n", "Here, we draw the corresponding optimal walk in the form of graph representation suggested to the salesman:\n",
"* The first number in the vertex represents the city number.\n", "* The first number in the vertex represents the city number.\n",
"* The second number in the vertex represents the order the salesman visits the corresponding city.\n", "* The second number in the vertex represents the order the salesman visits the corresponding city.\n",
"* The red edges represent the found optimal route for the salesman." "* The red edges represent the found optimal route for the salesman."
] ],
"metadata": {}
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 10,
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:26:08.431841Z",
"start_time": "2021-05-17T08:26:08.172882Z"
}
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1080x288 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [ "source": [
"label_dict = {i: str(i) + \", \" + str(t) for i, t in solution.items()}\n", "label_dict = {i: str(i) + \", \" + str(t) for i, t in solution.items()}\n",
"edge_color = [\"red\" if solution[u] == (solution[v] + 1) % n\n", "edge_color = [\"red\" if solution[u] == (solution[v] + 1) % n\n",
...@@ -468,18 +513,35 @@ ...@@ -468,18 +513,35 @@
"nx.drawing.nx_pylab.draw_networkx_edge_labels(G, pos=pos, ax=ax[1], edge_labels=nx.get_edge_attributes(G, 'weight'))\n", "nx.drawing.nx_pylab.draw_networkx_edge_labels(G, pos=pos, ax=ax[1], edge_labels=nx.get_edge_attributes(G, 'weight'))\n",
"plt.axis(\"off\")\n", "plt.axis(\"off\")\n",
"plt.show()" "plt.show()"
] ],
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 1080x288 with 2 Axes>"
],
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA1MAAADnCAYAAAD7CwxiAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAABgVklEQVR4nO3dd3iTZfcH8O+T0TTdtKUMKZTWMsoUqCBLxQniZiivOPiJuFBRHKgoiAgqoqiooOLA8QooDl5xgSIupuwWChQos4XSlu6meX5/HEoLdCRpmudJ8v1clxe00uRmNCfnvs99jqKqqgoiIiIiIiJyikHrBRAREREREXkjJlNEREREREQuYDJFRERERETkAiZTRERERERELmAyRURERERE5AImU0RERERERC5gMkVEREREROQCJlNEREREREQuYDJFRERERETkAiZTRERERERELmAyRURERERE5AImU0RERERERC5gMkVEREREROQCk9YLICJqaHa7ir3ZhUg/mo/iMjvKyu0wGw0INBvQOjoErSKDYDAoWi+TiIjIoxgf64/JFBH5HLtdxZ+7jmJ5aibW7MlGWmY+DIoCk0GBChWqCigKoECBza7CrqpIjAlBclwkBrSLQZ+EaAYPIiLyOYyP7qeoqqpqvQgiInfILSrDgrUZeHflbhSU2FBYWg5nXuAUAEEBRgRbTBjdLx7DesQi3GpuqOUSERF5BONjw2EyRURer6i0HNOWpuCLtRlQFKC4zF7vx7SaDbCrwPAesZgwsD2sAUY3rJSIiMhzGB8bHpMpIvJqq9Ozcf/n65FXVIZiW/2DxJkCTQaEWc2YPaIbkuMi3f74REREDYHx0TOYTBGRVyqxlWPKkm1YtH6/W3ba6hJoNmBItxaYODgJFpN/78IREZF+MT56FpMpIvI6BSU23PL+KqQcymuQ3baaBJoMSGoehvmjeiLYwv49RESkL4yPnsdkioi8SkGJDUPm/IXdWQUo8WCgqGAxGRDfOBiLxvT2u4BBRET6xfioDQ7tJSKvUWIrxy3vr9IsUMga7NidVYCR81ahxFauyRqIiIiqYnzUDpMpIvIaU5ZsQ8qhPM0CRYUSmx3bDuZhypIUTddBREQEMD5qickUEXmF1enZcplW40BRodhmx6L1GVizJ1vrpRARkR9jfNQWkyki0r2i0nLc//l6j3QlckZxmR33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6b90gYiI/ANjpOuYTBGR3wi2mLBoTG90aB7m8XKGQJMBHZqHYdGY3l4zKJGIiPwHY6RrFFXVe4d5IiL3KrGVY8qSFCxan4HiMnuDP1+gWeq/Jw5u71W7bURE5H8YI53DZIqI/NaaPdm477P1yCsqQ7HN/QEj0GRAmNWM2SO6IdlLLtISEREBjJGOYjJFRH6tqLQc035IwRdrMmBQgCI37MJZzQbYVWB4ciwmXNneK1q7EhERnYkxsm5MpoiIAOQWlWHh2gzMXbkb+SU2FJWVw5lXR0UBrGYjQiwm3NUvHkN76H9qOxERkSMYI2vGZIqIqAq7XcWfu47i1+1ZWJ1+DGmZ+TAoCkwGBSoAVVWhKAoUADa7Cruqok2TECTHRWFAuxj0jo+CwaBo/dsgIiJyO8bIszGZIiKqhd2uYl92IdKPFqDYVo5Smx0BJgMCTUa0jg5Gq6ggKIpvBQYiIiJHMEYymSIiIiIiInIJ50wRERERERG5gMkUERERERGRC5hMERERERERuYDJFBERERERkQuYTBEREREREbmAyRQREREREZELmEwRERERERG5gMkUERERERGRC5hMERERERERuYDJFBERERERkQuYTBEREREREbmAyRQREREREZELmEwRERERERG54P8BpYClOim4ApQAAAAASUVORK5CYII="
},
"metadata": {}
}
],
"metadata": {
"ExecuteTime": {
"end_time": "2021-05-17T08:26:08.431841Z",
"start_time": "2021-05-17T08:26:08.172882Z"
}
}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"The left graph given above shows a solution found by the parameterized quantum circuit, while the right graph given above shows a solution found by the brute-force algorithm. It can be seen that even if the order of the vertices are different, the routes are essentially the same, which verifies the correctness of using parameterized quantum circuit to solve the TSP." "The left graph given above shows a solution found by the parameterized quantum circuit, while the right graph given above shows a solution found by the brute-force algorithm. It can be seen that even if the order of the vertices are different, the routes are essentially the same, which verifies the correctness of using parameterized quantum circuit to solve the TSP."
] ],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"## Applications\n", "## Applications\n",
"\n", "\n",
...@@ -490,11 +552,11 @@ ...@@ -490,11 +552,11 @@
"The TSP, as one of the most famous optimization problems, also provides a platform for the study of general methods in solving combinatorial problem. This is usually the first several problems that researchers give a try for experiments of new algorithms.\n", "The TSP, as one of the most famous optimization problems, also provides a platform for the study of general methods in solving combinatorial problem. This is usually the first several problems that researchers give a try for experiments of new algorithms.\n",
"\n", "\n",
"More applications, formulations and solution approaches can be found in [6]." "More applications, formulations and solution approaches can be found in [6]."
] ],
"metadata": {}
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {},
"source": [ "source": [
"_______\n", "_______\n",
"\n", "\n",
...@@ -511,7 +573,8 @@ ...@@ -511,7 +573,8 @@
"[5] Klanšek, Uroš. \"Using the TSP solution for optimal route scheduling in construction management.\" [Organization, technology & management in construction: an international journal 3.1 (2011): 243-249.](https://www.semanticscholar.org/paper/Using-the-TSP-Solution-for-Optimal-Route-Scheduling-Klansek/3d809f185c03a8e776ac07473c76e9d77654c389)\n", "[5] Klanšek, Uroš. \"Using the TSP solution for optimal route scheduling in construction management.\" [Organization, technology & management in construction: an international journal 3.1 (2011): 243-249.](https://www.semanticscholar.org/paper/Using-the-TSP-Solution-for-Optimal-Route-Scheduling-Klansek/3d809f185c03a8e776ac07473c76e9d77654c389)\n",
"\n", "\n",
"[6] Matai, Rajesh, Surya Prakash Singh, and Murari Lal Mittal. \"Traveling salesman problem: an overview of applications, formulations, and solution approaches.\" [Traveling salesman problem, theory and applications 1 (2010).](https://www.sciencedirect.com/topics/computer-science/traveling-salesman-problem)" "[6] Matai, Rajesh, Surya Prakash Singh, and Murari Lal Mittal. \"Traveling salesman problem: an overview of applications, formulations, and solution approaches.\" [Traveling salesman problem, theory and applications 1 (2010).](https://www.sciencedirect.com/topics/computer-science/traveling-salesman-problem)"
] ],
"metadata": {}
} }
], ],
"metadata": { "metadata": {
...@@ -530,7 +593,7 @@ ...@@ -530,7 +593,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.8.8" "version": "3.7.11"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
...@@ -548,4 +611,4 @@ ...@@ -548,4 +611,4 @@
}, },
"nbformat": 4, "nbformat": 4,
"nbformat_minor": 4 "nbformat_minor": 4
} }
\ No newline at end of file
...@@ -24,10 +24,10 @@ ...@@ -24,10 +24,10 @@
"source": [ "source": [
"### 背景\n", "### 背景\n",
"\n", "\n",
"在监督学习的情况下,我们需要输入 $N$ 组带标签的数据点构成的数据集 $D = \\{(x^k,y^k)\\}_{k=1}^{N}$,其中 $x^k\\in \\mathbb{R}^{m}$ 是数据点,$y^k \\in\\{0,1\\}$ 是对应数据点 $x^k$ 的分类标签。**分类过程实质上是一个决策过程,决策给定数据点的标签归属问题**。 对于量子分类器框架,分类器 $\\mathcal{F}$ 的实现方式为一个含参 $\\theta$ 的量子神经网络/参数化量子电路, 测量量子系统以及数据后处理的组合。一个优秀的分类器 $\\mathcal{F}_\\theta$ 应该尽可能的将每个数据集内的数据点正确地映射到相对应的标签上 $\\mathcal{F}_\\theta(x^k) \\rightarrow y^k$。因此,我们将预测标签 $\\tilde{y}^{k} = \\mathcal{F}_\\theta(x^k)$ 和实际标签 $y^k$ 之间的累计距离作为损失函数 $\\mathcal{L}(\\theta)$ 进行优化。对于两分类任务,可以选择二次损失函数\n", "在监督学习的情况下,我们需要输入 $N$ 个带标签的数据点构成的数据集 $D = \\{(x^k,y^k)\\}_{k=1}^{K}$,其中 $x^k\\in \\mathbb{R}^{m}$ 是数据点,$y^k \\in\\{0,1\\}$ 是对应数据点 $x^k$ 的分类标签。**分类过程实质上是一个决策过程,决策给定数据点的标签归属问题**。 对于量子分类器框架,分类器 $\\mathcal{F}$ 的实现方式为一个含参 $\\theta$ 的量子神经网络/参数化量子电路, 测量量子系统以及数据后处理的组合。一个优秀的分类器 $\\mathcal{F}_\\theta$ 应该尽可能的将每个数据集内的数据点正确地映射到相对应的标签上 $\\mathcal{F}_\\theta(x^k) \\rightarrow y^k$。因此,我们将预测标签 $\\tilde{y}^{k} = \\mathcal{F}_\\theta(x^k)$ 和实际标签 $y^k$ 之间的累计距离作为损失函数 $\\mathcal{L}(\\theta)$ 进行优化。对于两分类任务,可以选择二次损失函数\n",
"\n", "\n",
"$$\n", "$$\n",
"\\mathcal{L}(\\theta) = \\sum_{k=1}^N |\\tilde{y}^{k}-y^k|^2. \\tag{1}\n", "\\mathcal{L}(\\theta) = \\sum_{k=1}^N 1/N \\cdot |\\tilde{y}^{k}-y^k|^2. \\tag{1}\n",
"$$\n", "$$\n",
"\n" "\n"
] ]
...@@ -40,16 +40,15 @@ ...@@ -40,16 +40,15 @@
"\n", "\n",
"这里我们给出实现量子电路学习 (QCL) 框架下量子分类器的一个流程。\n", "这里我们给出实现量子电路学习 (QCL) 框架下量子分类器的一个流程。\n",
"\n", "\n",
"1. 在初始化的量子比特 $\\lvert 0 \\rangle$ 上作用参数化的酉门 $U$(unitary gate),从而把原始的经典数据点 $x^k$ 编码成量子计算机可以运行的量子数据 $\\lvert \\psi_{in}\\rangle^k$。\n", "1. 将经典数据编码$x^k$为量子数据$\\lvert \\psi_{\\rm in}\\rangle^k$。本教材采用角度编码。关于编码方式的具体操作,见[量子态编码经典数据](./DataEncoding_EN.ipynb)。用户也可以尝试其他编码,如振幅编码,体验不同编码方式学习效率的区别。\n",
"2. 使输入态 $\\lvert \\psi_{in} \\rangle^k$ 通过参数为 $\\theta$ 的参数化电路 $U(\\theta)$ ,由此获得输出态 $\\lvert \\psi_{out}\\rangle^k = U(\\theta)\\lvert \\psi_{in} \\rangle^k$。\n", "2. 构建可调参数量子电路,对应幺正变换(unitary gate)$U(\\theta)$。\n",
"3. 对量子神经网络处理后的量子态 $\\lvert \\psi_{out}\\rangle^k$ 进行测量和数据后处理,得到估计出的标签 $\\tilde{y}^{k}$。\n", "3. 对每一个量子数据$\\lvert\\psi_{\\rm in}\\rangle^k$,通过参数化量子电路$U(\\theta)$,得到输出态$\\lvert \\psi_{\\rm out}\\rangle^k = U(\\theta)\\lvert \\psi_{\\rm in} \\rangle^k$。\n",
"4. 重复步骤2-3直到数据集内所有的数据点都经过了处理。然后计算损失函数 $\\mathcal{L}(\\theta)$。\n", "4. 对每一个量子数据得到的输出量子态$\\lvert \\psi_{\\rm out}\\rangle^k$,通过测量与数据后处理,得到标签 $\\tilde{y}^{k}$。\n",
"5. 通过梯度下降等优化方法不断调整参数 $\\theta$ 的值,从而最小化损失函数。记录优化完成后的最优参数 $\\theta^*$, 这时我们就学习到了最优的分类器 $\\mathcal{F}_{\\theta^*}$。\n", "5. 重复以上步骤,得到数据集内所有点的标签,并计算损失函数 $\\mathcal{L}(\\theta)$。\n",
"6. 通过梯度下降等优化方法不断调整参数 $\\theta$ 的值,从而最小化损失函数。记录优化完成后的最优参数 $\\theta^*$, 这时我们就学习到了最优的分类器 $\\mathcal{F}_{\\theta^*}$。\n",
"\n", "\n",
"\n", "<img src=\"./figures/qclassifier-fig-pipeline-cn.png\" width=\"700px\" /> \n",
"\n", "<center> 图 1:量子分类器训练的流程图 </center>"
"![QCL](figures/qclassifier-fig-pipeline-cn.png \"图 1:量子分类器训练的流程图\")\n",
"<div style=\"text-align:center\">图 1:量子分类器训练的流程图 </div>"
] ]
}, },
{ {
...@@ -58,7 +57,7 @@ ...@@ -58,7 +57,7 @@
"source": [ "source": [
"## Paddle Quantum 实现\n", "## Paddle Quantum 实现\n",
"\n", "\n",
"这里,我们先导入所需要的语言包:\n" "这里,我们先导入所需要的语言包:"
] ]
}, },
{ {
...@@ -72,42 +71,47 @@ ...@@ -72,42 +71,47 @@
}, },
"outputs": [], "outputs": [],
"source": [ "source": [
"import time\n", "# 导入numpy与paddle\n",
"import matplotlib\n",
"import numpy as np\n", "import numpy as np\n",
"import paddle\n", "import paddle\n",
"from numpy import pi as PI\n",
"from matplotlib import pyplot as plt\n",
"\n", "\n",
"from paddle import matmul, transpose\n", "# 构建量子电路\n",
"from paddle_quantum.circuit import UAnsatz\n", "from paddle_quantum.circuit import UAnsatz\n",
"from paddle_quantum.utils import pauli_str_to_matrix" "# 一些用到的函数\n",
"from numpy import pi as PI\n",
"from paddle import matmul, transpose # paddle矩阵乘法与转置\n",
"from paddle_quantum.utils import pauli_str_to_matrix,dagger # 得到N量子比特泡利矩阵,复共轭\n",
"\n",
"# 作图与计算时间\n",
"from matplotlib import pyplot as plt\n",
"import time"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"分类器问题用到的参数"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 2,
"metadata": { "metadata": {},
"ExecuteTime": {
"end_time": "2021-03-02T09:15:03.845958Z",
"start_time": "2021-03-02T09:15:03.840512Z"
}
},
"outputs": [], "outputs": [],
"source": [ "source": [
"# 这是教程中会用到的几个主要函数\n", "# 训练参数设置\n",
"__all__ = [\n", "Ntrain = 200 # 规定训练集大小\n",
" \"circle_data_point_generator\",\n", "Ntest = 100 # 规定测试集大小\n",
" \"data_point_plot\",\n", "gap = 0.5 # 设定决策边界的宽度\n",
" \"heatmap_plot\",\n", "N = 4 # 所需的量子比特数量\n",
" \"Ry\",\n", "DEPTH = 1 # 采用的电路深度\n",
" \"Rz\",\n", "BATCH = 20 # 训练时 batch 的大小\n",
" \"Observable\",\n", "EPOCH = int(200 * BATCH / Ntrain) \n",
" \"U_theta\",\n", " # 训练 epoch 轮数,使得总迭代次数 EPOCH * (Ntrain / BATCH) 在200左右\n",
" \"Net\",\n", "LR = 0.01 # 设置学习速率\n",
" \"QC\",\n", "seed_paras = 19 # 设置随机种子用以初始化各种参数\n",
" \"main\",\n", "seed_data = 2 # 固定生成数据集所需要的随机种子"
"]"
] ]
}, },
{ {
...@@ -118,12 +122,19 @@ ...@@ -118,12 +122,19 @@
"\n", "\n",
"对于监督学习来说,我们绕不开的一个问题就是——采用的数据集是什么样的?在这个教程中我们按照论文 [1] 里所提及方法生成简单的圆形决策边界二分数据集 $\\{(x^{k}, y^{k})\\}$。其中数据点 $x^{k}\\in \\mathbb{R}^{2}$,标签 $y^{k} \\in \\{0,1\\}$。\n", "对于监督学习来说,我们绕不开的一个问题就是——采用的数据集是什么样的?在这个教程中我们按照论文 [1] 里所提及方法生成简单的圆形决策边界二分数据集 $\\{(x^{k}, y^{k})\\}$。其中数据点 $x^{k}\\in \\mathbb{R}^{2}$,标签 $y^{k} \\in \\{0,1\\}$。\n",
"\n", "\n",
"![数据集](figures/qclassifier-fig-data-cn.png \"图 2:生成的数据集和对应的决策边界\")\n", "<img src=\"./figures/qclassifier-fig-data-cn.png\" width=\"400px\" /> \n",
"<div style=\"text-align:center\">图 2:生成的数据集和对应的决策边界 </div>\n", "<center> 图 2:生成的数据集和对应的决策边界 </center>\n",
"\n", "\n",
"具体的生成方式和可视化请见如下代码:" "具体的生成方式和可视化请见如下代码:"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"数据集生成函数 "
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 3,
...@@ -142,14 +153,15 @@ ...@@ -142,14 +153,15 @@
" :param Ntest: 测试集大小\n", " :param Ntest: 测试集大小\n",
" :param boundary_gap: 取值于 (0, 0.5), 两类别之间的差距\n", " :param boundary_gap: 取值于 (0, 0.5), 两类别之间的差距\n",
" :param seed_data: 随机种子\n", " :param seed_data: 随机种子\n",
" :return: 'Ntrain' 训练集\n", " :return: 四个列表:训练集x,训练集y,测试集x,测试集y\n",
" 'Ntest' 测试集\n",
" \"\"\"\n", " \"\"\"\n",
" # 生成共Ntrain + Ntest组数据,x对应二维数据点,y对应编号\n",
" # 取前Ntrain个为训练集,后Ntest个为测试集\n",
" train_x, train_y = [], []\n", " train_x, train_y = [], []\n",
" num_samples, seed_para = 0, 0\n", " num_samples, seed_para = 0, 0\n",
" while num_samples < Ntrain + Ntest:\n", " while num_samples < Ntrain + Ntest:\n",
" np.random.seed((seed_data + 10) * 1000 + seed_para + num_samples)\n", " np.random.seed((seed_data + 10) * 1000 + seed_para + num_samples)\n",
" data_point = np.random.rand(2) * 2 - 1\n", " data_point = np.random.rand(2) * 2 - 1 # 生成[-1, 1]范围内二维向量\n",
"\n", "\n",
" # 如果数据点的模小于(0.7 - gap),标为0\n", " # 如果数据点的模小于(0.7 - gap),标为0\n",
" if np.linalg.norm(data_point) < 0.7 - boundary_gap / 2:\n", " if np.linalg.norm(data_point) < 0.7 - boundary_gap / 2:\n",
...@@ -171,13 +183,26 @@ ...@@ -171,13 +183,26 @@
" print(\"训练集的维度大小 x {} 和 y {}\".format(np.shape(train_x[0:Ntrain]), np.shape(train_y[0:Ntrain])))\n", " print(\"训练集的维度大小 x {} 和 y {}\".format(np.shape(train_x[0:Ntrain]), np.shape(train_y[0:Ntrain])))\n",
" print(\"测试集的维度大小 x {} 和 y {}\".format(np.shape(train_x[Ntrain:]), np.shape(train_y[Ntrain:])), \"\\n\")\n", " print(\"测试集的维度大小 x {} 和 y {}\".format(np.shape(train_x[Ntrain:]), np.shape(train_y[Ntrain:])), \"\\n\")\n",
"\n", "\n",
" return train_x[0:Ntrain], train_y[0:Ntrain], train_x[Ntrain:], train_y[Ntrain:]\n", " return train_x[0:Ntrain], train_y[0:Ntrain], train_x[Ntrain:], train_y[Ntrain:]\n"
"\n", ]
"\n", },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"数据集可视化函数"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# 用以可视化生成的数据集\n", "# 用以可视化生成的数据集\n",
"def data_point_plot(data, label):\n", "def data_point_plot(data, label):\n",
" \"\"\"\n", " \"\"\"\n",
" :param data: 形状为 [M, 2], 代表 M 2-D 数据点\n", " :param data: 形状为 [M, 2], 代表M个 2-D 数据点\n",
" :param label: 取值 0 或者 1\n", " :param label: 取值 0 或者 1\n",
" :return: 画这些数据点\n", " :return: 画这些数据点\n",
" \"\"\"\n", " \"\"\"\n",
...@@ -191,9 +216,16 @@ ...@@ -191,9 +216,16 @@
" plt.show()" " plt.show()"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"此教程采用大小分别为 200, 100 的训练集,测试集,决策边界宽度为 0.5 的数据,用以训练与测试量子神经网络训练效果:"
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 5,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-02T09:15:06.422981Z", "end_time": "2021-03-02T09:15:06.422981Z",
...@@ -213,7 +245,7 @@ ...@@ -213,7 +245,7 @@
}, },
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -232,7 +264,7 @@ ...@@ -232,7 +264,7 @@
}, },
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -275,15 +307,18 @@ ...@@ -275,15 +307,18 @@
"source": [ "source": [
"### 数据的预处理\n", "### 数据的预处理\n",
"\n", "\n",
"与经典机器学习不同的是,量子分类器在实际工作的时候需要考虑数据的预处理。我们需要多加一个步骤将经典的数据转化成量子信息才能放在量子计算机上运行。接下来我们看看具体是怎么完成的。\n", "与经典机器学习不同的是,量子分类器在实际工作的时候需要考虑数据的预处理。我们需要多加一个步骤将经典的数据转化成量子信息才能放在量子计算机上运行。此处我们采用角度编码方式得到量子数据。\n",
"\n", "\n",
"首先我们确定需要使用的量子比特数量。因为我们的数据 $\\{x^{k} = (x^{k}_0, x^{k}_1)\\}$ 是二维的, 按照 Mitarai (2018) 论文[1]中的编码方式我们至少需要2个量子比特。接着准备一系列的初始量子态 $|00\\rangle$。然后将经典信息 $\\{x^{k}\\}$ 编码成一系列量子门 $U(x^{k})$ 并作用在初始量子态上。最终得到一系列的量子态 $|\\psi\\rangle^k = U(x^{k})|00\\rangle$。这样我们就完成从经典信息到量子信息的编码了!给定 $m$ 个量子比特去编码二维的经典数据点,则量子门的构造为:\n", "首先我们确定需要使用的量子比特数量。因为我们的数据 $\\{x^{k} = (x^{k}_0, x^{k}_1)\\}$ 是二维的, 按照 Mitarai (2018) 论文[1]中的编码方式我们至少需要2个量子比特。接着准备一系列的初始量子态 $|00\\rangle$。然后将经典信息 $\\{x^{k}\\}$ 编码成一系列量子门 $U(x^{k})$ 并作用在初始量子态上。最终得到一系列的量子态 $|\\psi_{\\rm in}\\rangle^k = U(x^{k})|00\\rangle$。这样我们就完成从经典信息到量子信息的编码了!\n",
"\n",
"给定 $m$ 个量子比特去编码二维的经典数据点,采用角度编码,量子门的构造为:\n",
"\n", "\n",
"$$\n", "$$\n",
"U(x^{k}) = \\otimes_{j=0}^{m-1} R_j^z\\big[\\arccos(x_{j \\, \\text{mod} \\, 2}\\cdot x_{j \\, \\text{mod} \\, 2})\\big] R_j^y\\big[\\arcsin(x_{j \\, \\text{mod} \\, 2}) \\big],\\tag{2}\n", "U(x^{k}) = \\otimes_{j=0}^{m-1} R_j^z\\big[\\arccos(x^{k}_{j \\, \\text{mod} \\, 2}\\cdot x^{k}_{j \\, \\text{mod} \\, 2})\\big] R_j^y\\big[\\arcsin(x^{k}_{j \\, \\text{mod} \\, 2}) \\big],\\tag{2}\n",
"$$\n", "$$\n",
"\n", "\n",
"**注意** :这种表示下,我们将第一个量子比特编号为 $j = 0$。更多编码方式见 [Robust data encodings for quantum classifiers](https://arxiv.org/pdf/2003.01695.pdf)。读者也可以直接使用量桨中提供的[编码方式](./DataEncoding_CN.ipynb)。这里我们也欢迎读者自己创新尝试全新的编码方式。\n", "**注意** :这种表示下,我们将第一个量子比特编号为 $j = 0$。更多编码方式见 [Robust data encodings for quantum classifiers](https://arxiv.org/pdf/2003.01695.pdf)。读者也可以直接使用量桨中提供的[编码方式](./DataEncoding_CN.ipynb)。这里我们也欢迎读者自己创新尝试全新的编码方式。\n",
"\n",
"由于这种编码的方式看着比较复杂,我们不妨来举一个简单的例子。假设我们给定一个数据点 $x = (x_0, x_1)= (1,0)$, 显然这个数据点的标签应该为 1,对应上图**蓝色**的点。同时数据点对应的2比特量子门 $U(x)$ 是\n", "由于这种编码的方式看着比较复杂,我们不妨来举一个简单的例子。假设我们给定一个数据点 $x = (x_0, x_1)= (1,0)$, 显然这个数据点的标签应该为 1,对应上图**蓝色**的点。同时数据点对应的2比特量子门 $U(x)$ 是\n",
"\n", "\n",
"$$\n", "$$\n",
...@@ -307,23 +342,24 @@ ...@@ -307,23 +342,24 @@
"\n", "\n",
"\n", "\n",
"$$\n", "$$\n",
"R_x(\\theta) := \n", "R_x(\\theta) :=\n",
"\\begin{bmatrix} \n", "\\begin{bmatrix}\n",
"\\cos \\frac{\\theta}{2} &-i\\sin \\frac{\\theta}{2} \\\\ \n", "\\cos \\frac{\\theta}{2} &-i\\sin \\frac{\\theta}{2} \\\\\n",
"-i\\sin \\frac{\\theta}{2} &\\cos \\frac{\\theta}{2} \n", "-i\\sin \\frac{\\theta}{2} &\\cos \\frac{\\theta}{2}\n",
"\\end{bmatrix}\n", "\\end{bmatrix}\n",
",\\quad \n", ",\\quad\n",
"R_y(\\theta) := \n", "R_y(\\theta) :=\n",
"\\begin{bmatrix}\n", "\\begin{bmatrix}\n",
"\\cos \\frac{\\theta}{2} &-\\sin \\frac{\\theta}{2} \\\\ \n", "\\cos \\frac{\\theta}{2} &-\\sin \\frac{\\theta}{2} \\\\\n",
"\\sin \\frac{\\theta}{2} &\\cos \\frac{\\theta}{2} \n", "\\sin \\frac{\\theta}{2} &\\cos \\frac{\\theta}{2}\n",
"\\end{bmatrix}\n", "\\end{bmatrix}\n",
",\\quad \n", ",\\quad\n",
"R_z(\\theta) := \n", "R_z(\\theta) :=\n",
"\\begin{bmatrix}\n", "\\begin{bmatrix}\n",
"e^{-i\\frac{\\theta}{2}} & 0 \\\\ \n", "e^{-i\\frac{\\theta}{2}} & 0 \\\\\n",
"0 & e^{i\\frac{\\theta}{2}}\n", "0 & e^{i\\frac{\\theta}{2}}\n",
"\\end{bmatrix}. \\tag{5}\n", "\\end{bmatrix}.\n",
"\\tag{5}\n",
"$$\n", "$$\n",
"\n", "\n",
"那么这个两比特量子门 $U(x)$ 的矩阵形式可以写为:\n", "那么这个两比特量子门 $U(x)$ 的矩阵形式可以写为:\n",
...@@ -350,13 +386,13 @@ ...@@ -350,13 +386,13 @@
"1 &0 \\\\ \n", "1 &0 \\\\ \n",
"0 &1\n", "0 &1\n",
"\\end{bmatrix}\n", "\\end{bmatrix}\n",
"\\bigg),\\tag{6}\n", "\\bigg)\\, .\\tag{6}\n",
"$$\n", "$$\n",
"\n", "\n",
"化简后我们作用在零初始化的 $|00\\rangle$ 量子态上可以得到编码后的量子态 $|\\psi\\rangle$,\n", "化简后我们作用在零初始化的 $|00\\rangle$ 量子态上可以得到编码后的量子态 $|\\psi_{\\rm in}\\rangle$,\n",
"\n", "\n",
"$$\n", "$$\n",
"|\\psi\\rangle =\n", "|\\psi_{\\rm in}\\rangle =\n",
"U(x)|00\\rangle = \\frac{1}{2}\n", "U(x)|00\\rangle = \\frac{1}{2}\n",
"\\begin{bmatrix}\n", "\\begin{bmatrix}\n",
"1-i &0 &-1+i &0 \\\\ \n", "1-i &0 &-1+i &0 \\\\ \n",
...@@ -389,26 +425,16 @@ ...@@ -389,26 +425,16 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 6,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-02T09:15:06.589265Z", "end_time": "2021-03-02T09:15:06.589265Z",
"start_time": "2021-03-02T09:15:06.452691Z" "start_time": "2021-03-02T09:15:06.452691Z"
} }
}, },
"outputs": [ "outputs": [],
{
"name": "stdout",
"output_type": "stream",
"text": [
"作为测试我们输入以上的经典信息:\n",
"(x_0, x_1) = (1, 0)\n",
"编码后输出的2比特量子态为:\n",
"[[[0.5-0.5j 0. +0.j 0.5-0.5j 0. +0.j ]]]\n"
]
}
],
"source": [ "source": [
"# 构建绕Y轴,绕Z轴旋转theta角度矩阵\n",
"def Ry(theta):\n", "def Ry(theta):\n",
" \"\"\"\n", " \"\"\"\n",
" :param theta: 参数\n", " :param theta: 参数\n",
...@@ -428,20 +454,24 @@ ...@@ -428,20 +454,24 @@
"# 经典 -> 量子数据编码器\n", "# 经典 -> 量子数据编码器\n",
"def datapoints_transform_to_state(data, n_qubits):\n", "def datapoints_transform_to_state(data, n_qubits):\n",
" \"\"\"\n", " \"\"\"\n",
" :param data: 形状为 [-1, 2]\n", " :param data: 形状为 [-1, 2],numpy向量形式\n",
" :param n_qubits: 数据转化后的量子比特数量\n", " :param n_qubits: 数据转化后的量子比特数量\n",
" :return: 形状为 [-1, 1, 2 ^ n_qubits]\n", " :return: 形状为 [-1, 1, 2 ^ n_qubits]\n",
" 形状中-1表示第一个参数为任意大小。在此教程实例分析中,对应于BATCH,用以得到Eq.(1)中平方误差的平均值\n",
" \"\"\"\n", " \"\"\"\n",
" dim1, dim2 = data.shape\n", " dim1, dim2 = data.shape\n",
" res = []\n", " res = []\n",
" for sam in range(dim1):\n", " for sam in range(dim1):\n",
" res_state = 1.\n", " res_state = 1.\n",
" zero_state = np.array([[1, 0]])\n", " zero_state = np.array([[1, 0]])\n",
" # 角度编码\n",
" for i in range(n_qubits):\n", " for i in range(n_qubits):\n",
" # 对偶数编号量子态作用Rz(arccos(x0^2)) Ry(arcsin(x0))\n",
" if i % 2 == 0:\n", " if i % 2 == 0:\n",
" state_tmp=np.dot(zero_state, Ry(np.arcsin(data[sam][0])).T)\n", " state_tmp=np.dot(zero_state, Ry(np.arcsin(data[sam][0])).T)\n",
" state_tmp=np.dot(state_tmp, Rz(np.arccos(data[sam][0] ** 2)).T)\n", " state_tmp=np.dot(state_tmp, Rz(np.arccos(data[sam][0] ** 2)).T)\n",
" res_state=np.kron(res_state, state_tmp)\n", " res_state=np.kron(res_state, state_tmp)\n",
" # 对奇数编号量子态作用Rz(arccos(x1^2)) Ry(arcsin(x1))\n",
" elif i % 2 == 1:\n", " elif i % 2 == 1:\n",
" state_tmp=np.dot(zero_state, Ry(np.arcsin(data[sam][1])).T)\n", " state_tmp=np.dot(zero_state, Ry(np.arcsin(data[sam][1])).T)\n",
" state_tmp=np.dot(state_tmp, Rz(np.arccos(data[sam][1] ** 2)).T)\n", " state_tmp=np.dot(state_tmp, Rz(np.arccos(data[sam][1] ** 2)).T)\n",
...@@ -449,8 +479,33 @@ ...@@ -449,8 +479,33 @@
" res.append(res_state)\n", " res.append(res_state)\n",
"\n", "\n",
" res = np.array(res)\n", " res = np.array(res)\n",
" return res.astype(\"complex128\")\n", " return res.astype(\"complex128\")\n"
"\n", ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"测试角度编码下得到的量子数据"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"作为测试我们输入以上的经典信息:\n",
"(x_0, x_1) = (1, 0)\n",
"编码后输出的2比特量子态为:\n",
"[[[0.5-0.5j 0. +0.j 0.5-0.5j 0. +0.j ]]]\n"
]
}
],
"source": [
"print(\"作为测试我们输入以上的经典信息:\")\n", "print(\"作为测试我们输入以上的经典信息:\")\n",
"print(\"(x_0, x_1) = (1, 0)\")\n", "print(\"(x_0, x_1) = (1, 0)\")\n",
"print(\"编码后输出的2比特量子态为:\")\n", "print(\"编码后输出的2比特量子态为:\")\n",
...@@ -465,14 +520,13 @@ ...@@ -465,14 +520,13 @@
"\n", "\n",
"那么在完成上述从经典数据到量子数据的编码后,我们现在可以把这些量子态输入到量子计算机里面了。在那之前,我们还需要设计下我们所采用的量子神经网络结构。\n", "那么在完成上述从经典数据到量子数据的编码后,我们现在可以把这些量子态输入到量子计算机里面了。在那之前,我们还需要设计下我们所采用的量子神经网络结构。\n",
"\n", "\n",
"![电路结构](figures/qclassifier-fig-circuit.png \"图 3:参数化量子神经网络的电路结构\")\n", "<img src=\"./figures/qclassifier-fig-circuit.png\" width=\"600px\" /> \n",
"<div style=\"text-align:center\">图 3:参数化量子神经网络的电路结构 </div>\n", "<center> 图 3:参数化量子神经网络的电路结构 </center>\n",
"\n",
"\n", "\n",
"为了方便,我们统一将上述参数化的量子神经网络称为 $U(\\boldsymbol{\\theta})$。这个 $U(\\boldsymbol{\\theta})$ 是我们分类器的关键组成部分,需要一定的复杂结构来拟合我们的决策边界。与经典神经网络类似,量子神经网络的的设计并不是唯一的,这里展示的仅仅是一个例子,读者不妨自己设计出自己的量子神经网络。我们还是拿原来提过的这个数据点 $x = (x_0, x_1)= (1,0)$ 来举例子,编码过后我们已经得到了一个量子态 $|\\psi\\rangle$,\n", "为了方便,我们统一将上述参数化的量子神经网络称为 $U(\\boldsymbol{\\theta})$。这个 $U(\\boldsymbol{\\theta})$ 是我们分类器的关键组成部分,需要一定的复杂结构来拟合我们的决策边界。与经典神经网络类似,量子神经网络的的设计并不是唯一的,这里展示的仅仅是一个例子,读者不妨自己设计出自己的量子神经网络。我们还是拿原来提过的这个数据点 $x = (x_0, x_1)= (1,0)$ 来举例子,编码过后我们已经得到了一个量子态 $|\\psi_{\\rm in}\\rangle$,\n",
"\n", "\n",
"$$\n", "$$\n",
"|\\psi\\rangle =\n", "|\\psi_{\\rm in}\\rangle =\n",
"\\frac{1}{2}\n", "\\frac{1}{2}\n",
"\\begin{bmatrix}\n", "\\begin{bmatrix}\n",
"1-i \\\\\n", "1-i \\\\\n",
...@@ -482,17 +536,17 @@ ...@@ -482,17 +536,17 @@
"\\end{bmatrix},\\tag{9}\n", "\\end{bmatrix},\\tag{9}\n",
"$$\n", "$$\n",
"\n", "\n",
"接着我们把这个量子态输入进我们的量子神经网络,也就是把一个酉矩阵乘以一个向量。得到处理过后的量子态 $|\\varphi\\rangle$\n", "接着我们把这个量子态输入进我们的量子神经网络,也就是把一个酉矩阵乘以一个向量。得到处理过后的量子态 $|\\psi_{\\rm out}\\rangle$\n",
"\n", "\n",
"$$\n", "$$\n",
"|\\varphi\\rangle = U(\\boldsymbol{\\theta})|\\psi\\rangle,\\tag{10}\n", "|\\psi_{\\rm out}\\rangle = U(\\boldsymbol{\\theta})|\\psi_{\\rm in}\\rangle,\\tag{10}\n",
"$$\n", "$$\n",
"\n", "\n",
"如果我们把所有的参数 $\\theta$ 都设置为 $\\theta = \\pi$, 那么我们就可以写出具体的矩阵了:\n", "如果我们把所有的参数 $\\theta$ 都设置为 $\\theta = \\pi$, 那么我们就可以写出具体的矩阵了:\n",
"\n", "\n",
"$$\n", "$$\n",
"|\\varphi\\rangle = \n", "|\\psi_{\\rm out}\\rangle = \n",
"U(\\boldsymbol{\\theta} =\\pi)|\\psi\\rangle =\n", "U(\\boldsymbol{\\theta} =\\pi)|\\psi_{\\rm in}\\rangle =\n",
"\\begin{bmatrix}\n", "\\begin{bmatrix}\n",
"0 &0 &-1 &0 \\\\ \n", "0 &0 &-1 &0 \\\\ \n",
"-1 &0 &0 &0 \\\\\n", "-1 &0 &0 &0 \\\\\n",
...@@ -519,7 +573,7 @@ ...@@ -519,7 +573,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 8,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-02T09:15:06.795398Z", "end_time": "2021-03-02T09:15:06.795398Z",
...@@ -529,9 +583,9 @@ ...@@ -529,9 +583,9 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"# 模拟搭建量子神经网络\n", "# 模拟搭建量子神经网络\n",
"def U_theta(theta, n, depth): \n", "def cir_Classifier(theta, n, depth): \n",
" \"\"\"\n", " \"\"\"\n",
" :param theta: 维数: [n, depth + 3]\n", " :param theta: 维数: [n, depth + 3] -- 初始增加一层广义旋转门\n",
" :param n: 量子比特数量\n", " :param n: 量子比特数量\n",
" :param depth: 电路深度\n", " :param depth: 电路深度\n",
" :return: U_theta\n", " :return: U_theta\n",
...@@ -546,11 +600,13 @@ ...@@ -546,11 +600,13 @@
" cir.rz(theta[i][2], i)\n", " cir.rz(theta[i][2], i)\n",
"\n", "\n",
" # 默认深度为 depth = 1\n", " # 默认深度为 depth = 1\n",
" # 搭建纠缠层和 Ry旋转层\n", " # 对每一层搭建电路\n",
" for d in range(3, depth + 3):\n", " for d in range(3, depth + 3):\n",
" # 搭建纠缠层\n",
" for i in range(n-1):\n", " for i in range(n-1):\n",
" cir.cnot([i, i + 1])\n", " cir.cnot([i, i + 1])\n",
" cir.cnot([n-1, 0])\n", " cir.cnot([n-1, 0])\n",
" # 对每一个量子比特搭建Ry\n",
" for i in range(n):\n", " for i in range(n):\n",
" cir.ry(theta[i][d], i)\n", " cir.ry(theta[i][d], i)\n",
"\n", "\n",
...@@ -561,13 +617,16 @@ ...@@ -561,13 +617,16 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### 测量与损失函数\n", "### 测量\n",
"\n",
"经过量子神经网络$U(\\theta)$后,得到是量子态$\\lvert \\psi_{\\rm out}\\rangle^k = U(\\theta)\\lvert \\psi_{\\rm in} \\rangle^k$。要想得到该量子态的标签,我们需要通过测量来得到经典信息。然后再通过这些处理后的经典信息计算损失函数 $\\mathcal{L}(\\boldsymbol{\\theta})$。最后再通过梯度下降算法来不断更新 QNN 参数 $\\boldsymbol{\\theta}$,并优化损失函数。\n",
"\n", "\n",
"当我们在量子计算机上(QPU)用量子神经网络处理过初始量子态 $|\\psi\\rangle$ 后, 我们需要重新测量这个新的量子态 $|\\varphi\\rangle$ 来获取经典信息。这些处理过后的经典信息可以用来计算损失函数 $\\mathcal{L}(\\boldsymbol{\\theta})$。最后我们再通过经典计算机(CPU)来不断更新QNN参数 $\\boldsymbol{\\theta}$ 并优化损失函数。这里我们采用的测量方式是测量泡利 $Z$ 算符在第一个量子比特上的期望值。 具体来说,\n", "\n",
"这里我们采用的测量方式是测量泡利 $Z$ 算符在第一个量子比特上的期望值。 具体来说,\n",
"\n", "\n",
"$$\n", "$$\n",
"\\langle Z \\rangle = \n", "\\langle Z \\rangle = \n",
"\\langle \\varphi |Z\\otimes I\\cdots \\otimes I| \\varphi\\rangle,\\tag{12}\n", "\\langle \\psi_{\\rm out} |Z\\otimes I\\cdots \\otimes I| \\psi_{\\rm out}\\rangle,\\tag{12}\n",
"$$\n", "$$\n",
"\n", "\n",
"复习一下,泡利 $Z$ 算符的矩阵形式为:\n", "复习一下,泡利 $Z$ 算符的矩阵形式为:\n",
...@@ -579,7 +638,7 @@ ...@@ -579,7 +638,7 @@
"继续我们前面的 2 量子比特的例子,测量过后我们得到的期望值就是:\n", "继续我们前面的 2 量子比特的例子,测量过后我们得到的期望值就是:\n",
"$$\n", "$$\n",
"\\langle Z \\rangle = \n", "\\langle Z \\rangle = \n",
"\\langle \\varphi |Z\\otimes I| \\varphi\\rangle = \n", "\\langle \\psi_{\\rm out} |Z\\otimes I| \\psi_{\\rm out}\\rangle = \n",
"\\frac{1}{2}\n", "\\frac{1}{2}\n",
"\\begin{bmatrix}\n", "\\begin{bmatrix}\n",
"-1-i \\quad\n", "-1-i \\quad\n",
...@@ -614,22 +673,33 @@ ...@@ -614,22 +673,33 @@
"\n", "\n",
"\n", "\n",
"$$\n", "$$\n",
"x^{k} \\rightarrow |\\psi\\rangle^{k} \\rightarrow U(\\boldsymbol{\\theta})|\\psi\\rangle^{k} \\rightarrow\n", "x^{k} \\rightarrow |\\psi_{\\rm in}\\rangle^{k} \\rightarrow U(\\boldsymbol{\\theta})|\\psi_{\\rm in}\\rangle^{k} \\rightarrow\n",
"|\\varphi\\rangle^{k} \\rightarrow ^{k}\\langle \\varphi |Z\\otimes I\\cdots \\otimes I| \\varphi\\rangle^{k}\n", "|\\psi_{\\rm out}\\rangle^{k} \\rightarrow ^{k}\\langle \\psi_{\\rm out} |Z\\otimes I\\cdots \\otimes I| \\psi_{\\rm out} \\rangle^{k}\n",
"\\rightarrow \\langle Z \\rangle \\rightarrow \\tilde{y}^{k}.\\tag{16}\n", "\\rightarrow \\langle Z \\rangle \\rightarrow \\tilde{y}^{k}.\\tag{16}\n",
"$$\n", "$$\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 损失函数\n",
"\n", "\n",
"最后我们就可以把损失函数定义为平方损失函数:\n", "相比于公式(1)中损失函数,需要在每次迭代中对所有 Ntrain 个数据点进行测量计算,在实际应用中,我们将训练集中的数据拆分为 \"Ntrain/BATCH\" 组,其中每组包含BATCH个数据。\n",
"\n", "\n",
"对第 i 组数据,训练对应损失函数:\n",
"$$\n", "$$\n",
"\\mathcal{L} = \\sum_{k} |y^{k} - \\tilde{y}^{k}|^2.\\tag{17}\n", "\\mathcal{L}_{i} = \\sum_{k=1}^{BATCH} \\frac{1}{BATCH} |y^{i,k} - \\tilde{y}^{i,k}|^2,\\tag{17}\n",
"$$\n", "$$\n",
"\n" "并对每一组训练 EPOCH 次。\n",
"\n",
"当取 \"BATCH = Ntrain\",此时仅有一组数据点,Eq. (17)重新变为Eq. (1)。\n"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 9,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-02T09:15:07.667491Z", "end_time": "2021-03-02T09:15:07.667491Z",
...@@ -651,37 +721,27 @@ ...@@ -651,37 +721,27 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 10,
"metadata": { "metadata": {},
"ExecuteTime": {
"end_time": "2021-03-02T09:15:08.373511Z",
"start_time": "2021-03-02T09:15:08.358729Z"
}
},
"outputs": [], "outputs": [],
"source": [ "source": [
"# 搭建整个优化流程图\n", "# 搭建整个优化流程图\n",
"class Net(paddle.nn.Layer):\n", "class Opt_Classifier(paddle.nn.Layer):\n",
" \"\"\"\n", " \"\"\"\n",
" 创建模型训练网络\n", " 创建模型训练网络\n",
" \"\"\"\n", " \"\"\"\n",
" def __init__(self,\n", " def __init__(self, n, depth, seed_paras=1, dtype='float64'):\n",
" n, # 量子比特数量\n", " # 初始化部分,通过n, depth给出初始电路\n",
" depth, # 电路深度\n", " super(Opt_Classifier, self).__init__()\n",
" seed_paras=1,\n",
" dtype='float64'):\n",
" super(Net, self).__init__()\n",
"\n",
" self.n = n\n", " self.n = n\n",
" self.depth = depth\n", " self.depth = depth\n",
" \n", " \n",
" # 初始化参数列表 theta,并用 [0, 2*pi] 的均匀分布来填充初始值\n", " # 初始化参数列表 theta,并用 [0, 2*pi] 的均匀分布来填充初始值\n",
" self.theta = self.create_parameter(\n", " self.theta = self.create_parameter(\n",
" shape=[n, depth + 3],\n", " shape=[n, depth + 3], # 此处使用量子电路有初始一层广义旋转门,故+3\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2*PI),\n", " default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2*PI),\n",
" dtype=dtype,\n", " dtype=dtype,\n",
" is_bias=False)\n", " is_bias=False)\n",
" \n",
" # 初始化偏置 (bias)\n", " # 初始化偏置 (bias)\n",
" self.bias = self.create_parameter(\n", " self.bias = self.create_parameter(\n",
" shape=[1],\n", " shape=[1],\n",
...@@ -692,30 +752,28 @@ ...@@ -692,30 +752,28 @@
" # 定义前向传播机制、计算损失函数 和交叉验证正确率\n", " # 定义前向传播机制、计算损失函数 和交叉验证正确率\n",
" def forward(self, state_in, label):\n", " def forward(self, state_in, label):\n",
" \"\"\"\n", " \"\"\"\n",
" Args:\n", " 输入: state_in:输入量子态,shape: [-1, 1, 2^n] -- 此教程中为[BATCH, 1, 2^n]\n",
" state_in: The input quantum state, shape [-1, 1, 2^n]\n", " label:输入量子态对应标签,shape: [-1, 1]\n",
" label: label for the input state, shape [-1, 1]\n", " 计算损失函数:\n",
" Returns:\n", " L = 1/BATCH * ((<Z> + 1)/2 + bias - label)^2\n",
" The loss:\n",
" L = ((<Z> + 1)/2 + bias - label)^2\n",
" \"\"\"\n", " \"\"\"\n",
" # 将 Numpy array 转换成 tensor\n", " # 将 Numpy array 转换成 tensor\n",
" Ob = paddle.to_tensor(Observable(self.n))\n", " Ob = paddle.to_tensor(Observable(self.n))\n",
" label_pp = paddle.to_tensor(label)\n", " label_pp = paddle.to_tensor(label)\n",
"\n", "\n",
" # 按照随机初始化的参数 theta \n", " # 按照随机初始化的参数 theta \n",
" cir = U_theta(self.theta, n=self.n, depth=self.depth)\n", " cir = cir_Classifier(self.theta, n=self.n, depth=self.depth)\n",
" Utheta = cir.U\n", " Utheta = cir.U\n",
" \n", " \n",
" # 因为 Utheta是学习到的,我们这里用行向量运算来提速而不会影响训练效果\n", " # 因为 Utheta是学习到的,我们这里用行向量运算来提速而不会影响训练效果\n",
" state_out = matmul(state_in, Utheta) # 维度 [-1, 1, 2 ** n]\n", " state_out = matmul(state_in, Utheta) # [-1, 1, 2 ** n]形式,第一个参数在此教程中为BATCH\n",
" \n", " \n",
" # 测量得到泡利 Z 算符的期望值 <Z>\n", " # 测量得到泡利 Z 算符的期望值 <Z> -- shape [-1,1,1]\n",
" E_Z = matmul(matmul(state_out, Ob), transpose(paddle.conj(state_out), perm=[0, 2, 1]))\n", " E_Z = matmul(matmul(state_out, Ob), transpose(paddle.conj(state_out), perm=[0, 2, 1]))\n",
" \n", " \n",
" # 映射 <Z> 处理成标签的估计值 \n", " # 映射 <Z> 处理成标签的估计值 \n",
" state_predict = paddle.real(E_Z)[:, 0] * 0.5 + 0.5 + self.bias\n", " state_predict = paddle.real(E_Z)[:, 0] * 0.5 + 0.5 + self.bias # 计算每一个y^{i,k}与真实值得平方差\n",
" loss = paddle.mean((state_predict - label_pp) ** 2)\n", " loss = paddle.mean((state_predict - label_pp) ** 2) # 对BATCH个得到的平方差取平均,得到L_i:shape:[1,1]\n",
" \n", " \n",
" # 计算交叉验证正确率\n", " # 计算交叉验证正确率\n",
" is_correct = (paddle.abs(state_predict - label_pp) < 0.5).nonzero().shape[0]\n", " is_correct = (paddle.abs(state_predict - label_pp) < 0.5).nonzero().shape[0]\n",
...@@ -728,23 +786,19 @@ ...@@ -728,23 +786,19 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### 训练效果与调参\n", "### 训练过程\n",
"\n", "\n",
"好了, 那么定义完以上所有的概念之后我们不妨来看看实际的训练效果!" "好了, 那么定义完以上所有的概念之后我们不妨来看看实际的训练过程!"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 11,
"metadata": { "metadata": {},
"ExecuteTime": {
"end_time": "2021-03-02T09:15:08.911819Z",
"start_time": "2021-03-02T09:15:08.887770Z"
}
},
"outputs": [], "outputs": [],
"source": [ "source": [
"def heatmap_plot(net, N):\n", "# 用于绘制最终训练得到分类器的平面分类图\n",
"def heatmap_plot(Opt_Classifier, N):\n",
" # 生成数据点 x_y_\n", " # 生成数据点 x_y_\n",
" Num_points = 30\n", " Num_points = 30\n",
" x_y_ = []\n", " x_y_ = []\n",
...@@ -758,7 +812,7 @@ ...@@ -758,7 +812,7 @@
" # 计算预测: heat_data\n", " # 计算预测: heat_data\n",
" input_state_test = paddle.to_tensor(\n", " input_state_test = paddle.to_tensor(\n",
" datapoints_transform_to_state(x_y_, N))\n", " datapoints_transform_to_state(x_y_, N))\n",
" loss_useless, acc_useless, state_predict, cir = net(state_in=input_state_test, label=x_y_[:, 0])\n", " loss_useless, acc_useless, state_predict, cir = Opt_Classifier(state_in=input_state_test, label=x_y_[:, 0])\n",
" heat_data = state_predict.reshape(Num_points, Num_points)\n", " heat_data = state_predict.reshape(Num_points, Num_points)\n",
"\n", "\n",
" # 画图\n", " # 画图\n",
...@@ -772,45 +826,72 @@ ...@@ -772,45 +826,72 @@
" ax.set_yticklabels(y_label)\n", " ax.set_yticklabels(y_label)\n",
" im = ax.imshow(heat_data, cmap=plt.cm.RdBu)\n", " im = ax.imshow(heat_data, cmap=plt.cm.RdBu)\n",
" plt.colorbar(im)\n", " plt.colorbar(im)\n",
" plt.show()\n", " plt.show()"
"\n", ]
"def QClassifier(Ntrain, Ntest, gap, N, D, EPOCH, LR, BATCH, seed_paras, seed_data,):\n", },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"通过 Adam 优化器不断学习训练"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"def QClassifier(Ntrain, Ntest, gap, N, DEPTH, EPOCH, LR, BATCH, seed_paras, seed_data,):\n",
" \"\"\"\n", " \"\"\"\n",
" 量子二分类器\n", " 量子二分类器\n",
" 输入参数:\n",
" Ntrain, # 规定训练集大小\n",
" Ntest, # 规定测试集大小\n",
" gap, # 设定决策边界的宽度\n",
" N, # 所需的量子比特数量\n",
" DEPTH, # 采用的电路深度\n",
" BATCH, # 训练时 batch 的大小\n",
" EPOCH, # 训练 epoch 轮数\n",
" LR, # 设置学习速率\n",
" seed_paras, # 设置随机种子用以初始化各种参数\n",
" seed_data, # 固定生成数据集所需要的随机种子\n",
" \"\"\"\n", " \"\"\"\n",
" # 生成数据集\n", " # 生成训练集测试集\n",
" train_x, train_y, test_x, test_y = circle_data_point_generator(Ntrain=Ntrain, Ntest=Ntest, boundary_gap=gap, seed_data=seed_data)\n", " train_x, train_y, test_x, test_y = circle_data_point_generator(Ntrain=Ntrain, Ntest=Ntest, boundary_gap=gap, seed_data=seed_data)\n",
"\n",
" # 读取训练集的维度\n", " # 读取训练集的维度\n",
" N_train = train_x.shape[0]\n", " N_train = train_x.shape[0]\n",
" \n", " \n",
" paddle.seed(seed_paras)\n", " paddle.seed(seed_paras)\n",
" # 定义优化图\n", " # 初始化寄存器存储正确率 acc 等信息\n",
" net = Net(n=N, depth=D)\n", " summary_iter, summary_test_acc = [], []\n",
"\n", "\n",
" # 一般来说,我们利用Adam优化器来获得相对好的收敛\n", " # 一般来说,我们利用Adam优化器来获得相对好的收敛\n",
" # 当然你可以改成SGD或者是RMSprop\n", " # 当然你可以改成SGD或者是RMSprop\n",
" opt = paddle.optimizer.Adam(learning_rate=LR, parameters=net.parameters())\n", " myLayer = Opt_Classifier(n=N, depth=DEPTH) # 得到初始化量子电路\n",
" opt = paddle.optimizer.Adam(learning_rate=LR, parameters=myLayer.parameters())\n",
"\n", "\n",
" # 初始化寄存器存储正确率 acc 等信息\n",
" summary_iter, summary_test_acc = [], []\n",
"\n", "\n",
" # 优化循环\n", " # 优化循环\n",
" # 此处将训练集分为Ntrain/BATCH组数据,对每一组训练后得到的量子线路作为下一组数据训练的初始量子电路\n",
" # 故通过cir记录每组数据得到的最终量子线路\n",
" i = 0 # 记录总迭代次数\n",
" for ep in range(EPOCH):\n", " for ep in range(EPOCH):\n",
" # 将训练集分组,对每一组训练\n",
" for itr in range(N_train // BATCH):\n", " for itr in range(N_train // BATCH):\n",
"\n", " i += 1 # 记录总迭代次数\n",
" # 将经典数据编码成量子态 |psi>, 维度 [-1, 2 ** N]\n", " # 将经典数据编码成量子态 |psi>, 维度 [BATCH, 2 ** N]\n",
" input_state = paddle.to_tensor(datapoints_transform_to_state(train_x[itr * BATCH:(itr + 1) * BATCH], N))\n", " input_state = paddle.to_tensor(datapoints_transform_to_state(train_x[itr * BATCH:(itr + 1) * BATCH], N))\n",
"\n", "\n",
" # 前向传播计算损失函数\n", " # 前向传播计算损失函数\n",
" loss, train_acc, state_predict_useless, cir \\\n", " loss, train_acc, state_predict_useless, cir \\\n",
" = net(state_in=input_state, label=train_y[itr * BATCH:(itr + 1) * BATCH])\n", " = myLayer(state_in=input_state, label=train_y[itr * BATCH:(itr + 1) * BATCH]) # 对此时量子电路优化\n",
" if itr % 50 == 0:\n", " # 显示迭代过程中performance变化\n",
"\n", " if i % 30 == 5:\n",
" # 计算测试集上的正确率 test_acc\n", " # 计算测试集上的正确率 test_acc\n",
" input_state_test = paddle.to_tensor(datapoints_transform_to_state(test_x, N))\n", " input_state_test = paddle.to_tensor(datapoints_transform_to_state(test_x, N))\n",
" loss_useless, test_acc, state_predict_useless, t_cir \\\n", " loss_useless, test_acc, state_predict_useless, t_cir \\\n",
" = net(state_in=input_state_test,label=test_y)\n", " = myLayer(state_in=input_state_test,label=test_y)\n",
" print(\"epoch:\", ep, \"iter:\", itr,\n", " print(\"epoch:\", ep, \"iter:\", itr,\n",
" \"loss: %.4f\" % loss.numpy(),\n", " \"loss: %.4f\" % loss.numpy(),\n",
" \"train acc: %.4f\" % train_acc,\n", " \"train acc: %.4f\" % train_acc,\n",
...@@ -818,37 +899,25 @@ ...@@ -818,37 +899,25 @@
" # 存储正确率 acc 等信息\n", " # 存储正确率 acc 等信息\n",
" summary_iter.append(itr + ep * N_train)\n", " summary_iter.append(itr + ep * N_train)\n",
" summary_test_acc.append(test_acc) \n", " summary_test_acc.append(test_acc) \n",
" if (itr + 1) % 151 == 0 and ep == EPOCH - 1:\n",
" print(\"训练后的电路:\")\n",
" print(cir)\n",
"\n", "\n",
" # 反向传播极小化损失函数\n", " # 反向传播极小化损失函数\n",
" loss.backward()\n", " loss.backward()\n",
" opt.minimize(loss)\n", " opt.minimize(loss)\n",
" opt.clear_grad()\n", " opt.clear_grad()\n",
"\n", " \n",
" # 得到训练后电路\n",
" print(\"训练后的电路:\")\n",
" print(cir)\n",
" # 画出 heatmap 表示的决策边界\n", " # 画出 heatmap 表示的决策边界\n",
" heatmap_plot(net, N=N)\n", " heatmap_plot(myLayer, N=N)\n",
"\n", "\n",
" return summary_test_acc" " return summary_test_acc"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"以上都是我们定义的函数,下面我们将运行主程序。"
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 13,
"metadata": { "metadata": {},
"ExecuteTime": {
"end_time": "2021-03-02T09:15:50.771171Z",
"start_time": "2021-03-02T09:15:09.593720Z"
}
},
"outputs": [ "outputs": [
{ {
"name": "stdout", "name": "stdout",
...@@ -857,36 +926,27 @@ ...@@ -857,36 +926,27 @@
"训练集的维度大小 x (200, 2) 和 y (200, 1)\n", "训练集的维度大小 x (200, 2) 和 y (200, 1)\n",
"测试集的维度大小 x (100, 2) 和 y (100, 1) \n", "测试集的维度大小 x (100, 2) 和 y (100, 1) \n",
"\n", "\n",
"epoch: 0 iter: 0 loss: 0.0318 train acc: 1.0000 test acc: 0.5400\n", "epoch: 0 iter: 4 loss: 0.1547 train acc: 0.8500 test acc: 0.6400\n",
"epoch: 0 iter: 50 loss: 0.3359 train acc: 0.0000 test acc: 0.8200\n", "epoch: 3 iter: 4 loss: 0.1337 train acc: 0.9500 test acc: 0.8800\n",
"epoch: 0 iter: 100 loss: 0.0396 train acc: 1.0000 test acc: 0.8700\n", "epoch: 6 iter: 4 loss: 0.1265 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 0 iter: 150 loss: 0.0952 train acc: 1.0000 test acc: 1.0000\n", "epoch: 9 iter: 4 loss: 0.1247 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 0 loss: 0.1586 train acc: 1.0000 test acc: 1.0000\n", "epoch: 12 iter: 4 loss: 0.1261 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 50 loss: 0.1534 train acc: 1.0000 test acc: 1.0000\n", "epoch: 15 iter: 4 loss: 0.1268 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 100 loss: 0.0624 train acc: 1.0000 test acc: 1.0000\n", "epoch: 18 iter: 4 loss: 0.1269 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 150 loss: 0.0883 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 0 loss: 0.1627 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 50 loss: 0.1378 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 100 loss: 0.0669 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 150 loss: 0.0860 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 0 loss: 0.1658 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 50 loss: 0.1359 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 100 loss: 0.0671 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 150 loss: 0.0849 train acc: 1.0000 test acc: 1.0000\n",
"训练后的电路:\n", "训练后的电路:\n",
"--Rz(0.542)----Ry(3.456)----Rz(2.699)----*--------------x----Ry(6.153)--\n", "--Rz(0.542)----Ry(3.458)----Rz(2.692)----*--------------x----Ry(6.191)--\n",
" | | \n", " | | \n",
"--Rz(3.514)----Ry(1.543)----Rz(2.499)----x----*---------|----Ry(3.050)--\n", "--Rz(3.514)----Ry(1.543)----Rz(2.499)----x----*---------|----Ry(2.968)--\n",
" | | \n", " | | \n",
"--Rz(5.947)----Ry(3.161)----Rz(3.897)---------x----*----|----Ry(1.583)--\n", "--Rz(5.947)----Ry(3.161)----Rz(3.897)---------x----*----|----Ry(1.579)--\n",
" | | \n", " | | \n",
"--Rz(0.718)----Ry(5.038)----Rz(1.348)--------------x----*----Ry(0.030)--\n", "--Rz(0.718)----Ry(5.038)----Rz(1.348)--------------x----*----Ry(0.036)--\n",
" \n" " \n"
] ]
}, },
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 2 Axes>" "<Figure size 432x288 with 2 Axes>"
] ]
...@@ -900,7 +960,7 @@ ...@@ -900,7 +960,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"主程序段总共运行了 23.798545360565186 秒\n" "主程序段总共运行了 7.24103569984436 秒\n"
] ]
} }
], ],
...@@ -915,10 +975,11 @@ ...@@ -915,10 +975,11 @@
" Ntest = 100, # 规定测试集大小\n", " Ntest = 100, # 规定测试集大小\n",
" gap = 0.5, # 设定决策边界的宽度\n", " gap = 0.5, # 设定决策边界的宽度\n",
" N = 4, # 所需的量子比特数量\n", " N = 4, # 所需的量子比特数量\n",
" D = 1, # 采用的电路深度\n", " DEPTH = 1, # 采用的电路深度\n",
" EPOCH = 4, # 训练 epoch 轮数\n", " BATCH = 20, # 训练时 batch 的大小\n",
" EPOCH = int(200 * BATCH / Ntrain), \n",
" # 训练 epoch 轮数,使得总迭代次数 EPOCH * (Ntrain / BATCH) 在200左右\n",
" LR = 0.01, # 设置学习速率\n", " LR = 0.01, # 设置学习速率\n",
" BATCH = 1, # 训练时 batch 的大小\n",
" seed_paras = 19, # 设置随机种子用以初始化各种参数\n", " seed_paras = 19, # 设置随机种子用以初始化各种参数\n",
" seed_data = 2, # 固定生成数据集所需要的随机种子\n", " seed_data = 2, # 固定生成数据集所需要的随机种子\n",
" )\n", " )\n",
...@@ -949,7 +1010,7 @@ ...@@ -949,7 +1010,7 @@
"\n", "\n",
"[2] Farhi, Edward, and Hartmut Neven. Classification with quantum neural networks on near term processors. [arXiv preprint arXiv:1802.06002 (2018).](https://arxiv.org/abs/1802.06002)\n", "[2] Farhi, Edward, and Hartmut Neven. Classification with quantum neural networks on near term processors. [arXiv preprint arXiv:1802.06002 (2018).](https://arxiv.org/abs/1802.06002)\n",
"\n", "\n",
"[3] [Schuld, Maria, et al. Circuit-centric quantum classifiers. [Physical Review A 101.3 (2020): 032308.](https://arxiv.org/abs/1804.00633)" "[3] Schuld, Maria, et al. Circuit-centric quantum classifiers. [Physical Review A 101.3 (2020): 032308.](https://arxiv.org/abs/1804.00633)"
] ]
} }
], ],
...@@ -969,7 +1030,7 @@ ...@@ -969,7 +1030,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.7.10" "version": "3.7.11"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
...@@ -19,24 +19,25 @@ ...@@ -19,24 +19,25 @@
"\n", "\n",
"### Background\n", "### Background\n",
"\n", "\n",
"In the language of supervised learning, we need to enter a data set composed of $N$ groups of labeled data points $D = \\{(x^k,y^k)\\}_{k=1}^{N}$ , Where $x^k\\in \\mathbb{R}^{m}$ is the data point, and $y^k \\in\\{0,1\\}$ is the label associated with the data point $x^k$. **The classification process is essentially a decision-making process, which determines the label attribution of a given data point**. For the quantum classifier framework, the realization of the classifier $\\mathcal{F}$ is a combination of a quantum neural network (or parameterized quantum circuit) with parameters $\\theta$, measurement, and data processing. An excellent classifier $\\mathcal{F}_\\theta$ should correctly map the data points in each data set to the corresponding labels as accurate as possible $\\mathcal{F}_\\theta(x^k ) \\rightarrow y^k$. Therefore, we use the cumulative distance between the predicted label $\\tilde{y}^{k} = \\mathcal{F}_\\theta(x^k)$ and the actual label $y^k$ as the loss function $\\mathcal {L}(\\theta)$ to be optimized. For binary classification tasks, we can choose the following loss function,\n", "In the language of supervised learning, we need to enter a data set composed of $N$ pairs of labeled data points $D = \\{(x^k,y^k)\\}_{k=1}^{N}$ , Where $x^k\\in \\mathbb{R}^{m}$ is the data point, and $y^k \\in\\{0,1\\}$ is the label associated with the data point $x^k$. **The classification process is essentially a decision-making process, which determines the label attribution of a given data point**. For the quantum classifier framework, the realization of the classifier $\\mathcal{F}$ is a combination of a quantum neural network (or parameterized quantum circuit) with parameters $\\theta$, measurement, and data processing. An excellent classifier $\\mathcal{F}_\\theta$ should correctly map the data points in each data set to the corresponding labels as accurate as possible $\\mathcal{F}_\\theta(x^k ) \\rightarrow y^k$. Therefore, we use the cumulative distance between the predicted label $\\tilde{y}^{k} = \\mathcal{F}_\\theta(x^k)$ and the actual label $y^k$ as the loss function $\\mathcal {L}(\\theta)$ to be optimized. For binary classification tasks, we can choose the following loss function,\n",
"\n", "\n",
"$$\n", "$$\n",
"\\mathcal{L}(\\theta) = \\sum_{k=1}^N |\\tilde{y}^{k}-y^k|^2. \\tag{1}\n", "\\mathcal{L}(\\theta) = \\sum_{k=1}^N 1/N \\cdot |\\tilde{y}^{k}-y^k|^2. \\tag{1}\n",
"$$\n", "$$\n",
"\n", "\n",
"### Pipeline\n", "### Pipeline\n",
"\n", "\n",
"Here we give the whole pipeline to implement a quantum classifier under the framework of quantum circuit learning (QCL).\n", "Here we give the whole pipeline to implement a quantum classifier under the framework of quantum circuit learning (QCL).\n",
"\n", "\n",
"1. Apply the parameterized quantum circuit $U$ on the initialized qubit $\\lvert 0 \\rangle$ to encode the original classical data point $x^k$ into quantum data that can be processed on a quantum computer $\\lvert \\psi_{in}\\rangle^k$.\n", "1. Encode the classical data $x^k$ to quantum data $\\lvert \\psi_{\\rm in}\\rangle^k$. In this tutorial, we use Angle Encoding, see [encoding methods](./DataEncoding_EN.ipynb) for details. Readers can also try other encoding methods, e.g., Amplitude Encoding, and see the performance.\n",
"2. Apply the parameterized circuit $U(\\theta)$ with the parameter $\\theta$ on input states $\\lvert \\psi_{in} \\rangle^k$, thereby obtaining the output state $\\lvert \\psi_{out} \\rangle^k = U(\\theta)\\lvert \\psi_{in} \\rangle^k$.\n", "2. Construct the parameterized quantum circuit (PQC), corresponds to the unitary gate $U(\\theta)$.\n",
"3. Measure the quantum state $\\lvert \\psi_{out}\\rangle^k$ processed by the quantum neural network to get the estimated label $\\tilde{y}^{k}$.\n", "3. Apply the parameterized circuit $U(\\theta)$ with the parameter $\\theta$ on input states $\\lvert \\psi_{\\rm in} \\rangle^k$, thereby obtaining the output state $\\lvert \\psi_{\\rm out} \\rangle^k = U(\\theta)\\lvert \\psi_{\\rm in} \\rangle^k$.\n",
"4. Repeat steps 2-3 until all data points in the data set have been processed. Then calculate the loss function $\\mathcal{L}(\\theta)$.\n", "4. Measure the quantum state $\\lvert \\psi_{\\rm out}\\rangle^k$ processed by the quantum neural network to get the estimated label $\\tilde{y}^{k}$.\n",
"5. Continuously adjust the parameter $\\theta$ through optimization methods such as gradient descent to minimize the loss function. Record the optimal parameters after optimization $\\theta^* $, and then we obtain the optimal classifier $\\mathcal{F}_{\\theta^*}$.\n", "5. Repeat steps 3-4 until all data points in the data set have been processed. Then calculate the loss function $\\mathcal{L}(\\theta)$.\n",
"6. Continuously adjust the parameter $\\theta$ through optimization methods such as gradient descent to minimize the loss function. Record the optimal parameters after optimization $\\theta^* $, and then we obtain the optimal classifier $\\mathcal{F}_{\\theta^*}$.\n",
"\n", "\n",
"![QCL](figures/qclassifier-fig-pipeline.png \"Figure 1: Flow chart of quantum classifier training\")\n", "<img src=\"./figures/qclassifier-fig-pipeline.png\" width=\"700px\" /> \n",
"<div style=\"text-align:center\">Figure 1: Flow chart of quantum classifier training </div>" "<center> Figure 1: Flow chart of quantum classifier training </center>"
] ]
}, },
{ {
...@@ -51,50 +52,49 @@ ...@@ -51,50 +52,49 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 1, "execution_count": 1,
"metadata": { "metadata": {},
"ExecuteTime": {
"end_time": "2021-03-09T04:03:35.665758Z",
"start_time": "2021-03-09T04:03:32.186676Z"
}
},
"outputs": [], "outputs": [],
"source": [ "source": [
"import time\n", "# Import numpy and paddle\n",
"import matplotlib\n",
"import numpy as np\n", "import numpy as np\n",
"import paddle\n", "import paddle\n",
"from numpy import pi as PI\n",
"from matplotlib import pyplot as plt\n",
"\n", "\n",
"from paddle import matmul, transpose\n", "# To construct quantum circuit\n",
"from paddle_quantum.circuit import UAnsatz\n", "from paddle_quantum.circuit import UAnsatz\n",
"from paddle_quantum.utils import pauli_str_to_matrix" "# Some functions\n",
"from numpy import pi as PI\n",
"from paddle import matmul, transpose # paddle matrix multiplication and transpose\n",
"from paddle_quantum.utils import pauli_str_to_matrix,dagger # N qubits Pauli matrix, complex conjugate\n",
"\n",
"# Plot figures, calculate the run time\n",
"from matplotlib import pyplot as plt\n",
"import time"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Parameters used for classification"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 2,
"metadata": { "metadata": {},
"ExecuteTime": {
"end_time": "2021-03-09T04:03:35.682126Z",
"start_time": "2021-03-09T04:03:35.668825Z"
}
},
"outputs": [], "outputs": [],
"source": [ "source": [
"# These are the main functions that will be used in the tutorial\n", "Ntrain = 200 # Specify the training set size\n",
"__all__ = [\n", "Ntest = 100 # Specify the test set size\n",
" \"circle_data_point_generator\",\n", "gap = 0.5 # Set the width of the decision boundary\n",
" \"data_point_plot\",\n", "N = 4 # Number of qubits required\n",
" \"heatmap_plot\",\n", "DEPTH = 1 # Circuit depth\n",
" \"Ry\",\n", "BATCH = 20 # Batch size during training\n",
" \"Rz\",\n", "EPOCH = int(200 * BATCH / Ntrain)\n",
" \"Observable\",\n", " # Number of training epochs, the total iteration number \"EPOCH * (Ntrain / BATCH)\" is chosen to be about 200\n",
" \"U_theta\",\n", "LR = 0.01 # Set the learning rate\n",
" \"Net\",\n", "seed_paras = 19 # Set random seed to initialize various parameters\n",
" \"QC\",\n", "seed_data = 2 # Fixed random seed required to generate the data set\n"
" \"main\",\n",
"]"
] ]
}, },
{ {
...@@ -103,14 +103,21 @@ ...@@ -103,14 +103,21 @@
"source": [ "source": [
"### Data set generation\n", "### Data set generation\n",
"\n", "\n",
"One of the key parts in supervised learning is what data set to use? In this tutorial, we follow the exact approach introduced in QCL paper to generate a simple binary data set $\\{(x^{(i)}, y^{(i)})\\}$ with circular decision boundary, where the data point $x^{(i)}\\in \\mathbb{R}^{2}$, and the label $y^{(i)} \\in \\{0,1\\}$. The figure below provides us a concrete example.\n", "One of the key parts in supervised learning is what data set to use? In this tutorial, we follow the exact approach introduced in QCL paper to generate a simple binary data set $\\{(x^{k}, y^{k})\\}$ with circular decision boundary, where the data point $x^{k}\\in \\mathbb{R}^{2}$, and the label $y^{k} \\in \\{0,1\\}$. The figure below provides us a concrete example.\n",
"\n", "\n",
"![QC-fig-data](./figures/qclassifier-fig-data.png \"Figure 2: Generated data set and the corresponding decision boundary\")\n", "<img src=\"./figures/qclassifier-fig-data.png\" width=\"400px\" /> \n",
"<div style=\"text-align:center\">Figure 2: Generated data set and the corresponding decision boundary </div>\n", "<center> Figure 2: Generated data set and the corresponding decision boundary </center>\n",
"\n", "\n",
"For the generation method and visualization, please see the following code:" "For the generation method and visualization, please see the following code:"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Generate a binary classification data set"
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 3,
...@@ -132,11 +139,13 @@ ...@@ -132,11 +139,13 @@
" :return: 'Ntrain' samples for training and\n", " :return: 'Ntrain' samples for training and\n",
" 'Ntest' samples for testing\n", " 'Ntest' samples for testing\n",
" \"\"\"\n", " \"\"\"\n",
" # Generate \"Ntrain + Ntest\" pairs of data, x for 2-dim data points, y for labels.\n",
" # The first \"Ntrain\" pairs are used as training set, the last \"Ntest\" pairs are used as testing set\n",
" train_x, train_y = [], []\n", " train_x, train_y = [], []\n",
" num_samples, seed_para = 0, 0\n", " num_samples, seed_para = 0, 0\n",
" while num_samples < Ntrain + Ntest:\n", " while num_samples < Ntrain + Ntest:\n",
" np.random.seed((seed_data + 10) * 1000 + seed_para + num_samples)\n", " np.random.seed((seed_data + 10) * 1000 + seed_para + num_samples)\n",
" data_point = np.random.rand(2) * 2 - 1\n", " data_point = np.random.rand(2) * 2 - 1 # 2-dim vector in range [-1, 1]\n",
"\n", "\n",
" # If the modulus of the data point is less than (0.7 - gap), mark it as 0\n", " # If the modulus of the data point is less than (0.7 - gap), mark it as 0\n",
" if np.linalg.norm(data_point) < 0.7-boundary_gap / 2:\n", " if np.linalg.norm(data_point) < 0.7-boundary_gap / 2:\n",
...@@ -158,10 +167,22 @@ ...@@ -158,10 +167,22 @@
" print(\"The dimensions of the training set x {} and y {}\".format(np.shape(train_x[0:Ntrain]), np.shape(train_y[0:Ntrain])))\n", " print(\"The dimensions of the training set x {} and y {}\".format(np.shape(train_x[0:Ntrain]), np.shape(train_y[0:Ntrain])))\n",
" print(\"The dimensions of the test set x {} and y {}\".format(np.shape(train_x[Ntrain:]), np.shape(train_y[Ntrain:])), \"\\n\")\n", " print(\"The dimensions of the test set x {} and y {}\".format(np.shape(train_x[Ntrain:]), np.shape(train_y[Ntrain:])), \"\\n\")\n",
"\n", "\n",
" return train_x[0:Ntrain], train_y[0:Ntrain], train_x[Ntrain:], train_y[Ntrain:]\n", " return train_x[0:Ntrain], train_y[0:Ntrain], train_x[Ntrain:], train_y[Ntrain:]\n"
"\n", ]
"\n", },
"# Visualize the generated data set\n", {
"cell_type": "markdown",
"metadata": {},
"source": [
"Visualize the generated data set"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def data_point_plot(data, label):\n", "def data_point_plot(data, label):\n",
" \"\"\"\n", " \"\"\"\n",
" :param data: shape [M, 2], means M 2-D data points\n", " :param data: shape [M, 2], means M 2-D data points\n",
...@@ -178,9 +199,16 @@ ...@@ -178,9 +199,16 @@
" plt.show()" " plt.show()"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this tutorial, we use a training set with 200 elements, a testing set with 100 elements. The boundary gap is 0.5."
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 5,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-09T04:03:37.244233Z", "end_time": "2021-03-09T04:03:37.244233Z",
...@@ -200,7 +228,7 @@ ...@@ -200,7 +228,7 @@
}, },
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAD4CAYAAADhNOGaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAAApn0lEQVR4nO2df6xexXnnP4+vYydu1Ma89mYdwNeQZZuQ3QrCVZSkUpqkJCHuClOVtiSG3qRUXm6b7kpRqxhZ6kZsrdL+Q6gSRCxKcLlXCQlVFLclYoGEXWk3kFx2AfNDxsYJYErCxQ6RIigJZvaPc974+PX5/XPOe74fafSeM+fX886ZM8/MPM/MmHMOIYQQw2VV1wIIIYToFikCIYQYOFIEQggxcKQIhBBi4EgRCCHEwFndtQBl2LBhg9uyZUvXYgghRK944IEHXnDObZyM76Ui2LJlC8vLy12LIYQQvcLMnoqLV9eQEEIMHCkCIYQYOFIEQggxcKQIhBBi4EgRCCHEwKlFEZjZzWb2vJk9knDczOxvzeyQmT1sZu+MHJs3s4NhmK9DHiHKsLQEW7bAqlXB79JS1xL5ic/p5JNsPsmSiXOucgDeB7wTeCTh+Fbgm4AB7wbuD+NPAw6Hv+vD7fVZz7vgggtcn1lcdG521jmz4HdxsWuJxOKic+vWOQcnwrp1ejeTNJVOdXwTPr1Dn2SJAiy7uDI6LrJMALakKIIvAh+L7B8ANgEfA76YdF5S6LMiiMsgZs4tLHQtWbP4rvxmZ09+J+MwO9u1ZH7RRDrVVWj69A59kiVKkiJoy0ZwOvBMZP9IGJcUfwpmtsPMls1seWVlpTFBm2bXLnjppZPjnIMbb6y/6ehL03RpCXbsgKeeCv7rU08F+z41lZ9+ulj8UHkqdjhStXSK+yZeeimIL4JP79AnWfLQG2Oxc26Pc27OOTe3ceMpI6R7Q9KH5FzxjJ+GT4VvXR96k2zeXCy+SXxR4JMsLYFZ/LEy6TT+n3UpF5/eoU+y5KEtRfAscGZk/4wwLil+akn6kKDe2oJPhW8fake7d8O6dSfHrVsXxLeJTwp8kl27ApkmMSueTtH/mUTRQrPKO6yifOOu9SU/5Sauv6hMIN1G8FucbCz+rjthLP4+gaF4fbh9Wtaz6rARdNVnHddvGNd/WFU+s/hnmNX4Z3Lia3/pJD7YMZpMq6byFBSXJel/VjWsLi46NxqduM9olH2fKjaKtGt9yE+T0KSxGPgy8Bzwc4J+/iuBq4CrwuMGfAF4EtgPzEWu/UPgUBg+med5VRVBlxb9tMw/fn4d8vlU+PrqQeEjTSlw3/JUmlKpUmiW+Z9V/pdP31keGlUEbYeqiiDp5c3MNK+9o7WVaPilX8qWr0jm6qrwTaoF+Vg78pGmChbf8pRP/zOP8k3Kv1Wu7QIpgghptZGmC83FRefWrDn5WWvWnPysumqFbWdA1fyr01Qa+panfPqfWcojTdYq13aBFEGErP7Jppt3WR9T35qbY/oqt280ocB9fDe+/M+swjrtnlWu7QIpgghxL6+O2lJd+FaLyItPBmpxMnXnKR+6O+JkKPs/0/5PVr6ucm3bSBFMsLgY2AS6aBHkla/rD60ovtV+xMn43q1Tlwx1fzvTZEyWIoghy1bQh8LXJ3woIETz+FC4tSlDU+6lXSBFEEOarWA0quURXtFGK6OPLRlRDB+6O9qWoUq+9umbkCKIIc6DB5x73eumrwDzrWYi+svQWgRJ+FTA5yVJEfRmrqEm2L4dbr4ZRqMTcaMRfOlLwbFpwqcpJ0S/8WH6hK5l8HkqkDJYoCT6xdzcnFteXu5ajF6xalWQYScxg9dea18e0W+WloJKxNNPB3MC7d7dfuWpSxmSJsubnYUf/KAdGcpgZg845+ZOiZciGAZ9zbhC+EhfK1ZJimDQXUNp+DoVcFm6bkoLMU1UmWbax7JFiiCGNvr/imSGOjLO9u2wZ0/QAjALfvfsmT5biBBtULZi5a1tIc6C7HtoeqnKpj0SinjwyNtHiPop4/Ezec3CQvF7dO3thNxH89O0j3KRzNB1xhFi2shTuYor9OuokHU9BiNJEchYHEPThtUihqa+GqWE8JWs73vcfRN1tzaL/w6LlgldO200aiw2s4vM7ICZHTKznTHHrzOzB8PwhJm9GDl2PHJsXx3yVKVpw2oRQ1NZo5SPBikhmqJIfs9aOjVuzE1SfbnocqveOm3ENROKBGCGYOWxs4E1wEPAuSnn/ylwc2T/p0Wf2XTXkHPNjhps2kYgu4IYEkXze1Z3a571Sqp00XY5IpmmbATAe4A7I/tXA1ennP9/gA9F9r1UBE1TJDMUzTiyK4ghUTS/l11DYFJB9LFy1aQiuBS4KbJ/BfD5hHNnCdY2nonEvQosA/cBl+R55jQogibp2iAlRJuUye9plaskRTH2EoITU9j3ZY6hMUmKoO1xBJcBtzvnjkfiZl1gvPg48Dkze2vchWa2w8yWzWx5ZWWlDVl7S5XBLkL0jTL5ffv2wDj72mvBb3Q8TdKYmxtuONHHfzwswbwZB1CROhTBs8CZkf0zwrg4LgO+HI1wzj0b/h4G7gXOj7vQObfHOTfnnJvbuHFjVZmngiQDmbcGKSEaoIn8nqQoyk7e2PYA0sLENROKBGA1cBg4ixPG4nfEnPc24AeE8xuFceuBteH2BuAgKYbmcVDXUHY/Zx+nyBWiLHXk9zz3KNsN5csAUpocUAZsBZ4g8B7aFcZdA1wcOeezwLUT170X2B8qj/3AlXmeJ0UQLJwjg7AQyRR1yMhTAJdxxPBpAGmjiqDtMHRFsLgYn1lkEBYioG6X0rL3dS5/K6KN7zpJEWjSuRR8HZSV1h8pg7AQxfvy0waZRcuBXbtgfr7Y5I15jNnj0cxF71EbcdrB99DWgDJfB2WlDXjxQT4huqZoX35Si2A0ql4OxJUla9YE9x53WyV19bZlI1CLIAGfl3ZMqh2MRppWWggo7lKa5HkE1cuBSXfU0Sgo4o8eDX6feirYTqKN6eKlCBLImo+kS5Iy7fXXdyOPEL5R1KU0aezAsWPx5xctB6LuqG98I/z85/mum51tp3InRZBAWo2ia9uBFpkRIp0y30jc2IEmBmfmVSKtjv2J6y/yPXRpI6hrXnIhhP80YStMs0fEubvWOSYI2QiKkVSjuOMOf20HQoh6aaL1nda1G22RAGzYAJdf3vzSllIEMYy7fq64Iti/9dYTTUWfbQdCiPpJm5eoTDdxknKBE/fasAE++cl4I3ITFU8pggmyFpfWhG5CCKi2EP2kcoGT73X0aLpBue6K5yAVQZoWz3IbrWuCq64NzkKIatTpYh53rzRqr3jGGQ58D1WMxVnGnzwDUaoab3werCaEyEed634UWRWtSlmBFq8PyFo8uo3FpbtewFoIUZ06v+Oke00yGgVG5bLG6kYXr+8TWcbeNubyl8FZiP5TZ1kRd681a4KCf2xQXlyEF15oZrzQ4BRBlrG3jcFaMjgL0X/qLCvi7nXzzUHBH+etVDtx/UW+hyZtBHWSZEuQjUCIYeDbAlFoPYITtPFytIKYEMPGxwpfo4oAuAg4ABwCdsYc/wSwAjwYhj+KHJsnWKLyIDCf53l9WJim6ZWGhBB+U6QMaKtimKQIVlftWjKzGeALwIeAI8D3zGyfc+6xiVNvc859auLa04D/BswBDnggvPbHVeXqGhmEhRg2ecuA8cC08TiC8cA0aG8iyTqMxe8CDjnnDjvnfgZ8BdiW89qPAHc5546Fhf9dBK2L3iODsBDDJm8ZkDUwrY3Bp3UogtOBZyL7R8K4SX7HzB42s9vN7MyC12JmO8xs2cyWV1ZWahC7WdpwQxVC+EveMiBrmcyy01gUoS330X8Etjjnfo2g1r+36A2cc3ucc3POubmNGzfWLmDdaM0AIYbN9u3B+sYzM8H+zEywP1kGpLUc2lopsQ5F8CxwZmT/jDDuFzjnjjrnXgl3bwIuyHttn0mbtVAIMd0sLcHevXD8eLB//HiwP1mbT2s5tGVrrEMRfA84x8zOMrM1wGXAvugJZrYpsnsx8Hi4fSfwYTNbb2brgQ+HcUII0Wvy1ubTeg/asjVW9hpyzr1qZp8iKMBngJudc4+a2TUErkr7gP9iZhcDrwLHCNxJcc4dM7P/TqBMAK5xziWsEiqEEP0hae6guPjt2+N7DHbvPtmjCJqxNQ5u0jkhhGiD1atPdAtFmZmBV1/Nf5+lpaAV8fTTQUtg9+76J52r3CIQQghxKnFKIC0+iaTWQp0MbtI5IYRog9nZYvFdIkUghBAN0KexRFIEYrqpa1im1hYVBenTWCIpghj0zU8JdQ3LbGt4p5g6+jKWSF5DE0xOAAVBc85XTS5SqGstQa0tKqYELVWZk7aGdIsWKDIsM60ZqKlkxZQjRTCBvnkPKdtXl3dYZlbXj6aSFVOOFMEE+uY9o0r/fF63jaxmYJ/cP4QogRTBBPrmPaNKX11et42sZmDd7h/yRhAZtJ5F4pYt8z00vVSl1hP2CLP49f7M6ntGm+uK+riQrfCKJrMICUtVqkUQQ19cvgZBHX11WdWrss3AMtU2eSOIDDrJInHawffQh8XrRU1UrR7lvT6pGZgWX0auNlo4otc0mUVIaBF0XqiXCVIEA6NKX12Vbp+0wr7sfdvshhK9pMkskqQI1DUk/CGpq6VKX10Vf+C0NnrZ+8obQWTQRRaRIhB+0NQ0DlVsDGmFfdn79mkCGtEJnWSRuGZC0QBcBBwADgE7Y45/GngMeBi4B5iNHDsOPBiGfXmep66hKaSp9nAVG0OaTPL+ET2EprqGzGwG+ALwUeBc4GNmdu7Eaf8PmHPO/RpwO/A3kWMvO+fOC8PFVeURPaWpId1VqldpbfS0+9bhBK6xBqJN4rRDkQC8B7gzsn81cHXK+ecD/zuy/9Oiz1SLYArxwYgaZ5Quaqiuo6Wg1oZoCBo0Fp8OPBPZPxLGJXEl8M3I/uvNbNnM7jOzS5IuMrMd4XnLKysrlQQWHtK1ETXJRgHFDNV1OIHX6UiuloXIQ5x2KBKAS4GbIvtXAJ9POPdy4D5gbSTu9PD3bOAHwFuznqkWwZTS9pDu6PNmZuppkdThBJ50DygmS56WhYbRDwqaGkdAzq4h4ELgceDfpNzrFuDSrGdKEQyQMgVWWlfPuHBOKnDLjuKpo4sr6R5m9Y6hUBfU4GhSEawGDgNnAWuAh4B3TJxzPvAkcM5E/Ppx6wDYABwEzs16phRBDylb81xcdG40OrUwyyqw4gq5NWuce93rsgv/pAI8z3+oy0aQpKSKKJSs1okPdhnRKo0pguDebAWeCAv7XWHcNcDF4fbdwI+YcBMF3gvsD5XHfuDKPM+TIugZZQvHuOvyFlhJhVyREJWxyH+oo7uljhZKVkGv6S4GR6OKoO0gRdAz6p6OIU+BlafbJy2sWnVyAd527TnP87IUzsJC/D0WFrr5T6JzkhSBRhaL5ik7RiBuneAoaaN4q64k9NprJ++3vXRdkhfV1q2B948ZXHFF+kjsO+6Iv/c4vmtPLeENUgSiecpOxzAzk3wsq8DavTsoLKsQdddse+m6uAFr8/Owd+8JBencyddMupi2veCO6C9xzQTfg7qGekZZG0Fa102efvesbqXZ2eTuk8muJx88bPLYPaIyq+tHTIC6hkRnlK15zs4mx+eptaZdPx4gdsMNMBrFnxet7ftQe87TDRWVWV0/Ii9x2sH3oBbBQGhzUZqua/t5yGoRFFlwRwwS5DUkeknVgizv9X0oMOMU1tg7qk2Z+5BWIhYpAjFdDLUw6vp/96X1JGJJUgQWHOsXc3Nzbnl5uWsxRFeMJ4iLTsy2bp08XppmaSnwXDp+/NRjs7OBzUV4jZk94Jybm4yXsVj0jzpn5xT5GCvfOCUAzY2nEK0gRSC6p+hUyW0P7ppm8qZ9nPKN4pymue4xUgSiW8qsVdz24C6fqbLeQJG0z6Nk61pnWrRPnOHA9yBj8RRRZtBTnwyWTRp3s9Ih69lF0r7IJH4asOYtyGtIeEnZGTC79p7JQ9MKK60gz/PsImmfNRNskXcnOiNJEchrSHTLli3xk8tNgxdK0/9t1apT5xuCYOTz5s3Zzy4q39JSYCt4+ung/j/9KRw9mv960TnyGhJ+Ms3TIDRt1E6zleR5dtG037795PWbr79+et/dwJAiEN3S5Rw+TS/s3rRRO60gz/PsImkfl1Y+zL8k6iGuv6hoAC4CDgCHgJ0xx9cCt4XH7we2RI5dHcYfAD6S53l12Aj60MUsGqSNhd3bMGonyVjns/tknBep0OCaxTMES1SezYk1i8+dOOePgRvD7cuA28Ltc8Pz1xKsefwkMJP1zKqKQPlatLawe5c1jjqevbjo3MxMelqJ3pCkCCobi83sPcBnnXMfCfevDlsafxU5587wnO+Y2Wrgh8BGYGf03Oh5ac+saiyeZvukyEmaofW115RJIH4qjyjjtBK9oUlj8enAM5H9I2Fc7DnOuVeBnwCjnNcCYGY7zGzZzJZXVlYqCayBqSKzD71KJmna9tAWWaOJhziAb0rpjbHYObfHOTfnnJvbuHFjpXtpYKrI9Jgpm0nKjJT2lTSlJ++gqaIORfAscGZk/4wwLvacsGvoV4CjOa+tnWn2WPQW32rJWR4vZTPJNE2Il6T0ZmaCtAK/3qkoT5zhoEgAVgOHCYy9Y2PxOybO+RNONhZ/Ndx+Bycbiw/TgrHYOXkNtUoZw6sPL2hh4YShdGYm2M+i7EhpH0l7b/K46CU0OcUEsBV4gsDrZ1cYdw1wcbj9euBrBG6i3wXOjly7K7zuAPDRPM/TFBOeklR4F51PyIdCpqwM07ZgfNF3OjOj2pXHNKoI2g5SBB6SVnAWrSX7UJiWlcEXJdZ0ayrpnaqF4DVJikBzDYl6SHO3hGKumFmunW1QRYbJOXl2725vtG1bq7clve9JhuRu2wM015BoljR3y6KGVx/curJkSDN+T87J0+aUC0nG6ssvr9egG/dO45BPdj+Iayb4HtQ15CF5Rurm7a7wpXuliKEUnBuNuu8KyeqyqTMdo+9Uo497AbIRiEapu/D2wWuoqKHUh37xPAvINFE4+6C8RSZSBKJ5fCi82yCr1t1lLTjvAjJNPXsI77/HJCkC2QhEfXTZN94mWbaKLvvFowPlkpiZSb9H0cF/4/OvuCLYv/XW6X7/U4gUgRBFyTKUdj1XyVghJ3H8ePKxolNkTNOUGh7R9kB8KQIhspj8KiGodY9Gp57b5lwlWaVFUqsgrbVQdIqMaZpSwxM60a1x/UW+B9kIRCPE9XFnGUG76hfPu7BOUQNu2uC/uP86TVNqeEKT4ynRgDIhUkgaiPWGN/i5QHve9RKKDm5Luu9oBC+/3J/06TFNjqfUgDIxDMp2riZ1ccQVctD9QKm86yUUNeAnDf6D+PSJHo+er6l8S9PFeEopAjE9VOlcLVqwd20Qbqq0SJqe+9ix+POPHdMC9jXTyTT5cf1FvgfZCEQsVTpXk64djaoNlCpjQ8hzTdsDuHyYCHDKib720SgIdZue0IAyMfVUMVxmTSlRxiBcprBeWDj1fyRd06ahWiOHG6Wt5JUiENNP1Vpr3QVrmXUYkpSZDzVvjRxujLYaXEmKQF5Dwn/yer60NQVzXoq6f6RN7dzmFNyiddqaeb0RryEzO83M7jKzg+Hv+phzzjOz75jZo2b2sJn9fuTYLWb2fTN7MAznVZFHTCFFDMBZ6xC3TVGDbprBumvjtGiUrmder+o1tBO4xzl3DnBPuD/JS8AfOOfeAVwEfM7M3hQ5/ufOufPC8GBFecS0UXTkqk/zHdW1DoOZ3DGnnE48hSJUVQTbgL3h9l7gkskTnHNPOOcOhtv/AjwPbKz4XNF38vr75/WX94Xo/9q1C+bn87dQ4koDM7jqqmA7Kb3anphG1E7njdk4w0HeALwY2bbofsL57wIeB1aF+7cQLFr/MHAdsDbl2h3AMrC8efPmei0ool2KuEj0yW2xDtePotNcyJtnKmjLDk9ZryHgbuCRmLBtsuAHfpxyn01hof/uiTgD1hK0KP4iSx4nr6H+U6Rw71NB15TSSrtvnxSliKXN6axKK4K0EBbsm1ykoE8475eB/wtcmnKv9wP/lOe5UgQ9p6i/f1/cFpuagC3tvpr0rfek6fK660FJiqCqjWAfMB9uzwPfmDzBzNYAXwf+3jl3+8SxTeGvEdgXHqkoj+gDRVwkik6a1iVNuX6k3bdrdxNRmTQzWFuzfFdVBNcCHzKzg8CF4T5mNmdmN4Xn/B7wPuATMW6iS2a2H9gPbAD+sqI8og/kdZGoY2L2Ng2pTbl+pN23SFrKoOwlabq8NV+JuGaC70FdQ1NAnu6eOkYKt21faKobK+2+Wc/sk51lgKS9nrpNQGhksegdScMtITk+St45+6cdpYP3JPWA1j1YXusRxKDWsuekDbCqMrW0r2MQmkLp4D1J4yDH4wuiq6K+4Q31P3+wikBrbveA3buDQn8S5/JZy2RIDVA69J6XXz6xffRo/WXVYBWB1tzuAdu3J3cB5anNdj1uvwnKNGOnMR0GRBtl1WAVgVrLPWF2Nj4+T22283H7NVO2GTtt6TAw2iirBmsslv2sJ/g2tXSXKNMOkjpfu4zFE6i13BNUmz2BmrGDpI2yarCKQOVLj/BpaukukdF3kLRRVg1WEUBy+SK3UuElasZOHXnLmqbrQqvrvV3/meySHtvjYLgVUeEJ4wzYl7mXRCo+lTWDNRYnIXucEKINuihrZCzOiexxQog28KmskSKYQPY4IUQb+FTWSBFMIHucEKINfCprpAgmkFupEKINfCpr5DUUw/btKviFEM3g46J7lVoEZnaamd1lZgfD3/UJ5x2PrE62LxJ/lpndb2aHzOy2cFlLIYToBUXHHPk663HVrqGdwD3OuXOAe8L9OF52zp0Xhosj8X8NXOec+3fAj4ErK8ojhBCtUKZQ93XW46qKYBuwN9zeS7AAfS7CBes/CIwXtC90vRBCdEmZQj3LZbSrWQ2qKoI3O+eeC7d/CLw54bzXm9mymd1nZpeEcSPgRefcq+H+EeD0pAeZ2Y7wHssrKysVxRZCiGqUGQeQ5jLaZbdRpiIws7vN7JGYsC16XrgwctIw5dlwNNvHgc+Z2VuLCuqc2+Ocm3POzW3cuLHo5UIIUStlxgGkuYx22W2UqQiccxc65/5DTPgG8CMz2wQQ/j6fcI9nw9/DwL3A+cBR4E1mNvZcOgN4tvI/EkKIFigzDiDNZbTLkcZVu4b2AfPh9jzwjckTzGy9ma0NtzcAvw48FrYgvg1cmna9EEL4SN5xAJP9/hA/k2iXI42rKoJrgQ+Z2UHgwnAfM5szs5vCc94OLJvZQwQF/7XOucfCY58BPm1mhwhsBn9XUR4hhGiEOENu1vTQRfr9Ox1p7JzrXbjgggtcURYXnZuddc4s+F1cLHyLXPep6zlCiO4Zf88QfNNBcR6Edeuyv+/xtZNhdjb9eU2VH8CyiylTOy/Uy4SiimBxMXhp0Rdh5tzCQqHbxN4nmhmyjgsh+kPc95y3QB8zqTyi5U8XJCmCQaxHkDTvtxncemv+4d1Z84drLQMhpoek7zmKWdAtVPQeXZUJg16PIMnq7lwx16wsq75P84sLIaqR57vNMuQm9ftv3erXcriDUARpL6tIIZ1l1fdpfnEhRDWyvts8htw4z6L5edi716/5hgahCHbvDl5CHEUK6Syrvk/ziwshqhH3PY/LkSJTRk96Ft1xh4fzDcUZDnwPZbyGFhbSrf4LC87NzATxMzPJhmR5DQkxHJr4nrs0IDNkr6ExSS91YSH+xRT1KqoDKRIhpoOkb7moS2mdJCmCQXgNZbF6NRw/fmr8zAy8+uqp8U0xHnwSbTauW6cV0oToG2nfMnT3nQ/aayiLOCWQFt8Uvs5VLoTIJjryeH4++Vv2aYnKMWoR4E+LYNWqoJE4SZavshCiW+JaAHF0/S2rRZDCjh3F4ptC7qdC9JO41nwcvn7LUgTADTfAwkLQAoDgd2EhiB/TxspBcj8VohpdrfCVZzxS2rfcldy/IM6C7Hso6zVUljxzDNXl6SOvISHK0eVcX0meQFGPoCQ52pQbeQ2VJ22+kN275ekjhA90Oa/P0hJcfnn8MZ/mI0qyEUgR5CDNiLt5c/xLHI3ghReal00IEZD0nULwPR47Fnyvu3c3U0nbsAGOHj01PqtAb9NJpBFjsZmdZmZ3mdnB8Hd9zDkfMLMHI+FfxwvYm9ktZvb9yLHzqsjTFGlG3KS+waNHu59ISoghkWaIPXq0+Xl9rr++nI3PByeRqsbincA9zrlzgHvC/ZNwzn3bOXeec+484IPAS8D/iJzy5+PjzrkHK8rTCGlG3LSXJf9/Idoj7juNo6mxOWXHB3jhJBJnOMgbgAPApnB7E3Ag4/wdwFJk/xbg0qLPbdtY7FyyEXdxMdlAFDd3SPQ+o1EQZBgWoh7SvkcfFoZJoi0nEZqYawh4MbJt0f2E878F/KfI/i2hMnkYuA5Ym+e5XSiCNEajZE+BKFkrHjXp4SBvJDEUsjx4xhNLDvEbKK0IgLuBR2LCtsmCH/hxyn02ASvA6ybiDFgL7AX+IuX6HcAysLx58+YWkiw/ed2/8mTQJiae0hKaYkjkWWJyqN9AUy2C3F1DwH8F9qQcfz/wT3me61uLwLl8Ne6k6WebbrJ2OduhEF0w2QW7apW+AeeSFUFVY/E+YD7cnge+kXLux4AvRyPMbFP4a8AlBC2NXjK5+EScgSiPF0ATngJaQlP0gTpH10a/xxdeSHYr1TcQUFURXAt8yMwOAheG+5jZnJndND7JzLYAZwL/c+L6JTPbD+wHNgB/WVEer8nyamjKU8AH9zQh0hhP2tbU8o36BjKIayb4HnzsGspLF15DshEI36mj+zKte9b3b6DXXkNdhT4rgq6Q15DwmarLN+Yp6BcXT/bwG438+A4011BJ2p5iQgjRLFXn28lzva8rAJadmqIMWo9ACOEtVUfX5nGI8HEFwKWleCUA7RqypQiEEJ1TdfnGNGPw2BsprsUA3XoOpSmhPs01JGqi84UphKiJsnk5jwt2Ekktiq1bT3gjJdGl51CaEmpzriEpAg9o2nWuTaTQppO877WrvJzUorjjjvQlJLteATBJCY1GLdst4izIvodp8xqalpG/vrvoiXIUea++5eW00fw+eM+1/c0g91F/qeo65wu+FQKiHoq8V1/y8thduok5vep2xW7TtTtJEahrqEPGzW2X4MHbt1GPmspiOinyXn0YwRvtnoqjSndQE11fVWwjdSFF0BFNZtbJ57TVZ+9DISDqp8h77XqRlaUlmJ9PtgsU9UaaxEcX1FqIayb4Hqahayir2VpH87Dt/kfZCKaTou81b1dHE10sadNP19E95UvXV1mQjcAv2shQXfTZayqL6aSNQrtqpSFrvY868n3f7WBSBJ7RRobqe+1F1I8virqJ/J/mIVRXy7Tvrd4kRSAbQUe00ZeqPnu/aXvMhU/jVZpwLEjK1zMz9c0nVHUEtLfEaQffwzS0CJxrvnbW99rLNNPFu6lSC687rzbRIlB+zwZ1DU03SR9qnR9wW90KvnRfNEkXfc1luwqbKGCbKrSHkHeq0IgiAH4XeBR4DZhLOe8igvWNDwE7I/FnAfeH8bcBa/I8V4rgZNqoCaU9o25lM4RaXRf2m7LKpymlpUK7fZpSBG8HfhW4N0kRADPAk8DZwBrgIeDc8NhXgcvC7RuBhTzPlSI4mTZql0nPGI3qLbj77pWRl648usq8KzkdTA9JiqCSsdg597hz7kDGae8CDjnnDjvnfgZ8BdgWLlj/QeD28Ly9BAvYi4K0MaI36V5Hj9Y7wGYoo5O7GHhV1tApp4Pppw2vodOBZyL7R8K4EfCic+7VifhYzGyHmS2b2fLKykpjwvaRNj7UovcqW3APpdDpyvukzHQGXY8WFs2TqQjM7G4zeyQmbGtDwDHOuT3OuTnn3NzGjRvbfLT3tPGhJj1jNIo/v2zBPaRCx4c5ZvIwtS6T4heszjrBOXdhxWc8C5wZ2T8jjDsKvMnMVoetgnG8KMj4g9y1K6iJb94cFJx1fqhJz4D4dWDLFtxt/BdRnO3b9Q6mmVoWrzeze4E/c86dsqK8ma0GngB+k6Cg/x7wcefco2b2NeAfnHNfMbMbgYedczdkPU+L1/vF0pIKbiH6QCOL15vZb5vZEeA9wD+b2Z1h/FvM7A6AsLb/KeBO4HHgq865R8NbfAb4tJkdIrAZ/F0VeUQ39KWLQwgRTy0tgrZRi0AIIYrTSItACCFE/5EiEEKIgSNFIIQQA0eKQAghBk4vjcVmtgIkrPabygbghZrFqQPJVRxfZZNcxfFVtmmUa9Y5d8qI3F4qgrKY2XKcxbxrJFdxfJVNchXHV9mGJJe6hoQQYuBIEQghxMAZmiLY07UACUiu4vgqm+Qqjq+yDUauQdkIhBBCnMrQWgRCCCEmkCIQQoiBM3WKwMx+18weNbPXzCzRxcrMLjKzA2Z2yMx2RuLPMrP7w/jbzGxNTXKdZmZ3mdnB8Hd9zDkfMLMHI+FfzeyS8NgtZvb9yLHz2pIrPO945Nn7IvGNpFde2czsPDP7TvjOHzaz348cqzXNkvJM5PjaMA0OhWmyJXLs6jD+gJl9pIocJeT6tJk9FqbPPWY2GzkW+15bkusTZrYSef4fRY7Nh+/9oJnN1ylXTtmui8j1hJm9GDnWSJqZ2c1m9ryZPZJw3Mzsb0OZHzazd0aOVUuvuIWM+xyAtwO/CtwLzCWcMwM8CZwNrAEeAs4Nj30VuCzcvhFYqEmuvwF2hts7gb/OOP804BiwLty/Bbi0gfTKJRfw04T4RtIrr2zAvwfOCbffAjwHvKnuNEvLM5Fz/hi4Mdy+DLgt3D43PH8tcFZ4n5kW5fpAJB8tjOVKe68tyfUJ4PMx154GHA5/14fb69uUbeL8PwVubiHN3ge8E3gk4fhW4JuAAe8G7q8rvaauReCce9w5dyDjtHcBh5xzh51zPwO+AmwzMwM+CNwenrcXuKQm0baF98t730uBbzrnXso4rypF5foFDadXLtmcc0845w6G2/8CPA80sZZpbJ5Jkfd24DfDNNoGfMU594pz7vvAofB+rcjlnPt2JB/dR7AaYNPkSa8kPgLc5Zw75pz7MXAXcFGHsn0M+HKNz4/FOfe/CCp/SWwD/t4F3EewwuMmakivqVMEOTkdeCayfySMGwEvumAxnWh8HbzZOfdcuP1D4M0Z51/GqZlvd9gkvM7M1rYs1+vNbNnM7ht3V9FsehWRDQAzexdBDe/JSHRdaZaUZ2LPCdPkJwRplOfaJuWKciVBrXJM3HttU67fCd/P7WY2XtK2yfQqdP+wG+0s4FuR6KbSLIskuSunV+aaxT5iZncD/zbm0C7n3DfalmdMmlzRHeecM7NEv91Qy/9HglXdxlxNUBiuIfAj/gxwTYtyzTrnnjWzs4Fvmdl+goKuEjWn2a3AvHPutTC6dJpNI2Z2OTAH/EYk+pT36px7Mv4OtfOPwJedc6+Y2X8maE19sKVn5+Uy4Hbn3PFIXJdp1gi9VATOuQsr3uJZ4MzI/hlh3FGC5tbqsEY3jq8sl5n9yMw2OeeeCwut51Nu9XvA151zP4/ce1wzfsXMvgT8WZtyOeeeDX8PW7BG9fnAP1AhveqSzcx+GfhngorAfZF7l06zGJLyTNw5RyxYq/tXCPJUnmublAszu5BAuf6Gc+6VcXzCe62jUMuUyzl3NLJ7E4FNaHzt+yeuvbcGmXLLFuEy4E+iEQ2mWRZJcldOr6F2DX0POMcCj5c1BC97nwssL98m6J8HmAfqamHsC++X576n9EmGBeG4X/4SINazoAm5zGz9uFvFzDYAvw481nB65ZVtDfB1gr7T2yeO1ZlmsXkmRd5LgW+FabQPuMwCr6KzgHOA71aQpZBcZnY+8EXgYufc85H42PfaolybIrsXE6xpDkFL+MOhfOuBD3Ny67hx2UL53kZgfP1OJK7JNMtiH/AHoffQu4GfhJWd6unVhPW7ywD8NkEf2SvAj4A7w/i3AHdEztsKPEGgyXdF4s8m+EgPAV8D1tYk1wi4BzgI3A2cFsbPATdFzttCoOFXTVz/LWA/QWG2CLyxLbmA94bPfij8vbLp9Cog2+XAz4EHI+G8JtIsLs8QdDVdHG6/PkyDQ2GanB25dld43QHgozXn+Sy57g6/hXH67Mt6ry3J9VfAo+Hzvw28LXLtH4bpeAj4ZJ1y5ZEt3P8scO3EdY2lGUHl77kwPx8hsOdcBVwVHjfgC6HM+4l4RVZNL00xIYQQA2eoXUNCCCFCpAiEEGLgSBEIIcTAkSIQQoiBI0UghBADR4pACCEGjhSBEEIMnP8PNRUZ2fYpuekAAAAASUVORK5CYII=",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -219,7 +247,7 @@ ...@@ -219,7 +247,7 @@
}, },
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 1 Axes>" "<Figure size 432x288 with 1 Axes>"
] ]
...@@ -248,6 +276,8 @@ ...@@ -248,6 +276,8 @@
"# Generate data set\n", "# Generate data set\n",
"train_x, train_y, test_x, test_y = circle_data_point_generator(\n", "train_x, train_y, test_x, test_y = circle_data_point_generator(\n",
" Ntrain, Ntest, boundary_gap, seed_data)\n", " Ntrain, Ntest, boundary_gap, seed_data)\n",
"\n",
"# Visualization\n",
"print(\"Visualization of {} data points in the training set: \".format(Ntrain))\n", "print(\"Visualization of {} data points in the training set: \".format(Ntrain))\n",
"data_point_plot(train_x, train_y)\n", "data_point_plot(train_x, train_y)\n",
"print(\"Visualization of {} data points in the test set: \".format(Ntest))\n", "print(\"Visualization of {} data points in the test set: \".format(Ntest))\n",
...@@ -260,10 +290,12 @@ ...@@ -260,10 +290,12 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Data preprocessing\n", "### Data preprocessing\n",
"Different from classical machine learning, quantum classifiers need to consider data preprocessing heavily. We need one more step to convert classical data into quantum information before running on a quantum computer. Now let's take a look at how it can be done. First, we determine the number of qubits that need to be used. Because our data $\\{x^{(i)} = (x^{(i)}_0, x^{(i)}_1)\\}$ is two-dimensional, according to the paper by Mitarai (2018) we need at least 2 qubits for encoding. Then prepare a group of initial quantum states $|00\\rangle$. Encode the classical information $\\{x^{(i)}\\}$ into a group of quantum gates $U(x^{(i)})$ and act them on the initial quantum states. Finally we get a group of quantum states $|\\psi^{(i)}\\rangle = U(x^{(i)})|00\\rangle$. In this way, we have completed the encoding from classical information into quantum information! Given $m$ qubits to encode a two-dimensional classical data point, the quantum gate is:\n", "Different from classical machine learning, quantum classifiers need to consider data preprocessing heavily. We need one more step to convert classical data into quantum information before running on a quantum computer. In this tutorial we use \"Angle Encoding\" to get quantum data.\n",
"\n",
"First, we determine the number of qubits that need to be used. Because our data $\\{x^{k} = (x^{k}_0, x^{k}_1)\\}$ is two-dimensional, according to the paper by Mitarai (2018) we need at least 2 qubits for encoding. Then prepare a group of initial quantum states $|00\\rangle$. Encode the classical information $\\{x^{k}\\}$ into a group of quantum gates $U(x^{k})$ and act them on the initial quantum states. Finally we get a group of quantum states $|\\psi_{\\rm in}\\rangle^k = U(x^{k})|00\\rangle$. In this way, we have completed the encoding from classical information into quantum information! Given $m$ qubits to encode a two-dimensional classical data point, the quantum gate is:\n",
"\n", "\n",
"$$\n", "$$\n",
"U(x^{(i)}) = \\otimes_{j=0}^{m-1} R_j^z\\big[\\arccos(x^{(i)}_{j \\, \\text{mod} \\, 2}\\cdot x^{(i)}_{j \\, \\text{mod} \\, 2})\\big] R_j^y\\big[\\arcsin(x^{(i)}_{j \\, \\text{mod} \\, 2}) \\big],\n", "U(x^{k}) = \\otimes_{j=0}^{m-1} R_j^z\\big[\\arccos(x^{k}_{j \\, \\text{mod} \\, 2}\\cdot x^{k}_{j \\, \\text{mod} \\, 2})\\big] R_j^y\\big[\\arcsin(x^{k}_{j \\, \\text{mod} \\, 2}) \\big],\n",
"\\tag{2}\n", "\\tag{2}\n",
"$$\n", "$$\n",
"\n", "\n",
...@@ -336,14 +368,14 @@ ...@@ -336,14 +368,14 @@
"1 &0 \\\\ \n", "1 &0 \\\\ \n",
"0 &1\n", "0 &1\n",
"\\end{bmatrix}\n", "\\end{bmatrix}\n",
"\\bigg),\n", "\\bigg) \\, .\n",
"\\tag{6}\n", "\\tag{6}\n",
"$$\n", "$$\n",
"\n", "\n",
"After simplification, we can get the encoded quantum state $|\\psi\\rangle$ by acting the quantum gate on the initialized quantum state $|00\\rangle$,\n", "After simplification, we can get the encoded quantum state $|\\psi_{\\rm in}\\rangle$ by acting the quantum gate on the initialized quantum state $|00\\rangle$,\n",
"\n", "\n",
"$$\n", "$$\n",
"|\\psi\\rangle =\n", "|\\psi_{\\rm in}\\rangle =\n",
"U(x)|00\\rangle = \\frac{1}{2}\n", "U(x)|00\\rangle = \\frac{1}{2}\n",
"\\begin{bmatrix}\n", "\\begin{bmatrix}\n",
"1-i &0 &-1+i &0 \\\\\n", "1-i &0 &-1+i &0 \\\\\n",
...@@ -378,27 +410,17 @@ ...@@ -378,27 +410,17 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 6,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-09T04:03:37.354267Z", "end_time": "2021-03-09T04:03:37.354267Z",
"start_time": "2021-03-09T04:03:37.258314Z" "start_time": "2021-03-09T04:03:37.258314Z"
} }
}, },
"outputs": [ "outputs": [],
{
"name": "stdout",
"output_type": "stream",
"text": [
"As a test, we enter the classical information:\n",
"(x_0, x_1) = (1, 0)\n",
"The 2-qubit quantum state output after encoding is:\n",
"[[[0.5-0.5j 0. +0.j 0.5-0.5j 0. +0.j ]]]\n"
]
}
],
"source": [ "source": [
"def myRy(theta):\n", "# Gate: rotate around Y-axis, Z-axis with angle theta\n",
"def Ry(theta):\n",
" \"\"\"\n", " \"\"\"\n",
" :param theta: parameter\n", " :param theta: parameter\n",
" :return: Y rotation matrix\n", " :return: Y rotation matrix\n",
...@@ -406,7 +428,7 @@ ...@@ -406,7 +428,7 @@
" return np.array([[np.cos(theta / 2), -np.sin(theta / 2)],\n", " return np.array([[np.cos(theta / 2), -np.sin(theta / 2)],\n",
" [np.sin(theta / 2), np.cos(theta / 2)]])\n", " [np.sin(theta / 2), np.cos(theta / 2)]])\n",
"\n", "\n",
"def myRz(theta):\n", "def Rz(theta):\n",
" \"\"\"\n", " \"\"\"\n",
" :param theta: parameter\n", " :param theta: parameter\n",
" :return: Z rotation matrix\n", " :return: Z rotation matrix\n",
...@@ -421,26 +443,55 @@ ...@@ -421,26 +443,55 @@
" :param n_qubits: the number of qubits to which\n", " :param n_qubits: the number of qubits to which\n",
" the data transformed\n", " the data transformed\n",
" :return: shape [-1, 1, 2 ^ n_qubits]\n", " :return: shape [-1, 1, 2 ^ n_qubits]\n",
" the first parameter -1 in this shape means can be arbitrary. In this tutorial, it equals to BATCH.\n",
" \"\"\"\n", " \"\"\"\n",
" dim1, dim2 = data.shape\n", " dim1, dim2 = data.shape\n",
" res = []\n", " res = []\n",
" for sam in range(dim1):\n", " for sam in range(dim1):\n",
" res_state = 1.\n", " res_state = 1.\n",
" zero_state = np.array([[1, 0]])\n", " zero_state = np.array([[1, 0]])\n",
" # Angle Encoding\n",
" for i in range(n_qubits):\n", " for i in range(n_qubits):\n",
" # For even number qubits, perform Rz(arccos(x0^2)) Ry(arcsin(x0))\n",
" if i % 2 == 0:\n", " if i % 2 == 0:\n",
" state_tmp=np.dot(zero_state, myRy(np.arcsin(data[sam][0])).T)\n", " state_tmp=np.dot(zero_state, Ry(np.arcsin(data[sam][0])).T)\n",
" state_tmp=np.dot(state_tmp, myRz(np.arccos(data[sam][0] ** 2)).T)\n", " state_tmp=np.dot(state_tmp, Rz(np.arccos(data[sam][0] ** 2)).T)\n",
" res_state=np.kron(res_state, state_tmp)\n", " res_state=np.kron(res_state, state_tmp)\n",
" # For odd number qubits, perform Rz(arccos(x1^2)) Ry(arcsin(x1))\n",
" elif i% 2 == 1:\n", " elif i% 2 == 1:\n",
" state_tmp=np.dot(zero_state, myRy(np.arcsin(data[sam][1])).T)\n", " state_tmp=np.dot(zero_state, Ry(np.arcsin(data[sam][1])).T)\n",
" state_tmp=np.dot(state_tmp, myRz(np.arccos(data[sam][1] ** 2)).T)\n", " state_tmp=np.dot(state_tmp, Rz(np.arccos(data[sam][1] ** 2)).T)\n",
" res_state=np.kron(res_state, state_tmp)\n", " res_state=np.kron(res_state, state_tmp)\n",
" res.append(res_state)\n", " res.append(res_state)\n",
"\n", "\n",
" res = np.array(res)\n", " res = np.array(res)\n",
" return res.astype(\"complex128\")\n", " return res.astype(\"complex128\")\n"
"\n", ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"quantum data after angle encoding"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"As a test, we enter the classical information:\n",
"(x_0, x_1) = (1, 0)\n",
"The 2-qubit quantum state output after encoding is:\n",
"[[[0.5-0.5j 0. +0.j 0.5-0.5j 0. +0.j ]]]\n"
]
}
],
"source": [
"print(\"As a test, we enter the classical information:\")\n", "print(\"As a test, we enter the classical information:\")\n",
"print(\"(x_0, x_1) = (1, 0)\")\n", "print(\"(x_0, x_1) = (1, 0)\")\n",
"print(\"The 2-qubit quantum state output after encoding is:\")\n", "print(\"The 2-qubit quantum state output after encoding is:\")\n",
...@@ -454,12 +505,14 @@ ...@@ -454,12 +505,14 @@
"### Building Quantum Neural Network \n", "### Building Quantum Neural Network \n",
"After completing the encoding from classical data to quantum data, we can now input these quantum states into the quantum computer. Before that, we also need to design the quantum neural network.\n", "After completing the encoding from classical data to quantum data, we can now input these quantum states into the quantum computer. Before that, we also need to design the quantum neural network.\n",
"\n", "\n",
"![QC-fig-classifier_circuit](figures/qclassifier-fig-circuit.png)\n", "<img src=\"./figures/qclassifier-fig-circuit.png\" width=\"600px\" /> \n",
"<center> Figure 3: Parameterized Quantum Circuit </center>\n",
"\n", "\n",
"For convenience, we call the parameterized quantum neural network as $U(\\boldsymbol{\\theta})$. $U(\\boldsymbol{\\theta})$ is a key component of our classifier, and it needs a certain complex structure to fit our decision boundary. Similar to traditional neural networks, the structure of a quantum neural network is not unique. The structure shown above is just one case. You could design your own structure. Let’s take the previously mentioned data point $x = (x_0, x_1)= (1,0)$ as an example. After encoding, we have obtained a quantum state $|\\psi\\rangle$,\n", "\n",
"For convenience, we call the parameterized quantum neural network as $U(\\boldsymbol{\\theta})$. $U(\\boldsymbol{\\theta})$ is a key component of our classifier, and it needs a certain complex structure to fit our decision boundary. Similar to traditional neural networks, the structure of a quantum neural network is not unique. The structure shown above is just one case. You could design your own structure. Let’s take the previously mentioned data point $x = (x_0, x_1)= (1,0)$ as an example. After encoding, we have obtained a quantum state $|\\psi_{\\rm in}\\rangle$,\n",
"\n", "\n",
"$$\n", "$$\n",
"|\\psi\\rangle =\n", "|\\psi_{\\rm in}\\rangle =\n",
"\\frac{1}{2}\n", "\\frac{1}{2}\n",
"\\begin{bmatrix}\n", "\\begin{bmatrix}\n",
"1-i \\\\\n", "1-i \\\\\n",
...@@ -473,15 +526,15 @@ ...@@ -473,15 +526,15 @@
"Then we input this quantum state into our quantum neural network (QNN). That is, multiply a unitary matrix by a vector to get the processed quantum state $|\\varphi\\rangle$\n", "Then we input this quantum state into our quantum neural network (QNN). That is, multiply a unitary matrix by a vector to get the processed quantum state $|\\varphi\\rangle$\n",
"\n", "\n",
"$$\n", "$$\n",
"|\\varphi\\rangle = U(\\boldsymbol{\\theta})|\\psi\\rangle.\n", "|\\psi_{\\rm out}\\rangle = U(\\boldsymbol{\\theta})|\\psi_{\\rm in}\\rangle.\n",
"\\tag{10}\n", "\\tag{10}\n",
"$$\n", "$$\n",
"\n", "\n",
"If we set all the QNN parameters to be $\\theta = \\pi$, then we can write down the resulting state:\n", "If we set all the QNN parameters to be $\\theta = \\pi$, then we can write down the resulting state:\n",
"\n", "\n",
"$$\n", "$$\n",
"|\\varphi\\rangle =\n", "|\\psi_{\\rm out}\\rangle =\n",
"U(\\boldsymbol{\\theta} =\\pi)|\\psi\\rangle =\n", "U(\\boldsymbol{\\theta} =\\pi)|\\psi_{\\rm in}\\rangle =\n",
"\\begin{bmatrix}\n", "\\begin{bmatrix}\n",
"0 &0 &-1 &0 \\\\\n", "0 &0 &-1 &0 \\\\\n",
"-1 &0 &0 &0 \\\\\n", "-1 &0 &0 &0 \\\\\n",
...@@ -509,7 +562,7 @@ ...@@ -509,7 +562,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 8,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-09T04:03:37.426687Z", "end_time": "2021-03-09T04:03:37.426687Z",
...@@ -519,9 +572,9 @@ ...@@ -519,9 +572,9 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"# Simulation of building a quantum neural network\n", "# Simulation of building a quantum neural network\n",
"def U_theta(theta, n, depth):\n", "def cir_Classifier(theta, n, depth): \n",
" \"\"\"\n", " \"\"\"\n",
" :param theta: dim: [n, depth + 3]\n", " :param theta: dim: [n, depth + 3], \"+3\" because we add an initial generalized rotation gate to each qubit\n",
" :param n: number of qubits\n", " :param n: number of qubits\n",
" :param depth: circuit depth\n", " :param depth: circuit depth\n",
" :return: U_theta\n", " :return: U_theta\n",
...@@ -529,7 +582,7 @@ ...@@ -529,7 +582,7 @@
" # Initialize the network\n", " # Initialize the network\n",
" cir = UAnsatz(n)\n", " cir = UAnsatz(n)\n",
" \n", " \n",
" # Build a rotation layer\n", " # Build a generalized rotation layer\n",
" for i in range(n):\n", " for i in range(n):\n",
" cir.rz(theta[i][0], i)\n", " cir.rz(theta[i][0], i)\n",
" cir.ry(theta[i][1], i)\n", " cir.ry(theta[i][1], i)\n",
...@@ -538,25 +591,29 @@ ...@@ -538,25 +591,29 @@
" # The default depth is depth = 1\n", " # The default depth is depth = 1\n",
" # Build the entangleed layer and Ry rotation layer\n", " # Build the entangleed layer and Ry rotation layer\n",
" for d in range(3, depth + 3):\n", " for d in range(3, depth + 3):\n",
" for i in range(n - 1):\n", " # The entanglement layer\n",
" for i in range(n-1):\n",
" cir.cnot([i, i + 1])\n", " cir.cnot([i, i + 1])\n",
" cir.cnot([n - 1, 0])\n", " cir.cnot([n-1, 0])\n",
" # Add Ry to each qubit\n",
" for i in range(n):\n", " for i in range(n):\n",
" cir.ry(theta[i][d], i)\n", " cir.ry(theta[i][d], i)\n",
"\n", "\n",
" return cir" " return cir\n"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Measurement and loss function\n", "### Measurement\n",
"After the initial quantum state, $|\\psi\\rangle$ has been processed with QNN on the quantum computer (QPU), we need to measure this new quantum state $|\\varphi\\rangle$ to obtain the classical information. These processed classical information can be used to calculate the loss function $\\mathcal{L}(\\boldsymbol{\\theta})$. Finally, we use the classical computer (CPU) to continuously update the QNN parameters $\\boldsymbol{\\theta}$ and optimize the loss function. Here we measure the expected value of the Pauli $Z$ operator on the first qubit. Specifically,\n", "After passing through the PQC $U(\\theta)$, the quantum data becomes $\\lvert \\psi_{\\rm out}\\rangle^k = U(\\theta)\\lvert \\psi_{\\rm in} \\rangle^k$. To get its label, we need to measure this new quantum state to obtain the classical information. These processed classical information will then be used to calculate the loss function $\\mathcal{L}(\\boldsymbol{\\theta})$. Finally, based on the gradient descent algorithm, we continuously update the PQC parameters $\\boldsymbol{\\theta}$ and optimize the loss function. \n",
"\n",
"Here we measure the expected value of the Pauli $Z$ operator on the first qubit. Specifically,\n",
"\n", "\n",
"$$\n", "$$\n",
"\\langle Z \\rangle =\n", "\\langle Z \\rangle =\n",
"\\langle \\varphi |Z\\otimes I\\cdots \\otimes I| \\varphi\\rangle.\n", "\\langle \\psi_{\\rm out} |Z\\otimes I\\cdots \\otimes I| \\psi_{\\rm out}\\rangle.\n",
"\\tag{12}\n", "\\tag{12}\n",
"$$\n", "$$\n",
"\n", "\n",
...@@ -571,7 +628,7 @@ ...@@ -571,7 +628,7 @@
"\n", "\n",
"$$\n", "$$\n",
"\\langle Z \\rangle =\n", "\\langle Z \\rangle =\n",
"\\langle \\varphi |Z\\otimes I| \\varphi\\rangle =\n", "\\langle \\psi_{\\rm out} |Z\\otimes I| \\psi_{\\rm out}\\rangle =\n",
"\\frac{1}{2}\n", "\\frac{1}{2}\n",
"\\begin{bmatrix}\n", "\\begin{bmatrix}\n",
"-1-i \\quad\n", "-1-i \\quad\n",
...@@ -596,32 +653,44 @@ ...@@ -596,32 +653,44 @@
"= 1. \\tag{14}\n", "= 1. \\tag{14}\n",
"$$\n", "$$\n",
"\n", "\n",
"This measurement result seems to be our original label 1. Does this mean that we have successfully classified this data point? This is not the case because the range of $\\langle Z \\rangle$ is usually between $[-1,1]$. To match it to our label range $y^{(i)} \\in \\{0,1\\}$, we need to map the upper and lower limits. The simplest mapping is \n", "This measurement result seems to be our original label 1. Does this mean that we have successfully classified this data point? This is not the case because the range of $\\langle Z \\rangle$ is usually between $[-1,1]$. \n",
"To match it to our label range $y^{k} \\in \\{0,1\\}$, we need to map the upper and lower limits. The simplest mapping is \n",
"\n", "\n",
"$$\n", "$$\n",
"\\tilde{y}^{(i)} = \\frac{\\langle Z \\rangle}{2} + \\frac{1}{2} + bias \\quad \\in [0, 1].\n", "\\tilde{y}^{k} = \\frac{\\langle Z \\rangle}{2} + \\frac{1}{2} + bias \\quad \\in [0, 1].\n",
"\\tag{15}\n", "\\tag{15}\n",
"$$\n", "$$\n",
"\n", "\n",
"Using bias is a trick in machine learning. The purpose is to make the decision boundary not restricted by the origin or some hyperplane. Generally, the default bias is initialized to be 0, and the optimizer will continuously update it like all the other parameters $\\theta$ in the iterative process to ensure $\\tilde{y}^{k} \\in [0, 1]$. Of course, you can also choose other complex mappings (activation functions), such as the sigmoid function. After mapping, we can regard $\\tilde{y}^{k}$ as the label we estimated. $\\tilde{y}^{k}< 0.5$ corresponds to label 0, and $\\tilde{y}^{k}> 0.5$ corresponds to label 1. It's time to quickly review the whole process before we finish discussion,\n", "Using bias is a trick in machine learning. The purpose is to make the decision boundary not restricted by the origin or some hyperplane. Generally, the default bias is initialized to be 0, and the optimizer will continuously update it like all the other parameters $\\theta$ in the iterative process to ensure $\\tilde{y}^{k} \\in [0, 1]$. Of course, you can also choose other complex mappings (activation functions), such as the sigmoid function. After mapping, we can regard $\\tilde{y}^{k}$ as the label we estimated. $\\tilde{y}^{k}< 0.5$ corresponds to label 0, and $\\tilde{y}^{k}> 0.5$ corresponds to label 1. It's time to quickly review the whole process before we finish discussion,\n",
"\n", "\n",
"$$\n", "$$\n",
"x^{(i)} \\rightarrow |\\psi\\rangle^{(i)} \\rightarrow U(\\boldsymbol{\\theta})|\\psi\\rangle^{(i)} \\rightarrow\n", "x^{k} \\rightarrow |\\psi_{\\rm in}\\rangle^{k} \\rightarrow U(\\boldsymbol{\\theta})|\\psi_{\\rm in}\\rangle^{k} \\rightarrow\n",
"|\\varphi\\rangle^{(i)} \\rightarrow ^{(i)}\\langle \\varphi |Z\\otimes I\\cdots \\otimes I| \\varphi\\rangle^{(i)}\n", "|\\psi_{\\rm out}\\rangle^{k} \\rightarrow ^{k}\\langle \\psi_{\\rm out} |Z\\otimes I\\cdots \\otimes I| \\psi_{\\rm out} \\rangle^{k}\n",
"\\rightarrow \\langle Z \\rangle \\rightarrow \\tilde{y}^{(i)}. \\tag{16}\n", "\\rightarrow \\langle Z \\rangle \\rightarrow \\tilde{y}^{k}.\\tag{16}\n",
"$$\n", "$$\n",
"\n", "\n",
"Finally, we can define the loss function as a square loss function:\n", "\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Loss function\n",
"To calculate the loss function in Eq. (1), we need to measure all training data in each iteration. In real practice, we devide the training data into \"Ntrain/BATCH\" groups, where each group contains \"BATCH\" data pairs.\n",
"\n", "\n",
"The loss function for the i-th group is \n",
"$$\n", "$$\n",
"\\mathcal{L} = \\sum_{(i)} |y^{(i)}-\\tilde{y}^{(i)}|^2. \\tag{17}\n", "\\mathcal{L}_{i} = \\sum_{k=1}^{BATCH} \\frac{1}{BATCH} |y^{i,k} - \\tilde{y}^{i,k}|^2,\\tag{17}\n",
"$$\n", "$$\n",
"\n" "and we train the PQC with $\\mathcal{L}_{i}$ for \"EPOCH\" times. \n",
"\n",
"If you set \"BATCH = Ntrain\", there will be only one group, and Eq. (17) becomes Eq. (1)."
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 7, "execution_count": 9,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-09T04:03:37.439183Z", "end_time": "2021-03-09T04:03:37.439183Z",
...@@ -643,7 +712,7 @@ ...@@ -643,7 +712,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 10,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-09T04:03:37.503213Z", "end_time": "2021-03-09T04:03:37.503213Z",
...@@ -653,27 +722,22 @@ ...@@ -653,27 +722,22 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"# Build the computational graph\n", "# Build the computational graph\n",
"class Net(paddle.nn.Layer):\n", "class Opt_Classifier(paddle.nn.Layer):\n",
" \"\"\"\n", " \"\"\"\n",
" Construct the model net\n", " Construct the model net\n",
" \"\"\"\n", " \"\"\"\n",
" def __init__(self,\n", " def __init__(self, n, depth, seed_paras=1, dtype='float64'):\n",
" n, # number of qubits\n", " # Initialization, use n, depth give the initial PQC\n",
" depth, # circuit depth\n", " super(Opt_Classifier, self).__init__()\n",
" seed_paras=1,\n",
" dtype='float64'):\n",
" super(Net, self).__init__()\n",
"\n",
" self.n = n\n", " self.n = n\n",
" self.depth = depth\n", " self.depth = depth\n",
" \n", " \n",
" # Initialize the parameters theta with a uniform distribution of [0, 2*pi]\n", " # Initialize the parameters theta with a uniform distribution of [0, 2*pi]\n",
" self.theta = self.create_parameter(\n", " self.theta = self.create_parameter(\n",
" shape=[n, depth + 3],\n", " shape=[n, depth + 3], # \"+3\" because we add an initial generalized rotation gate to each qubit\n",
" default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2*PI),\n", " default_initializer=paddle.nn.initializer.Uniform(low=0.0, high=2*PI),\n",
" dtype=dtype,\n", " dtype=dtype,\n",
" is_bias=False)\n", " is_bias=False)\n",
" \n",
" # Initialize bias\n", " # Initialize bias\n",
" self.bias = self.create_parameter(\n", " self.bias = self.create_parameter(\n",
" shape=[1],\n", " shape=[1],\n",
...@@ -685,35 +749,36 @@ ...@@ -685,35 +749,36 @@
" def forward(self, state_in, label):\n", " def forward(self, state_in, label):\n",
" \"\"\"\n", " \"\"\"\n",
" Args:\n", " Args:\n",
" state_in: The input quantum state, shape [-1, 1, 2^n]\n", " state_in: The input quantum state, shape [-1, 1, 2^n] -- in this tutorial: [BATCH, 1, 2^n]\n",
" label: label for the input state, shape [-1, 1]\n", " label: label for the input state, shape [-1, 1]\n",
" Returns:\n", " Returns:\n",
" The loss:\n", " The loss:\n",
" L = ((<Z> + 1)/2 + bias-label)^2\n", " L = 1/BATCH * ((<Z> + 1)/2 + bias - label)^2\n",
" \"\"\"\n", " \"\"\"\n",
" # Convert Numpy array to tensor\n", " # Convert Numpy array to tensor\n",
" Ob = paddle.to_tensor(Observable(self.n))\n", " Ob = paddle.to_tensor(Observable(self.n))\n",
" label_pp = paddle.to_tensor(label)\n", " label_pp = paddle.to_tensor(label)\n",
"\n", "\n",
" # According to the randomly initialized parameters theta to build the quantum gate\n", " # Build the quantum circuit\n",
" cir = U_theta(self.theta, n=self.n, depth=self.depth)\n", " cir = cir_Classifier(self.theta, n=self.n, depth=self.depth)\n",
" Utheta = cir.U\n", " Utheta = cir.U\n",
" \n", " \n",
" # Because Utheta is achieved by learning, we compute with row vectors to speed up without affecting the training effect\n", " # Because Utheta is achieved by learning, we compute with row vectors to speed up without affecting the training effect\n",
" state_out = matmul(state_in, Utheta) # dimension [-1, 1, 2 ** n]\n", " state_out = matmul(state_in, Utheta) # shape:[-1, 1, 2 ** n], the first parameter is BATCH in this tutorial\n",
" \n", " \n",
" # Measure the expected value of Pauli Z operator <Z>\n", " # Measure the expected value of Pauli Z operator <Z> -- shape [-1,1,1]\n",
" E_Z = matmul(matmul(state_out, Ob), transpose(paddle.conj(state_out), perm=[0, 2, 1]))\n", " E_Z = matmul(matmul(state_out, Ob), transpose(paddle.conj(state_out), perm=[0, 2, 1]))\n",
" \n", " \n",
" # Mapping <Z> to the estimated value of the label\n", " # Mapping <Z> to the estimated value of the label\n",
" state_predict = paddle.real(E_Z)[:, 0] * 0.5 + 0.5 + self.bias\n", " state_predict = paddle.real(E_Z)[:, 0] * 0.5 + 0.5 + self.bias # |y^{i,k} - \\tilde{y}^{i,k}|^2\n",
" loss = paddle.mean((state_predict - label_pp) ** 2)\n", " loss = paddle.mean((state_predict - label_pp) ** 2) # Get average for \"BATCH\" |y^{i,k} - \\tilde{y}^{i,k}|^2: L_i:shape:[1,1]\n",
" \n", " \n",
" # Calculate the accuracy of cross-validation\n", " # Calculate the accuracy of cross-validation\n",
" is_correct = (paddle.abs(state_predict - label_pp) < 0.5).nonzero().shape[0]\n", " is_correct = (paddle.abs(state_predict - label_pp) < 0.5).nonzero().shape[0]\n",
" acc = is_correct / label.shape[0]\n", " acc = is_correct / label.shape[0]\n",
"\n", "\n",
" return loss, acc, state_predict.numpy(), cir" " return loss, acc, state_predict.numpy(), cir\n",
" "
] ]
}, },
{ {
...@@ -727,16 +792,12 @@ ...@@ -727,16 +792,12 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 11,
"metadata": { "metadata": {},
"ExecuteTime": {
"end_time": "2021-03-09T04:03:38.325454Z",
"start_time": "2021-03-09T04:03:38.299975Z"
}
},
"outputs": [], "outputs": [],
"source": [ "source": [
"def heatmap_plot(net, N):\n", "# Draw the figure of the final training classifier\n",
"def heatmap_plot(Opt_Classifier, N):\n",
" # generate data points x_y_\n", " # generate data points x_y_\n",
" Num_points = 30\n", " Num_points = 30\n",
" x_y_ = []\n", " x_y_ = []\n",
...@@ -750,7 +811,7 @@ ...@@ -750,7 +811,7 @@
" # make prediction: heat_data\n", " # make prediction: heat_data\n",
" input_state_test = paddle.to_tensor(\n", " input_state_test = paddle.to_tensor(\n",
" datapoints_transform_to_state(x_y_, N))\n", " datapoints_transform_to_state(x_y_, N))\n",
" loss_useless, acc_useless, state_predict, cir = net(state_in=input_state_test, label=x_y_[:, 0])\n", " loss_useless, acc_useless, state_predict, cir = Opt_Classifier(state_in=input_state_test, label=x_y_[:, 0])\n",
" heat_data = state_predict.reshape(Num_points, Num_points)\n", " heat_data = state_predict.reshape(Num_points, Num_points)\n",
"\n", "\n",
" # plot\n", " # plot\n",
...@@ -764,71 +825,103 @@ ...@@ -764,71 +825,103 @@
" ax.set_yticklabels(y_label)\n", " ax.set_yticklabels(y_label)\n",
" im = ax.imshow(heat_data, cmap=plt.cm.RdBu)\n", " im = ax.imshow(heat_data, cmap=plt.cm.RdBu)\n",
" plt.colorbar(im)\n", " plt.colorbar(im)\n",
" plt.show()\n", " plt.show()"
"\n", ]
"def QClassifier(Ntrain, Ntest, gap, N, D, EPOCH, LR, BATCH, seed_paras, seed_data,):\n", },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Learn the PQC via Adam"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"ExecuteTime": {
"end_time": "2021-03-09T04:03:38.325454Z",
"start_time": "2021-03-09T04:03:38.299975Z"
}
},
"outputs": [],
"source": [
"def QClassifier(Ntrain, Ntest, gap, N, DEPTH, EPOCH, LR, BATCH, seed_paras, seed_data,):\n",
" \"\"\"\n", " \"\"\"\n",
" Quantum Binary Classifier\n", " Quantum Binary Classifier\n",
" Input:\n",
" Ntrain # Specify the training set size\n",
" Ntest # Specify the test set size\n",
" gap # Set the width of the decision boundary\n",
" N # Number of qubits required\n",
" DEPTH # Circuit depth\n",
" BATCH # Batch size during training\n",
" EPOCH # Number of training epochs, the total iteration number \"EPOCH * (Ntrain / BATCH)\" is chosen to be about 200\n",
" LR # Set the learning rate\n",
" seed_paras # Set random seed to initialize various parameters\n",
" seed_data # Fixed random seed required to generate the data set\n",
" \"\"\"\n", " \"\"\"\n",
" \n",
" # Generate data set\n", " # Generate data set\n",
" train_x, train_y, test_x, test_y = circle_data_point_generator(Ntrain=Ntrain, Ntest=Ntest, boundary_gap=gap, seed_data=seed_data)\n", " train_x, train_y, test_x, test_y = circle_data_point_generator(Ntrain=Ntrain, Ntest=Ntest, boundary_gap=gap, seed_data=seed_data)\n",
"\n",
" # Read the dimension of the training set\n", " # Read the dimension of the training set\n",
" N_train = train_x.shape[0]\n", " N_train = train_x.shape[0]\n",
"\n", " \n",
" paddle.seed(seed_paras)\n", " paddle.seed(seed_paras)\n",
" # Define optimization graph\n", " # Initialize the registers to store the accuracy rate and other information\n",
" net = Net(n=N, depth=D)\n", " summary_iter, summary_test_acc = [], []\n",
"\n", "\n",
" # Generally, we use Adam optimizer to get relatively good convergence\n", " # Generally, we use Adam optimizer to get relatively good convergence\n",
" # Of course, it can be changed to SGD or RMSprop\n", " # Of course, it can be changed to SGD or RMSprop\n",
" opt = paddle.optimizer.Adam(learning_rate=LR, parameters=net.parameters())\n", " myLayer = Opt_Classifier(n=N, depth=DEPTH) # Initial PQC\n",
" opt = paddle.optimizer.Adam(learning_rate=LR, parameters=myLayer.parameters())\n",
"\n", "\n",
" # Initialize the registers to store the accuracy rate and other information\n",
" summary_iter, summary_test_acc = [], []\n",
"\n", "\n",
" # Optimize iteration\n", " # Optimize iteration\n",
" # We divide the training set into \"Ntrain/BATCH\" groups\n",
" # For each group the final circuit will be used as the initial circuit for the next group\n",
" # Use cir to record the final circuit after learning.\n",
" i = 0 # Record the iteration number\n",
" for ep in range(EPOCH):\n", " for ep in range(EPOCH):\n",
" # Learn for each group\n",
" for itr in range(N_train // BATCH):\n", " for itr in range(N_train // BATCH):\n",
"\n", " i += 1 # Record the iteration number\n",
" # Encode classical data into a quantum state |psi>, dimension [-1, 2 ** N]\n", " # Encode classical data into a quantum state |psi>, dimension [BATCH, 2 ** N]\n",
" input_state = paddle.to_tensor(datapoints_transform_to_state(train_x[itr * BATCH:(itr + 1) * BATCH], N))\n", " input_state = paddle.to_tensor(datapoints_transform_to_state(train_x[itr * BATCH:(itr + 1) * BATCH], N))\n",
"\n", "\n",
" # Run forward propagation to calculate loss function\n", " # Run forward propagation to calculate loss function\n",
" loss, train_acc, state_predict_useless, cir \\\n", " loss, train_acc, state_predict_useless, cir \\\n",
" = net(state_in=input_state, label=train_y[itr * BATCH:(itr + 1) * BATCH])\n", " = myLayer(state_in=input_state, label=train_y[itr * BATCH:(itr + 1) * BATCH]) # optimize the given PQC\n",
" if itr % 50 == 0:\n", " # Print the performance in iteration\n",
" if i % 30 == 5:\n",
" # Calculate the correct rate on the test set test_acc\n", " # Calculate the correct rate on the test set test_acc\n",
" input_state_test = paddle.to_tensor(datapoints_transform_to_state(test_x, N))\n", " input_state_test = paddle.to_tensor(datapoints_transform_to_state(test_x, N))\n",
" loss_useless, test_acc, state_predict_useless, t_cir \\\n", " loss_useless, test_acc, state_predict_useless, t_cir \\\n",
" = net(state_in=input_state_test,label=test_y)\n", " = myLayer(state_in=input_state_test,label=test_y)\n",
" print(\"epoch:\", ep, \"iter:\", itr,\n", " print(\"epoch:\", ep, \"iter:\", itr,\n",
" \"loss: %.4f\" % loss.numpy(),\n", " \"loss: %.4f\" % loss.numpy(),\n",
" \"train acc: %.4f\" % train_acc,\n", " \"train acc: %.4f\" % train_acc,\n",
" \"test acc: %.4f\" % test_acc)\n", " \"test acc: %.4f\" % test_acc)\n",
"\n",
" # Store accuracy rate and other information\n", " # Store accuracy rate and other information\n",
" summary_iter.append(itr + ep * N_train)\n", " summary_iter.append(itr + ep * N_train)\n",
" summary_test_acc.append(test_acc)\n", " summary_test_acc.append(test_acc) \n",
" if (itr + 1) % 151 == 0 and ep == EPOCH - 1:\n",
" print(\"The trained circuit:\")\n",
" print(cir)\n",
"\n", "\n",
" # Run back propagation to minimize the loss function\n", " # Run back propagation to minimize the loss function\n",
" loss.backward()\n", " loss.backward()\n",
" opt.minimize(loss)\n", " opt.minimize(loss)\n",
" opt.clear_grad()\n", " opt.clear_grad()\n",
"\n", " \n",
" # Print the final circuit\n",
" print(\"The trained circuit:\")\n",
" print(cir)\n",
" # Draw the decision boundary represented by heatmap\n", " # Draw the decision boundary represented by heatmap\n",
" heatmap_plot(net, N=N)\n", " heatmap_plot(myLayer, N=N)\n",
"\n", "\n",
" return summary_test_acc" " return summary_test_acc\n"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 13,
"metadata": { "metadata": {
"ExecuteTime": { "ExecuteTime": {
"end_time": "2021-03-09T04:04:19.852356Z", "end_time": "2021-03-09T04:04:19.852356Z",
...@@ -843,36 +936,27 @@ ...@@ -843,36 +936,27 @@
"The dimensions of the training set x (200, 2) and y (200, 1)\n", "The dimensions of the training set x (200, 2) and y (200, 1)\n",
"The dimensions of the test set x (100, 2) and y (100, 1) \n", "The dimensions of the test set x (100, 2) and y (100, 1) \n",
"\n", "\n",
"epoch: 0 iter: 0 loss: 0.0318 train acc: 1.0000 test acc: 0.5400\n", "epoch: 0 iter: 4 loss: 0.1547 train acc: 0.8500 test acc: 0.6400\n",
"epoch: 0 iter: 50 loss: 0.3359 train acc: 0.0000 test acc: 0.8200\n", "epoch: 3 iter: 4 loss: 0.1337 train acc: 0.9500 test acc: 0.8800\n",
"epoch: 0 iter: 100 loss: 0.0396 train acc: 1.0000 test acc: 0.8700\n", "epoch: 6 iter: 4 loss: 0.1265 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 0 iter: 150 loss: 0.0952 train acc: 1.0000 test acc: 1.0000\n", "epoch: 9 iter: 4 loss: 0.1247 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 0 loss: 0.1586 train acc: 1.0000 test acc: 1.0000\n", "epoch: 12 iter: 4 loss: 0.1261 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 50 loss: 0.1534 train acc: 1.0000 test acc: 1.0000\n", "epoch: 15 iter: 4 loss: 0.1268 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 100 loss: 0.0624 train acc: 1.0000 test acc: 1.0000\n", "epoch: 18 iter: 4 loss: 0.1269 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 1 iter: 150 loss: 0.0883 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 0 loss: 0.1627 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 50 loss: 0.1378 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 100 loss: 0.0669 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 2 iter: 150 loss: 0.0860 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 0 loss: 0.1658 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 50 loss: 0.1359 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 100 loss: 0.0671 train acc: 1.0000 test acc: 1.0000\n",
"epoch: 3 iter: 150 loss: 0.0849 train acc: 1.0000 test acc: 1.0000\n",
"The trained circuit:\n", "The trained circuit:\n",
"--Rz(0.542)----Ry(3.456)----Rz(2.699)----*--------------x----Ry(6.153)--\n", "--Rz(0.542)----Ry(3.458)----Rz(2.692)----*--------------x----Ry(6.191)--\n",
" | | \n", " | | \n",
"--Rz(3.514)----Ry(1.543)----Rz(2.499)----x----*---------|----Ry(3.050)--\n", "--Rz(3.514)----Ry(1.543)----Rz(2.499)----x----*---------|----Ry(2.968)--\n",
" | | \n", " | | \n",
"--Rz(5.947)----Ry(3.161)----Rz(3.897)---------x----*----|----Ry(1.583)--\n", "--Rz(5.947)----Ry(3.161)----Rz(3.897)---------x----*----|----Ry(1.579)--\n",
" | | \n", " | | \n",
"--Rz(0.718)----Ry(5.038)----Rz(1.348)--------------x----*----Ry(0.030)--\n", "--Rz(0.718)----Ry(5.038)----Rz(1.348)--------------x----*----Ry(0.036)--\n",
" \n" " \n"
] ]
}, },
{ {
"data": { "data": {
"image/png": "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\n", "image/png": "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",
"text/plain": [ "text/plain": [
"<Figure size 432x288 with 2 Axes>" "<Figure size 432x288 with 2 Axes>"
] ]
...@@ -886,7 +970,7 @@ ...@@ -886,7 +970,7 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"The main program finished running in 23.123697519302368 seconds.\n" "The main program finished running in 7.169757127761841 seconds.\n"
] ]
} }
], ],
...@@ -901,10 +985,11 @@ ...@@ -901,10 +985,11 @@
" Ntest = 100, # Specify the test set size\n", " Ntest = 100, # Specify the test set size\n",
" gap = 0.5, # Set the width of the decision boundary\n", " gap = 0.5, # Set the width of the decision boundary\n",
" N = 4, # Number of qubits required\n", " N = 4, # Number of qubits required\n",
" D = 1, # Circuit depth\n", " DEPTH = 1, # Circuit depth\n",
" EPOCH = 4, # Number of training epochs\n", " BATCH = 20, # Batch size during training\n",
" EPOCH = int(200 * BATCH / Ntrain),\n",
" # Number of training epochs, the total iteration number \"EPOCH * (Ntrain / BATCH)\" is chosen to be about 200\n",
" LR = 0.01, # Set the learning rate\n", " LR = 0.01, # Set the learning rate\n",
" BATCH = 1, # Batch size during training\n",
" seed_paras = 19, # Set random seed to initialize various parameters\n", " seed_paras = 19, # Set random seed to initialize various parameters\n",
" seed_data = 2, # Fixed random seed required to generate the data set\n", " seed_data = 2, # Fixed random seed required to generate the data set\n",
" )\n", " )\n",
...@@ -935,7 +1020,7 @@ ...@@ -935,7 +1020,7 @@
"\n", "\n",
"[2] Farhi, Edward, and Hartmut Neven. Classification with quantum neural networks on near term processors. [arXiv preprint arXiv:1802.06002 (2018).](https://arxiv.org/abs/1802.06002)\n", "[2] Farhi, Edward, and Hartmut Neven. Classification with quantum neural networks on near term processors. [arXiv preprint arXiv:1802.06002 (2018).](https://arxiv.org/abs/1802.06002)\n",
"\n", "\n",
"[3] [Schuld, Maria, et al. Circuit-centric quantum classifiers. [Physical Review A 101.3 (2020): 032308.](https://arxiv.org/abs/1804.00633)\n" "[3] Schuld, Maria, et al. Circuit-centric quantum classifiers. [Physical Review A 101.3 (2020): 032308.](https://arxiv.org/abs/1804.00633)\n"
] ]
} }
], ],
...@@ -955,7 +1040,7 @@ ...@@ -955,7 +1040,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.7.10" "version": "3.7.11"
}, },
"toc": { "toc": {
"base_numbering": 1, "base_numbering": 1,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册