ホーム » TensorFlow Quantum » TensorFlow Quantum 0.2.0 : Tutorials : Hello, many worlds

TensorFlow Quantum 0.2.0 : Tutorials : Hello, many worlds

TensorFlow Quantum 0.2.0 Tutorials : Hello, many worlds (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 03/13/2020 (0.2.0)

* 本ページは、TensorFlow Quantum の以下のページを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

Tutorials : Hello, many worlds

このチュートリアルは古典的ニューラルネットがどのように量子ビット・キャリブレーションエラーを訂正することを学習できるかを示します。それは NISQ 回路を作成し、編集しそして起動するために Cirq – Python フレームワークを導入して Cirq が TensorFlow Quantum とどのように相互作用できるかを実演します。

 

セットアップ

Install 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

 

1. 基本

1.1 Cirq とパラメータ化された量子回路

TensorFlow Quantum (TFQ) を調べる前に、幾つか Cirq の基本を見てみましょう。Cirq は Google からの量子計算のための Python ライブラリです。静的そしてパラメータ化されたゲートを含む、回路を定義するためにそれを使用します。

Cirq は自由パラメータを表すために SymPy シンボルを使用します。

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

次のコードは貴方のパラメータを使用して 2-量子ビット回路を作成します :

# 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.

回路を評価するために、cirq.Simulator インターフェイスを使用できます。cirq.ParamResolver オブジェクトへ渡すことにより特定の数値で回路の自由パラメータを置き換えます。次のコードはパラメータ化された回路の raw 状態ベクトル出力を計算します :

# 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
array([ 0.9387913 +0.j        , -0.23971277+0.j        ,
        0.        +0.06120872j,  0.        -0.23971277j], dtype=complex64)

状態ベクトルはシミュレータの外側では直接的にアクセス可能ではありません (上の出力で複素数に気付くでしょう)。物理的に現実的であるために、測定を指定しなければなりません、これは状態ベクトルを古典コンピュータが理解できる実数に変換します。Cirq は Pauli 演算子 $\hat{X}$, $\hat{Y}$ と $\hat{Z}$ の組み合わせを使用して測定を指定します。例として、次のコードはちょうどシミュレートした状態ベクトル上で $\hat{Z}_0$ と $\frac{1}{2}\hat{Z}_0 + \hat{X}_1$ を測定します :

z0 = cirq.Z(q0)

qubit_map={q0: 0, q1: 1}

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

z0x1.expectation_from_wavefunction(output_state_vector, qubit_map).real
-0.04063427448272705

 

1.2 tensor としての量子回路

TensorFlow Quantum (TFQ) は tfq.convert_to_tensor を提供します、Cirq オブジェクトを tensor に変換する関数です。これは Cirq オブジェクトを 量子層量子 ops に送ることを可能にします。関数は Cirq Circuit と Cirq Pauli のリストか配列上で呼び出せます :

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

print(circuit_tensor.shape)
print(circuit_tensor.dtype)
(1,)
<dtype: 'string'>

これは Cirq オブジェクトを tf.string tensor としてエンコードし、これは必要に応じて tfq 演算がデコードします。

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

 

1.3 回路シミュレーションのバッチ処理

TFQ は期待値、サンプリングと状態ベクトルを計算するための方法を提供します。今は、期待値にフォーカスしましょう。

期待値を計算するための最高位のインターフェイスは tfq.layers.Expectation 層で、これは tf.keras.Layer です。その最も単純な形式では、この層は多くの cirq.ParamResolvers に渡りパラメータ化された回路をシミュレートすることに同値です ; けれども、TFQ は次の TensorFlow セマンティクスをバッチ処理することを可能にし、回路は効率的な C++ コードを使用してシミュレートされます。

私達の a と b パラメータを置き換えるために値のバッチを作成します :

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

Cirq でパラメータ値に渡る回路実行をバッチ処理することはループを必要とします :

cirq_results = []
cirq_simulator = cirq.Simulator()

for vals in batch_vals:
    resolver = cirq.ParamResolver({a: vals[0], b: vals[1]})
    final_state = cirq_simulator.simulate(circuit, resolver).final_state
    cirq_results.append(
        [z0.expectation_from_wavefunction(final_state, {
            q0: 0,
            q1: 1
        }).real])

print('cirq batch results: \n {}'.format(np.array(cirq_results)))
cirq batch results: 
 [[-0.84454578]
 [ 0.805327  ]
 [ 0.78711689]
 [ 0.20195568]
 [ 0.56565583]]

同じ演算が TFQ では単純化されます :

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

 

2. ハイブリッド量子-古典的最適化

基本を見た今、ハイブリッド量子古典的ニューラルネットを構築するために TensorFlow Quantum を使用しましょう。シングル量子ビットを制御するために古典的なニューラルネットを訓練します。制御は 0 か 1 状態の量子ビットを正しく準備するために最適化され、シミュレートされたシステマティックなキャリブレーションエラーに打ち勝ちます。図はアーキテクチャを示します :

ニューラルネットなしでさえも、これは解くのに簡単な問題ですが、主題は (TFQ を使用して解くかもしれない) 実際の量子制御問題に類似しています。それは tf.keras.Model 内部で tfq.layers.ControlledPQC (パラメータ化された量子回路) 層を使用して量子古典的計算の end-to-end なサンプルを実演します。

このチュートリアルの実装のために、このアーキテクチャは 3 パートに分割されます :

  • 入力回路とデータポイント回路: 最初の 3 つの $R$ ゲート。
  • 制御回路: 他の 3 つの $R$ ゲート。
  • コントローラ: 制御回路のパラメータを設定する古典的なニューラルネットワーク。

 

2.1 制御回路定義

上の図で示されるような、学習可能なシングルビット回転を定義します。これは制御回路に対応します。

# 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)

 

2.2 コントローラ

今はコントローラネットワークを定義します :

# 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()
array([[ 0.        ,  0.        ,  0.        ],
       [ 0.8239053 , -0.71268165, -0.62467915]], dtype=float32)

 

2.3 コントローラを回路に接続する

シングル keras.Model として、コントローラを制御回路に接続するために tfq を使用します。

このスタイルのモデル定義についてのより多くは Keras Functional API ガイド を見てください。

最初にモデルへの入力を定義します :

# 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)

ネットワーク・アーキテクチャは下のモデルのプロットで示されます。正しさを検証するためにこのモデルプロットをアーキテクチャ図と比較してください。

Note: graphviz パッケージのシステムインストールを必要とするかもしれません。

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

(訳注 : 原文ママ)

Failed to import pydot. You must install pydot and graphviz for `pydotprint` to work.

このモデルは 2 つの入力を取ります : コントローラのためのコマンド、そして入力回路、コントローラはその出力を訂正しようとします。

 

2.4 データセット

モデルは各コマンドのために正しい測定値を出力しようとします。コマンドと正しい値は下で定義されます。

# 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)

これはこのタスクのための訓練データセット全体ではありません。データセットの各データポイントはまた入力回路を必要とします。

 

2.5 入力回路定義

(訳注: 原文のインデックス番号は修正。)

下の入力回路はモデルが訂正することを学習するランダムなミスキャリブレーションを定義します。

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

回路の 2 つのコピーがあります、各データポイントに一つです。

datapoint_circuits.shape
TensorShape([2])

 

2.6 訓練

定義された入力で tfq モデルをテスト実行できます。

model([datapoint_circuits, commands]).numpy()
array([[-0.44448078],
       [-0.8360152 ]], 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()

このプロットからニューラルネットワークがシステマティックなミスキャリブレーションに打ち勝つことを学習したことを見ることができます。

 

2.7 出力を検証する

今は量子ビット・キャリブレーションエラーを訂正するために、訓練モデルを使用します。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 controller\nnetwork 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: [-1.0564872  3.8130002  0.7327498]
Which gives an actual expectation of: 0.9826827049255371

For a desired output (expectation) of [-1.] with noisy preparation, the controller
network found the following values for theta: [ 0.9573223  -1.4036056  -0.09569579]
Which gives an actual expectation of: -0.9561153650283813

訓練の間の損失関数の値はモデルがどのくらい上手く学習しているかの大雑把な考えを提供します。損失が低くなれば、上のセルの期待値は desired_values に近づきます。パラメータ阿智に関心がないのであれば、tfq を使用して上から常に出力を確認できます :

model([datapoint_circuits, commands])
<tf.Tensor: shape=(2, 1), dtype=float32, numpy=
array([[ 0.9826828],
       [-0.9561153]], dtype=float32)>

 

3 異なる演算子の固有状態を準備することを学習する

1 と 0 に対応する $\pm \hat{Z}$ 固有状態の選択は任意です。1 に $+ \hat{Z}$ 固有状態に対応させてそして 0 に $-\hat{X}$ 固有状態に対応させることを単に容易に望むことができたでしょう。これを達成する一つの方法は、下の図で示されるように各コマンドに対して異なる測定演算子を指定することによります :

これは tfq.layers.Expectation の使用を必要とします。今は入力は 3 つのオブジェクトを含むように増大しました : 回路、コマンドと演算子です。出力は依然として期待値です。

 

3.1 新しいモデル定義

このタスクを達成するためのモデルを見てみましょう :

# Define inputs.
commands_input = tf.keras.layers.Input(shape=(1),
                                       dtype=tf.dtypes.float32,
                                       name='commands_input')
circuits_input = tf.keras.Input(shape=(),
                                # The circuit-tensor has dtype `tf.string` 
                                dtype=tf.dtypes.string,
                                name='circuits_input')
operators_input = tf.keras.Input(shape=(1,),
                                 dtype=tf.dtypes.string,
                                 name='operators_input')

ここにコントローラ・ネットワークがあります :

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

回路とコントローラを tfq を使用して単一の keras.Model に結合します :

dense_2 = controller(commands_input)

# Since you aren't using a PQC or ControlledPQC you must append
# your model circuit onto the datapoint circuit tensor manually.
full_circuit = tfq.layers.AddCircuit()(circuits_input, append=model_circuit)
expectation_output = tfq.layers.Expectation()(full_circuit,
                                              symbol_names=control_params,
                                              symbol_values=dense_2,
                                              operators=operators_input)

# Contruct your Keras model.
two_axis_control_model = tf.keras.Model(
    inputs=[circuits_input, commands_input, operators_input],
    outputs=[expectation_output])

 

3.2 データセット

今は model_circuit のために供給する各データポイントのために測定することを望む演算子もまた含みます :

# The operators to measure, for each command.
operator_data = tfq.convert_to_tensor([[cirq.X(qubit)], [cirq.Z(qubit)]])

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

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

 

3.3 訓練

新しい入力と出力を持つ今、keras を使用して再度訓練できます。

optimizer = tf.keras.optimizers.Adam(learning_rate=0.05)
loss = tf.keras.losses.MeanSquaredError()

two_axis_control_model.compile(optimizer=optimizer, loss=loss)

history = two_axis_control_model.fit(
    x=[datapoint_circuits, commands, operator_data],
    y=expected_outputs,
    epochs=30,
    verbose=1)
Train on 2 samples
Epoch 1/30
2/2 [==============================] - 1s 326ms/sample - loss: 1.0935
Epoch 2/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.8408
Epoch 3/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.5724
Epoch 4/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.3353
Epoch 5/30
2/2 [==============================] - 0s 1ms/sample - loss: 0.1855
Epoch 6/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.1152
Epoch 7/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0859
Epoch 8/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0757
Epoch 9/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0658
Epoch 10/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0486
Epoch 11/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0306
Epoch 12/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0181
Epoch 13/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0124
Epoch 14/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0120
Epoch 15/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0155
Epoch 16/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0211
Epoch 17/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0259
Epoch 18/30
2/2 [==============================] - 0s 1ms/sample - loss: 0.0268
Epoch 19/30
2/2 [==============================] - 0s 1ms/sample - loss: 0.0235
Epoch 20/30
2/2 [==============================] - 0s 1ms/sample - loss: 0.0180
Epoch 21/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0126
Epoch 22/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0083
Epoch 23/30
2/2 [==============================] - 0s 2ms/sample - loss: 0.0051
Epoch 24/30
2/2 [==============================] - 0s 1ms/sample - loss: 0.0029
Epoch 25/30
2/2 [==============================] - 0s 1ms/sample - loss: 0.0015
Epoch 26/30
2/2 [==============================] - 0s 1ms/sample - loss: 8.1761e-04
Epoch 27/30
2/2 [==============================] - 0s 1ms/sample - loss: 4.8669e-04
Epoch 28/30
2/2 [==============================] - 0s 1ms/sample - loss: 3.7943e-04
Epoch 29/30
2/2 [==============================] - 0s 1ms/sample - loss: 3.9353e-04
Epoch 30/30
2/2 [==============================] - 0s 1ms/sample - loss: 4.7893e-04
plt.plot(history.history['loss'])
plt.title("Learning to Control a Qubit")
plt.xlabel("Iterations")
plt.ylabel("Error in Control")
plt.show()

損失関数はゼロに下がりました。

controller はスタンドアローン・モデルとして利用可能です。コントローラを呼び出し、各コマンド信号へのレスポンスを確認します。これらの出力を random_rotations の内容と正しく比較するには何某かの作業がかかるでしょう。

controller.predict(np.array([0,1]))
array([[-1.942868  , -0.2633527 ,  0.4679988 ],
       [-0.58572036,  0.0779818 , -1.1244173 ]], dtype=float32)
 

以上






AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com