摘要:本文从零带你体验量子神经网络在自然语言处理中的应用

本文分享自华为云社区《体验量子神经网络在自然语言处理中的应用》,原文作者:JeffDing。

本文从零带你体验量子神经网络在自然语言处理中的应用。

一、运行环境

CPU:Intel(R) Core(TM) i7-4712MQ CPU @ 2.30GHz

内存:4GB

操作系统:Ubuntu 20.10

MindSpore版本:1.2

二、安装Mindspore

参考官网安装文档:https://www.mindspore.cn/install/

安装MindQuantum参照文档 :https://gitee.com/mindspore/mindquantum/blob/r0.1/README_CN.md

通过Mindspore.__version__查看版本

三、体验量子神经网络在自然语言处理中的应用

1.环境准备

入包 import numpy as np import time from projectq.ops import QubitOperator import mindspore.ops as ops import mindspore.dataset as ds from mindspore import nn from mindspore.train.callback import LossMonitor from mindspore import Model from mindquantum.nn import MindQuantumLayer from mindquantum import Hamiltonian, Circuit, RX, RY, X, H, UN #数据预处理 def GenerateWordDictAndSample(corpus, window=2): all_words = corpus.split() word_set = list(set(all_words)) word_set.sort() word_dict = {w: i for i,w in enumerate(word_set)} sampling = [] for index, word in enumerate(all_words[window:-window]): around = [] for i in range(index, index + 2*window + 1): if i != index + window: around.append(all_words) sampling.append([around,all_words[index + window]]) return word_dict, sampling word_dict, sample = GenerateWordDictAndSample("I love natural language processing") print(word_dict) print('word dict size: ', len(word_dict)) print('samples: ', sample) print('number of samples: ', len(sample))

运行结果:

[注意] 当前模拟器线程为 1。如果您的模拟速度较慢,请根据您的模型将 OMP_NUM_THREADS 设置为适当的数字。
{'I': 0, 'language': 1, 'love': 2, 'natural': 3, 'processing': 4}
word dict size: 5
samples: [[['I', 'love', ' language', 'processing'], 'natural']]
样本数:1

可知如上信息,我们得到该句子的词典大小为 5,能够产生一个样本点。

2.编码线路

def Genera**coderCircuit(n_qubits, prefix=''): if len(prefix) != 0 and prefix[-1] != '_': prefix += '_' circ = Circuit() for i in range(n_qubits): circ += RX(prefix + str(i)).on(i) return circ Genera**coderCircuit(3,prefix='e')

运行结果:

RX(e_0|0)
RX(e_1|1)
RX(e_2|2)

我们通常用|0〉">|0〉|0〉和|1〉">|1〉|1〉来标记二能级量子比特的两个状态,由态叠加原理,量子比特还可以处于这两个状态的叠加态:

|ψ〉=α|0〉+β|1〉">|ψ〉=α|0〉+β|1〉|ψ〉=α|0〉+β|1〉

对于n">nn比特的量子态,其将处于2n">2n2n维的希尔伯特空间中。对于上面由5个词构成的词典,我们只需要⌈log2⁡5⌉=3">⌈log25⌉=3⌈log2⁡5⌉=3个量子比特即可完成编码,这也体现出量子计算的优越性。

例如对于上面词典中的“love”,其对应的标签为2,2的二进制表示为010,我们只需将编码线路中的e_0、e_1和e_2分别设为0">00、π">ππ和0">00即可。

#通过Evolution算子来验证 from mindquantum.nn import generate_evolution_operator from mindspore import context from mindspore import Tensor n_qubits = 3 # number of qubits of this quantum circuit label = 2 # label need to encode label_bin = bin(label)[-1:1:-1].ljust(n_qubits,'0') # binary form of label label_array = np.array([int(i)*np.pi for i in label_bin]).astype(np.float32) # parameter value of encoder encoder = Genera**coderCircuit(n_qubits, prefix='e') # encoder circuit encoder_para_names = encoder.parameter_resolver().para_name # parameter names of encoder print("Label is: ", label) print("Binary label is: ", label_bin) print("Parameters of encoder is: \n", np.round(label_array, 5)) print("Encoder circuit is: \n", encoder) print("Encoder parameter names are: \n", encoder_para_names) context.set_context(mode=context.GRAPH_MODE, device_target="CPU") # quantum state evolution operator evol = generate_evolution_operator(param_names=encoder_para_names, circuit=encoder) state = evol(Tensor(label_array)) state = state.asnumpy() quantum_state = state[:, 0] + 1j * state[:, 1] amp = np.round(np.abs(quantum_state)**2, 3) print("Amplitude of quantum state is: \n", amp) print("Label in quantum state is: ", np.argmax(amp))

