Categories
程式開發

谷歌開源用於訓練量子模型的機器學習框架TensorFlow Quantum


物理學家理查德· 費曼曾說過:

自然不是古板的,如果想要要模擬自然,最好使用量子力學定律。

2020年3月11日,TensorFlow Dev Summit峰會通過線上直播的方式與各位開發者見面。會上,谷歌介紹了近期宣布開源的一款用於訓練量子模型的機器學習庫TensorFlow Quantum(簡稱TFQ)。谷歌表示,該量子機器學習模型能夠處理量子數據,並能夠在量子計算機上執行。

谷歌開源用於訓練量子模型的機器學習框架TensorFlow Quantum 1

量子機器學習庫TensorFlow Quantum

機器學習(ML)雖然不能精確模擬自然界中的系統,但卻能夠學習系統模型並預測系統行為。在過去幾年,經典的ML模型解決了科學領域諸多難題,在癌症檢測、地震餘震預測、極端天氣預測以及系外行星探測等方面發揮了巨大作用。

近年來,隨著量子計算技術的發展,在量子機器學習模型上的新發現將對世界級重大問題產生深遠影響,從而帶來醫學、材料、傳感和通信領域的突破。但是,迄今為止我們遇到的瓶頸是,缺乏研究工具來發現有用的、可以處理量子數據並能在計算機上使用的量子機器學習模型。

基於此,谷歌最神秘的部門Google X與滑鐵盧大學和大眾汽車公司等合作,聯合發布TensorFlow Quantum(TFQ),這是一個用於快速建立量子ML模型原型的開源庫。 TFQ為量子計算和機器學習研究社區的結合提供了必要工具,從而控制/建模自然或人工量子系統,比如內含大約50~100量子比特的噪聲中級量子處理器(NISQ)。

在底層,TFQ 集成了NISQ算法的開源框架Cirq(Cirq 是Google 專為NISQ 算法打造的框架,允許開發者為特定的量子處理器編寫量子算法)和TensorFlow,通過提供與現有TensorFlow API兼容的量子計算原語和高性能量子電路模擬器,為鑑別、生成量子經典模型的設計實現,提供高層次的抽象。

量子機器學習模型是什麼?

量子模型能用量子力學原點表示和概括數據。但是,要了解量子模型,必須引入兩個概念:量子數據模型和混合量子經典模型。

量子數據模型表現出量子疊加和量子糾纏的特性,導致聯合概率分佈,這可能需要成倍數量的經典計算資源來表示或存儲。能夠在量子處理器/傳感器/網絡上生成/模擬的量子數據包括化學物質和量子物質的模擬、量子控制、量子通信網絡、量子計算學等。

但一個不容忽視的問題是,NISQ處理器生成的量子數據是嘈雜的,通常在測量發生之前就被糾纏了。但是,將量子機器學習應用於嘈雜的糾纏量子數據上,可以最大程度地提取有用的經典信息。基於這種技術的啟發,TFQ庫為模型的開發提供了基元(該模型可分解和概括量子數據中的關聯),從而為改進現有量子算法或發現新的量子算法提供了可能。

引入的第二個概念是混合量子經典模型。由於近期的量子處理器仍然很小且嘈雜,因此量子模型不能單獨使用量子處理器,NISQ處理器需要與經典處理器協同工作才有效。由於TensorFlow已經支持跨CPU、GPU和TPU的異構計算,因此它是試驗混合量子經典算法的天然平台。

TFQ包含了特定量子計算所需的基本結構,例如量子比特、門、電路和測量運算符。用戶指定的量子計算然後可以在模擬或真實硬件上執行。 Cirq也包含了大量機器,可幫助用戶為NISQ機器(例如編譯器和調度程序)設計出高效算法,並且能使混合量子經典算法的實現在量子電路模擬器上運行,並最終在量子處理器上運行。

谷歌開源用於訓練量子模型的機器學習框架TensorFlow Quantum 2

如今,谷歌已經將TFQ應用到了混合量子經典卷積神經網絡、量子控制的機器學習、量子神經網絡的分層學習、量子動態學習、混合量子態的生成建模以及通過經典遞歸神經網絡來學習量子神經網絡等方面。以及通過經典循環神經網絡,來學習量子神經網絡等等方面。