运行结果:

Label is:  2
Binary label is:  010
Parameters of encoder is: 
 [0.      3.14159 0.     ]
Encoder circuit is: 
 RX(e_0|0)
RX(e_1|1)
RX(e_2|2)
Encoder parameter names are: 
 ['e_0', 'e_1', 'e_2']
Amplitude of quantum state is: 
 [0. 0. 1. 0. 0. 0. 0. 0.]
Label in quantum state is:  2

通过上面的验证,我们发现,对于标签为2的数据,最后得到量子态的振幅最大的位置也是2,因此得到的量子态正是对输入标签的编码。我们将对数据编码生成参数数值的过程总结成如下函数。

def GenerateTrainData(sample, word_dict):n_qubits = np.int(np.ceil(np.log2(1 + max(word_dict.values()))))data_x = []data_y = []for around, center in sample:data_x.append([])for word in around:label = word_dict[word]label_bin = bin(label)[-1:1:-1].ljust(n_qubits,'0')label_array = [int(i)*np.pi for i in label_bin]data_x[-1].extend(label_array)data_y.append(word_dict[center])return np.array(data_x).astype(np.float32), np.array(data_y).astype(np.int32)
GenerateTrainData(sample, word_dict)

运行结果:

(array([[0.       , 0.       , 0.       , 0.       , 3.1415927, 0.       ,
         3.1415927, 0.       , 0.       , 0.       , 0.       , 3.1415927]],
       dtype=float32),
 array([3], dtype=int32))

根据上面的结果,我们将4个输入的词编码的信息合并为一个更长向量,便于后续神经网络调用。

3.Ansatz线路

#定义如下函数生成Ansatz线路 def GenerateAnsatzCircuit(n_qubits, layers, prefix=''): if len(prefix) != 0 and prefix[-1] != '_': prefix += '_' circ = Circuit() for l in range(layers): for i in range(n_qubits): circ += RY(prefix + str(l) + '_' + str(i)).on(i) for i in range(l % 2, n_qubits, 2): if i < n_qubits and i + 1 < n_qubits: circ += X.on(i + 1, i) return circ GenerateAnsatzCircuit(5, 2, 'a')

运行结果:

RY(a_0_0|0)
RY(a_0_1|1)
RY(a_0_2|2)
RY(a_0_3|3)
RY(a_0_4|4)
X(1 <-: 0)
X(3 <-: 2)
RY(a_1_0|0)
RY(a_1_1|1)
RY(a_1_2|2)
RY(a_1_3|3)
RY(a_1_4|4)
X(2 <-: 1)
X(4 <-: 3)

4.测量

def GenerateEmbeddingHamiltonian(dims, n_qubits): hams = [] for i in range(dims): s = '' for j, k in enumerate(bin(i + 1)[-1:1:-1]): if k == '1': s = s + 'Z' + str(j) + ' ' hams.append(Hamiltonian(QubitOperator(s))) return hams GenerateEmbeddingHamiltonian(5, 5)

运行结果:

[1.0 Z0, 1.0 Z1, 1.0 Z0 Z1, 1.0 Z2, 1.0 Z0 Z2]

5.量子版词向量嵌入层

运行之前请在终端运行export OMP_NUM_THREADS=4

def QEmbedding(num_embedding, embedding_dim, window, layers, n_threads):n_qubits = int(np.ceil(np.log2(num_embedding)))hams = GenerateEmbeddingHamiltonian(embedding_dim, n_qubits)circ = Circuit()circ = UN(H, n_qubits)encoder_param_name = []ansatz_param_name = []for w in range(2 * window):encoder = Genera**coderCircuit(n_qubits, 'Encoder_' + str(w))ansatz = GenerateAnsatzCircuit(n_qubits, layers, 'Ansatz_' + str(w))encoder.no_grad()circ += encodercirc += ansatzencoder_param_name.extend(list(encoder.parameter_resolver()))ansatz_param_name.extend(list(ansatz.parameter_resolver()))net = MindQuantumLayer(encoder_param_name,ansatz_param_name,circ,hams,n_threads=n_threads)return netclass CBOW(nn.Cell):def __init__(self, num_embedding, embedding_dim, window, layers, n_threads,hidden_dim):super(CBOW, self).__init__()self.embedding = QEmbedding(num_embedding, embedding_dim, window,layers, n_threads)self.dense1 = nn.Dense(embedding_dim, hidden_dim)self.dense2 = nn.Dense(hidden_dim, num_embedding)self.relu = ops.ReLU()def construct(self, x):embed = self.embedding(x)out = self.dense1(embed)out = self.relu(out)out = self.dense2(out)return outclass LossMonitorWithCollection(LossMonitor):def __init__(self, per_print_times=1):super(LossMonitorWithCollection, self).__init__(per_print_times)self.loss = []def begin(self, run_context):self.begin_time = time.time()def end(self, run_context):self.end_time = time.time()print('Total time used: {}'.format(self.end_time - self.begin_time))def epoch_begin(self, run_context):self.epoch_begin_time = time.time()def epoch_end(self, run_context):cb_params = run_context.original_args()self.epoch_end_time = time.time()if self._per_print_times != 0 and cb_params.cur_step_num % self._per_print_times == 0:print('')def step_end(self, run_context):cb_params = run_context.original_args()loss = cb_params.net_outputsif isinstance(loss, (tuple, list)):if isinstance(loss[0], Tensor) and isinstance(loss[0].asnumpy(), np.ndarray):loss = loss[0]if isinstance(loss, Tensor) and isinstance(loss.asnumpy(), np.ndarray):loss = np.mean(loss.asnumpy())cur_step_in_epoch = (cb_params.cur_step_num - 1) % cb_params.batch_num + 1if isinstance(loss, float) and (np.isnan(loss) or np.isinf(loss)):raise ValueError("epoch: {} step: {}. Invalid loss, terminating training.".format(cb_params.cur_epoch_num, cur_step_in_epoch))self.loss.append(loss)if self._per_print_times != 0 and cb_params.cur_step_num % self._per_print_times == 0:print("\repoch: %+3s step: %+3s time: %5.5s, loss is %5.5s" % (cb_params.cur_epoch_num, cur_step_in_epoch, time.time() - self.epoch_begin_time, loss), flush=True, end='')import mindspore as msfrom mindspore import contextfrom mindspore import Tensorcontext.set_context(mode=context.GRAPH_MODE, device_target="CPU")corpus = """We are about to study the idea of a computational process.Computational processes are abstract beings that inhabit computers.As they evolve, processes manipulate other abstract things called data.The evolution of a process is directed by a pattern of rulescalled a program. People create programs to direct processes. In effect,we conjure the spirits of the computer with our spells."""ms.set_seed(42)window_size = 2embedding_dim = 10hidden_dim = 128word_dict, sample = GenerateWordDictAndSample(corpus, window=window_size)train_x,train_y = GenerateTrainData(sample, word_dict)train_loader = ds.NumpySlicesDataset({"around": train_x,"center": train_y},shuffle=False).batch(3)net = CBOW(len(word_dict), embedding_dim, window_size, 3, 4, hidden_dim)net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')net_opt = nn.Momentum(net.trainable_params(), 0.01, 0.9)loss_monitor = LossMonitorWithCollection(500)model = Model(net, net_loss, net_opt)model.train(350, train_loader, callbacks=[loss_monitor], dataset_sink_mode=False)

运行结果:

epoch:  25 step:  20 time: 36.14, loss is 3.154
epoch:  50 step:  20 time: 36.51, loss is 2.945
epoch:  75 step:  20 time: 36.71, loss is 0.226
epoch: 100 step:  20 time: 36.56, loss is 0.016
Total time used: 3668.7517251968384

打印收敛过程中的损失函数值:

import matplotlib.pyplot as plt plt.plot(loss_monitor.loss,'.') plt.xlabel('Steps') plt.ylabel('Loss') plt.show()

打印量子嵌入层的量子线路中的参数

net.embedding.weight.asnumpy()