谷歌團隊在TFQ白皮書中放出了這些量子應用的示例,並能在瀏覽器中通過Colab運行(項目地址:https://github.com/tensorflow/quantum/tree/research)。

TFQ的工作原理

TFQ能夠幫助研究人員在單個計算圖中構建量子數據集、量子模型和作為張量的經典控制參數。導致經典概率事件的量子測量結果可通過TensorFlow Ops獲得,可用標準Keras函數進行訓練。

為直觀地闡述如何使用量子數據,可以考慮使用量子神經網絡對量子狀態進行監督分類。正如經典ML一樣,量子ML面臨的關鍵問題是如何對“噪音數據”進行分類。為了建立和訓練這種模型,研究人員需要做的工作有:

  • 準備一個量子數據集

量子數據被加載為張量(數字的多維數組)。每個量子數據張量都指定為用Cirq編寫的量子電路,該電路可實時生成量子數據。張量由TensorFlow在量子計算機上執行以生成量子數據集。

  • 評估量子神經網絡模型

研究人員可以使用Cirq設計量子神經網絡原型,然後將其嵌入TensorFlow計算圖中。基於對量子數據結構的認知,可以從幾大類中選擇參數化的量子模型。該模型的目標是執行量子處理,以提取隱藏在典型糾纏狀態下的信息。換言之,量子模型本質上是對輸入的量子數據進行分離,將隱藏的信息編碼在經典關聯中,從而使其可用於局部測量和經典後處理(算法)。

  • 樣本或平均值

量子態的測量從經典隨機變量中,以樣本形式提取經典信息。來自該隨機變量值的分佈通常取決於量子態本身以及所測得的可觀測值。由於許多變分算法依賴於測量值的平均值,因此TFQ提供了在涉及步驟(1)和(2)的多個運行中求平均值的方法。

  • 評估經典神經網絡模型

提取經典信息後,其格式適用於進一步經典後處理。由於所提取的信息仍然可能被編碼為測量期望之間的經典關聯,因此可以使用經典的深度神經網絡來提取這種關聯。

  • 評估成本函數

根據經典後處理的結果,評估成本函數。這可以基於模型執行分類任務的準確性(如果量子數據被標記),或者基於其他標準(如果任務是無監督的)。

  • 評估梯度和更新參數

評估成本函數後,應更新管道中的自由參數,這通常是通過梯度下降執行的。

谷歌開源用於訓練量子模型的機器學習框架TensorFlow Quantum 3

TensorFlow Quantum的關鍵特徵是它能夠同時訓練和執行多個量子電路。 TensorFlow能夠跨計算機集群進行並行計算,並能夠在多核計算機上模擬相對較大的量子電路。為了實現後者,谷歌還宣布發布新的高性能開源量子電路模擬器 qsim (項目地址:https://github.com/quantumlib/qsim),該模擬器已證明能夠在111秒內模擬門深度為14的32比特量子電路。

接下來,谷歌列舉了具體的示例來幫助開發者理解。

基礎知識

安裝TensorFlow Quantum:

pip install -q tensorflow-quantum

導入TensorFlow和模塊依賴項:

import tensorflow as tf
import tensorflow_quantum as tfq

import cirq
import sympy
import numpy as np

# visualization tools
%matplotlib inline
import matplotlib.pyplot as plt
from cirq.contrib.svg import SVGCircuit

參數化量子電路

現在,使用cirq來模擬量子電路。 Cirq是谷歌提供的用於量子計算的Python庫,可以使用它來定義電路,包括靜態和參數化門。 Cirq使用SymPy符號表示自由參數:

a, b = sympy.symbols('a b')

以下代碼使用參數創建一個兩比特電路:

# Create two qubits
q0, q1 = cirq.GridQubit.rect(1, 2)

# Create a circuit on these qubits using the parameters you created above.
circuit = cirq.Circuit(
    cirq.rx(a).on(q0),
    cirq.ry(b).on(q1), cirq.CNOT(control=q0, target=q1))

SVGCircuit(circuit)
findfont: Font family ['Arial'] not found. Falling back to DejaVu Sans.

谷歌開源用於訓練量子模型的機器學習框架TensorFlow Quantum 4

要評估電路,可以使用該cirq.Simulator,可以通過傳入cirq.ParamResolver對象來用特定編號替換電路中的自由參數。以下代碼計算參數化電路的原始狀態向量輸出:

# Calculate a state vector with a=0.5 and b=-0.5.
resolver = cirq.ParamResolver({a: 0.5, b: -0.5})
output_state_vector = cirq.Simulator().simulate(circuit, resolver).final_state
output_state_vector

我們得到具有4個元素的狀態向量:

数组([0.9387913 + 0.j,-0.23971277 + 0.j,
        0. + 0.06120872j,0. -0.23971277j],dtype = complex64)

通常,我們不能直接從量子計算機獲得狀態向量。因此,我們通常不嘗試讀取狀態向量,而是嘗試計算與狀態向量間接相關的特定值。

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

這是Z運算符的期望值。通常,我們在布洛球的Z軸上獲得量子計算結果。通過獲取樣本,您可以輕鬆估算pauli Z運算符的期望值。

谷歌開源用於訓練量子模型的機器學習框架TensorFlow Quantum 5

量子態表示為布洛球

結果是:

0.8775825500488281

如果:

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

結果為:

-0.04063427448272705

量子電路作為張量

TensorFlow Quantum(TFQ)提供tfq.convert_to_tensor將Cirq對象轉換為張量,開發者可以將Cirq對象發送到谷歌的 quantum layers和quantum ops,可以在Cirq電路和Cirq Paulis的列表或數組上調用該函數:

# Rank 1 tensor containing 1 circuit.
circuit_tensor = tfq.convert_to_tensor([circuit])

print(circuit_tensor.shape)
print(circuit_tensor.dtype)

結果如下:

(1,)

這會將Cirq對象編碼為tf.string張量,tfq操作可根據需要對其進行解碼:

# Rank 1 tensor containing 2 Pauli operators.
pauli_tensor = tfq.convert_to_tensor([z0, z0x1])
pauli_tensor.shape

結果為:

TensorShape([2])

量子經典混合

現在,開發者已經了解部分基礎知識,讓我們使用TensorFlow Quantum構建一個混合的量子經典神經網絡,將訓練經典的神經網絡來控制單個量子位。將優化控制以正確準備處於0或1狀態的量子位,從而克服模擬的系統校準誤差。該圖顯示了體系結構:

谷歌開源用於訓練量子模型的機器學習框架TensorFlow Quantum 6

即使沒有神經網絡,這也是一個直接解決的問題,但主題類似於可能使用TFQ解決的實際量子控制問題,演示了使用tfq.layers.ControlledPQC內部的(參數化量子電路)層進行量子經典計算的端到端示例tf.keras.Model。

第一步:受控電路定義

# Parameters that the classical NN will feed values into.
control_params = sympy.symbols('theta_1 theta_2 theta_3')

# Create the parameterized circuit.
qubit = cirq.GridQubit(0, 0)
model_circuit = cirq.Circuit(
    cirq.rz(control_params[0])(qubit),
    cirq.ry(control_params[1])(qubit),
    cirq.rx(control_params[2])(qubit))

SVGCircuit(model_circuit)

谷歌開源用於訓練量子模型的機器學習框架TensorFlow Quantum 7

第二步:定義控制器網絡

# The classical neural network layers.
controller = tf.keras.Sequential([
    tf.keras.layers.Dense(10, activation='elu'),
    tf.keras.layers.Dense(3)
])

給定一批命令,控制器為受控電路輸出一批控制信號。
控制器是隨機初始化的,因此,這些輸出尚無用。

controller(tf.constant([[0.0],[1.0]])).numpy()

結果為:

数组([[0.,0.,0.],
       [-0.16003934,0.26334327,0.3790441]],dtype = float32)

第三步:將控制器連接到電路

使用tfq將控制器連接到被控制電路,作為單一的keras.Model。首先,定義模型的輸入:

# This input is the simulated miscalibration that the model will learn to correct.
circuits_input = tf.keras.Input(shape=(),
                                # The circuit-tensor has dtype `tf.string` 
                                dtype=tf.string,
                                name='circuits_input')

# Commands will be either `0` or `1`, specifying the state to set the qubit to.
commands_input = tf.keras.Input(shape=(1,),
                                dtype=tf.dtypes.float32,
                                name='commands_input')

接下來,將運算應用於這些輸入,以定義計算:

dense_2 = controller(commands_input)

# TFQ layer for classically controlled circuits.
expectation_layer = tfq.layers.ControlledPQC(model_circuit,
                                             # Observe Z
                                             operators = cirq.Z(qubit))
expectation = expectation_layer([circuits_input, dense_2])

現在將此計算打包為tf.keras.Model:

# The full Keras model is built from our layers.
model = tf.keras.Model(inputs=[circuits_input, commands_input],
                       outputs=expectation)

注意:可能需要係統安裝graphviz軟件包。

tf.keras.utils.plot_model(model, show_shapes=True, dpi=70)

結果為:

无法导入pydot。您必须安装pydot和graphviz才能使pydotprint运行。

數據集

模型嘗試為每個命令輸出正確的正確測量值$ hat {Z} $,命令和正確值定義如下:

# The command input values to the classical NN.
commands = np.array([[0], [1]], dtype=np.float32)

# The desired Z expectation value at output of quantum circuit.
expected_outputs = np.array([[1], [-1]], dtype=np.float32)

這不是此任務的整個訓練數據集。數據集中的每個數據點也需要一個輸入電路。

輸入點定義

下面的輸入電路定義了模型將學習校正的隨機失調:

random_rotations = np.random.uniform(0, 2 * np.pi, 3)
noisy_preparation = cirq.Circuit(
  cirq.rx(random_rotations[0])(qubit),
  cirq.ry(random_rotations[1])(qubit),
  cirq.rz(random_rotations[2])(qubit)
)
datapoint_circuits = tfq.convert_to_tensor([
  noisy_preparation
] * 2)  # Make two copied of this circuit

電路有兩個副本,每個數據點一個。

datapoint_circuits.shape
TensorShape([2])

訓練

使用定義的輸入測試tfq模型:

model([datapoint_circuits, commands]).numpy()
数组([[0.16693401],
       [-0.17766671]],dtype = float32)

現在,運行標準的訓練過程將這些值調整為expected_outputs。

optimizer = tf.keras.optimizers.Adam(learning_rate=0.05)
loss = tf.keras.losses.MeanSquaredError()
model.compile(optimizer=optimizer, loss=loss)
history = model.fit(x=[datapoint_circuits, commands],
                    y=expected_outputs,
                    epochs=30,
                    verbose=0)
plt.plot(history.history['loss'])
plt.title("Learning to Control a Qubit")
plt.xlabel("Iterations")
plt.ylabel("Error in Control")
plt.show()

谷歌開源用於訓練量子模型的機器學習框架TensorFlow Quantum 8

從該圖中可以看出,神經網絡已經學會克服系統失調。

驗證輸出

現在,使用經過訓練的模型來校正量子位校準誤差。使用Cirq:

現在,使用經過訓練的模型來校正量子位校準誤差。使用Cirq:

def check_error(command_values, desired_values):
  """Based on the value in `command_value` see how well you could prepare
  the full circuit to have `desired_value` when taking expectation w.r.t. Z."""
  params_to_prepare_output = controller(command_values).numpy()
  full_circuit = noisy_preparation + model_circuit

  # Test how well you can prepare a state to get expectation the expectation
  # value in `desired_values`
  for index in [0, 1]:
    state = cirq_simulator.simulate(
        full_circuit,
        {s:v for (s,v) in zip(control_params, params_to_prepare_output[index])}
    ).final_state
    expectation = z0.expectation_from_wavefunction(state, {qubit: 0}).real
    print(f'For a desired output (expectation) of {desired_values[index]} with'
          f' noisy preparation, the controllernnetwork found the following '
          f'values for theta: {params_to_prepare_output[index]}nWhich gives an'
          f' actual expectation of: {expectation}n')


check_error(commands, expected_outputs)
For a desired output (expectation) of [1.] with noisy preparation, the controller
network found the following values for theta: [-0.22817115 -0.2512403  -1.5496594 ]
Which gives an actual expectation of: 0.9663878679275513

For a desired output (expectation) of [-1.] with noisy preparation, the controller
network found the following values for theta: [-1.2500848  1.4088008  2.5982447]
Which gives an actual expectation of: -0.9780153036117554

訓練期間損失函數的值提供了關於模型學習程度的粗略概念。損耗越小,上述單元格中的期望值越接近desired_values。如果不關心參數值,則可以始終使用tfq命令檢查上面的輸出:

model([datapoint_circuits, commands])

結果為:


如果想了解更多教程,可以訪問Tensorflow網站。

教程鏈接:
https://www.tensorflow.org/quantum/tutorials/hello_many_worlds/
參考連接:
https://ai.googleblog.com/2020/03/announcing-tensorflow-quantum-open.html
論文地址:
https://arxiv.org/pdf/2003.02989.pdf
Crip項目地址:
https://github.com/quantumlib/Cirq