array([-6.4384632e-02, -1.2658586e-01,  1.0083634e-01, -1.3011757e-01,
        1.4005195e-03, -1.9296107e-04, -7.9315618e-02, -2.9339856e-01,
        7.6259784e-02,  2.9878360e-01, -1.3091319e-04,  6.8271365e-03,
       -8.5563213e-02, -2.4168481e-01, -8.2548901e-02,  3.0743122e-01,
       -7.8157615e-04, -3.2907310e-03, -1.4412615e-01, -1.9241245e-01,
       -7.5561814e-02, -3.1189525e-03,  3.8330450e-03, -1.4486053e-04,
       -4.8195502e-01,  5.3657538e-01,  3.8986996e-02,  1.7286544e-01,
       -3.4090234e-03, -9.5573599e-03, -4.8208281e-01,  5.9604627e-01,
       -9.7009525e-02,  1.8312852e-01,  9.5267012e-04, -1.2261710e-03,
        3.4219343e-02,  8.0031365e-02, -4.5349425e-01,  3.7360430e-01,
        8.9665735e-03,  2.1575980e-03, -2.3871836e-01, -2.4819574e-01,
       -6.2781256e-01,  4.3640310e-01, -9.7688911e-03, -3.9542126e-03,
       -2.4010721e-01,  4.8120108e-02, -5.6876510e-01,  4.3773583e-01,
        4.7241263e-03,  1.4138421e-02, -1.2472854e-03,  1.1096644e-01,
        7.1980711e-03,  7.3047012e-02,  2.0803964e-02,  1.1490706e-02,
        8.6638138e-02,  2.0503466e-01,  4.7177267e-03, -1.8399477e-02,
        1.1631225e-02,  2.0587114e-03,  7.6739892e-02, -6.3548386e-02,
        1.7298019e-01, -1.9143591e-02,  4.1606693e-04, -9.2881303e-03],
      dtype=float32)

6.经典版词向量嵌入层

class CBOWClassical(nn.Cell):def __init__(self, num_embedding, embedding_dim, window, hidden_dim):super(CBOWClassical, self).__init__()self.dim = 2 * window * embedding_dimself.embedding = nn.Embedding(num_embedding, embedding_dim, True)self.dense1 = nn.Dense(self.dim, hidden_dim)self.dense2 = nn.Dense(hidden_dim, num_embedding)self.relu = ops.ReLU()self.reshape = ops.Reshape()def construct(self, x):embed = self.embedding(x)embed = self.reshape(embed, (-1, self.dim))out = self.dense1(embed)out = self.relu(out)out = self.dense2(out)return outtrain_x = []train_y = []for i in sample:around, center = itrain_y.append(word_dict[center])train_x.append([])for j in around:train_x[-1].append(word_dict[j])train_x = np.array(train_x).astype(np.int32)train_y = np.array(train_y).astype(np.int32)print("train_x shape: ", train_x.shape)print("train_y shape: ", train_y.shape)train_loader = ds.NumpySlicesDataset({"around": train_x,"center": train_y},shuffle=False).batch(3)net = CBOWClassical(len(word_dict), embedding_dim, window_size, hidden_dim)net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')net_opt = nn.Momentum(net.trainable_params(), 0.01, 0.9)loss_monitor = LossMonitorWithCollection(500)model = Model(net, net_loss, net_opt)model.train(350, train_loader, callbacks=[loss_monitor], dataset_sink_mode=False)

运行结果:

train_x shape:  (58, 4)
train_y shape:  (58,)
epoch:  25 step:  20 time: 0.077, loss is 3.156
epoch:  50 step:  20 time: 0.095, loss is 3.025
epoch:  75 step:  20 time: 0.115, loss is 2.996
epoch: 100 step:  20 time: 0.088, loss is 1.773
epoch: 125 step:  20 time: 0.083, loss is 0.172
epoch: 150 step:  20 time: 0.110, loss is 0.008
epoch: 175 step:  20 time: 0.086, loss is 0.003
epoch: 200 step:  20 time: 0.081, loss is 0.001
epoch: 225 step:  20 time: 0.081, loss is 0.000
epoch: 250 step:  20 time: 0.078, loss is 0.000
epoch: 275 step:  20 time: 0.079, loss is 0.000
epoch: 300 step:  20 time: 0.080, loss is 0.000
epoch: 325 step:  20 time: 0.078, loss is 0.000
epoch: 350 step:  20 time: 0.081, loss is 0.000
Total time used: 30.569124698638916

收敛图:

由上可知,通过量子模拟得到的量子版词嵌入模型也能很好的完成嵌入任务。当数据集大到经典计算机算力难以承受时,量子计算机将能够轻松处理这类问题。

点击关注,第一时间了解华为云新鲜技术~

技术实践丨体验量子神经网络在自然语言处理中的应用相关推荐

  1. 技术实践丨基于MindSpore框架Yolov3-darknet模型的篮球动作检测体验

    摘要:通过对篮球动作的分类训练及识别检测实例的讲解和体验,使我们了解了Yolov3模型的原理.架构等基本知识,为日后的深入学习奠定了基础. 背靠全新的设计理念,华为云推出了 MindSpore深度学习 ...

  2. yolov3模型识别不出训练图片_技术实践丨基于MindSpore框架Yolov3-darknet模型的篮球动作检测体验...

    摘要:通过对篮球动作的分类训练及识别检测实例的讲解和体验,使我们了解了Yolov3模型的原理.架构等基本知识,为日后的深入学习奠定了基础. 背靠全新的设计理念,华为云推出了 MindSpore深度学习 ...

  3. 技术实践丨GaussDB(DWS)运维管理功能“升级”的原理和使用

    摘要:本文将详细介绍GaussDB(DWS)重要运维管理功能"升级"的原理和使用. 运维管理模块是任何软件产品最基础和重要的一部分.是软件产品的门户,也是用户接触和使用软件产品的和 ...

  4. 技术实践丨如何解决异步接口请求快慢不均导致的数据错误问题?

    本文分享自华为云社区<如何解决异步接口请求快慢不均导致的数据错误问题?>,原文作者:Kagol . 引言 搜索功能,我想很多业务都会涉及,这个功能的特点是: 用户可以在输入框中输入一个关键 ...

  5. 技术实践丨列存表并发更新时的锁等待问题原理

    本文分享自华为云社区<列存表并发更新时时的锁等待问题原理>,原文作者:PFloyd . 当开启transaction,执行updata的语句执行成功,不执行commit或rollback: ...

  6. 技术实践丨Prometheus+Grafana搭建HBase监控仪表盘

    摘要:Grafana+Prometheus是目前非常流行的监控方案,图形化展示非常强大. 本文分享自华为云社区<Prometheus+Grafana搭建HBase监控仪表盘>,原文作者:L ...

  7. 技术实践丨React Native 项目 Web 端同构

    摘要:尽管 React Native 已经进入开源的第 6 个年头,距离发布 1.0 版本依旧是遥遥无期."Learn once, write anywhere",完全不影响 Re ...

  8. 技术实践丨PostgreSQL插件之pg_dirtyread “闪回查询“

    摘要:Oracle数据库有时候不小心删除掉数据,想查询这些数据,或者恢复数据,就可以使用带有as of子句的select语句进行闪回查询. PG粉有福了,下面介绍一种类似"闪回查询" ...

  9. 技术实践丨PostgreSQL开启Huge Page场景分析

    PostgreSQL用户经常发现,服务端在连接数较大的情况下,会出现系统内存消耗过多的情况,严重者可能会造成OOM.但是服务端配置的共享内存(shared_buffers,wal_buffers等)是 ...

最新文章

  1. python标准函数有哪些_python基本语法有哪些?
  2. storm自定义分组与Hbase预分区结合节省内存消耗
  3. 实现 ASP.NET 网站地图提供者
  4. 杭电oj2043密码
  5. 【转】增强 scite 编辑器的代码提示功能
  6. 后缀自动机(SAM)构造实现过程演示+习题集锦
  7. java并发数据共享机制_Java并发编程:核心理论之数据共享性
  8. 单列表_使用Excel中的quot;记录单quot;功能快速录入数据
  9. Jsoup 数据修改
  10. 清空 linux 服务器,Linux服务器清理
  11. React Hooks 梳理
  12. 453.最小移动次数使数组元素相等
  13. 28款数据恢复软件分类介绍
  14. android真机调试工具,ADB 安卓真机调试工具
  15. Unity中,图片 替换 光标 —— 疑问解答
  16. linux177端口怎么打开,AIX5.3,如何使用xmanager管理?177端口打不开的相关推荐_ChinaUnix论坛...
  17. 2021小结暨2022打脸计划
  18. kaggle操作入门
  19. MyBatis自定义自定义动态SQL解析方式
  20. java 电子围栏_基于H5与webGL的 3d 电子围栏展示

热门文章

  1. es6 next()方法的参数
  2. 视觉SLAM十四讲学习笔记-第六讲学习笔记总结(1)---非线性优化原理
  3. c语言printf族函数,C语言中的printf族函数深入详解
  4. 集群搭建在一台计算机上,服务器集群
  5. c语言链表错误,C语言创建链表错误之通过指针参数申请动态内存实例分析
  6. android 删除wifi文件在哪里设置,如何删除无线终端的无线配置文件
  7. mysql教程qt linux_一步步学Qt,第四天-Linux 下mysql数据库链接
  8. python的scapy_Python Scapy vs dp
  9. ios客户端做屏蔽_Transmission 屏蔽迅雷反吸血脚本
  10. 线段树区改区查标记永久化板子