Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/ko/quantum/tutorials/noise.ipynb
25118 views
Kernel: Python 3
#@title Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.

노이즈

현대의 양자 컴퓨터에는 노이즈가 존재합니다. 큐비트는 주변 환경의 간섭, 불완전한 제작, TLS뿐만 아니라 심지어 감마선에도 취약합니다. 오늘날의 알고리즘은 대규모 오류 수정을 진행하기 전까지 노이즈가 있는 상태에서도 기능을 유지할 수 있어야 합니다. 이러한 점은 노이즈가 있는 환경에서 현대의 양자 컴퓨터를 대상으로 양자 알고리즘/모델 검증하기 위한 알고리즘을 테스트하는 작업을 중요하게 만듭니다.

이 튜토리얼에서는 고수준의 tfq.layers API를 통해 TFQ에서 노이즈가 있는 회로 시뮬레이션의 기본 사항을 살펴봅니다.

설치하기

!pip install tensorflow==2.7.0 tensorflow-quantum==0.7.2
!pip install -q git+https://github.com/tensorflow/docs
# Update package resources to account for version changes. import importlib, pkg_resources importlib.reload(pkg_resources)
import random import cirq import sympy import tensorflow_quantum as tfq import tensorflow as tf import numpy as np # Plotting import matplotlib.pyplot as plt import tensorflow_docs as tfdocs import tensorflow_docs.plots

1. 양자 노이즈의 이해

1.1 기본 회로 노이즈

양자 컴퓨터의 노이즈는 측정할 수 있는 비트열 샘플에 영향을 줍니다. 이에 대해 생각할 수 있는 직관적인 방법 중 하나는 노이즈가 있는 양자 컴퓨터가 아래의 다이어그램과 같이 임의의 위치에서 게이트를 "삽입", "삭제" 또는 "교체"하는 것입니다.

이러한 직관을 바탕으로 노이즈를 처리할 때 더 이상 단일 순수 상태의 ψ|\psi \rangle를 사용하지 않고 대신 원하는 회로인 ρ=jpjψjψj\rho = \sum_j p_j |\psi_j \rangle \langle \psi_j |에서 가능한 모든 노이즈를 실현한 앙상블을 처리합니다. 여기서 pjp_j는 시스템이 ψj|\psi_j \rangle 있을 확률을 제공합니다.

시스템이 완벽하게 실행되는 시간의 90% 혹은 이 한 가지 모드의 실패로 오류가 발생한 시간의 10%를 사전에 알게 될 경우의 앙상블은 다음과 같을 수 있습니다.

ρ=0.9ψdesiredψdesired+0.1ψnoisyψnoisy\rho = 0.9 |\psi_\text{desired} \rangle \langle \psi_\text{desired}| + 0.1 |\psi_\text{noisy} \rangle \langle \psi_\text{noisy}|

우리의 회로가 오류를 일으킬 수 있는 방법이 한 가지 이상이었다면 앙상블 ρ\rho는 두 개 이상의 항을 포함할 것입니다(발생할 수 있는 노이즈가 있는 각 새로운 실현마다 하나씩). ρ\rho는 노이즈가 있는 시스템을 설명하는 밀도 행렬이라고 합니다.

1.2 채널을 사용한 회로 노이즈 모델링

안타깝게도 실제로 회로에서 오류가 발생할 수 있는 모든 방법과 정확한 확률을 아는 것은 거의 불가능합니다. 간단히 할 수 있는 가정은 회로에서 각 작업을 수행한 후에 해당 작업으로 발생할 수 있는 오류의 방식을 대략적으로 캡처하는 일종의 채널이 있다는 것입니다. 다음과 같이 약간의 노이즈가 있는 회로를 빠르게 생성할 수 있습니다.

def x_circuit(qubits): """Produces an X wall circuit on `qubits`.""" return cirq.Circuit(cirq.X.on_each(*qubits)) def make_noisy(circuit, p): """Add a depolarization channel to all qubits in `circuit` before measurement.""" return circuit + cirq.Circuit(cirq.depolarize(p).on_each(*circuit.all_qubits())) my_qubits = cirq.GridQubit.rect(1, 2) my_circuit = x_circuit(my_qubits) my_noisy_circuit = make_noisy(my_circuit, 0.5) my_circuit
my_noisy_circuit

다음을 사용하여 노이즈가 없는 밀도 행렬 ρ\rho를 검사할 수 있습니다.

rho = cirq.final_density_matrix(my_circuit) np.round(rho, 3)

그리고 노이즈가 있는 밀도 행렬 matrix ρ\rho에는 다음을 사용합니다.

rho = cirq.final_density_matrix(my_noisy_circuit) np.round(rho, 3)

두 개의 서로 다른 ρ \rho 를 비교하면 노이즈가 상태의 진폭에 영향을 미쳤음을 알 수 있습니다(결과적으로 샘플링 확률). 노이즈가 없는 경우 항상 11 |11\rangle 상태를 샘플링할 것으로 예상됩니다. 그러나 노이즈가 있는 상태에서는 00 |00\rangle 또는 01 |01\rangle 또는 10 |10\rangle 도 샘플링할 확률이 0이 아닙니다.

"""Sample from my_noisy_circuit.""" def plot_samples(circuit): samples = cirq.sample(circuit + cirq.measure(*circuit.all_qubits(), key='bits'), repetitions=1000) freqs, _ = np.histogram(samples.data['bits'], bins=[i+0.01 for i in range(-1,2** len(my_qubits))]) plt.figure(figsize=(10,5)) plt.title('Noisy Circuit Sampling') plt.xlabel('Bitstring') plt.ylabel('Frequency') plt.bar([i for i in range(2** len(my_qubits))], freqs, tick_label=['00','01','10','11']) plot_samples(my_noisy_circuit)

소음이 없는 경우에는 다음과 같이 항상 11|11\rangle을 얻을 수 있습니다.

"""Sample from my_circuit.""" plot_samples(my_circuit)

노이즈를 조금 더 높이면 노이즈와 원하는 동작(샘플링 11|11\rangle)을 구분하기가 점점 더 어려워집니다.

my_really_noisy_circuit = make_noisy(my_circuit, 0.75) plot_samples(my_really_noisy_circuit)

참고: 회로에서 여러 채널을 실험하여 노이즈를 생성해 보세요. Cirq와 TFQ에서 지원되는 공용 채널은 여기에서 확인할 수 있습니다.

2. TFQ의 기본 노이즈

노이즈가 회로 실행에 영향을 미치는 방식에 대한 이해를 통해 TFQ에서 노이즈가 작동하는 방식을 탐색할 수 있습니다. TensorFlow Quantum은 밀도 행렬 시뮬레이션에 대한 대안으로 몬테카를로/궤적 기반 시뮬레이션을 사용합니다. 이는 밀도 행렬 시뮬레이션의 메모리 복잡성으로 인해 기존의 전체 밀도 행렬 시뮬레이션 방법이 대규모 시뮬레이션을 <= 20 큐비트로 제한하기 때문입니다. 몬테카를로/궤적 시뮬레이션은 이 비용을 시간에 따른 추가 비용과 교환합니다. backend='noisy' 옵션은 모든 tfq.layers.Sample, tfq.layers.SampledExpectationtfq.layers.Expectation에 사용할 수 있습니다(Expectation의 경우 필수 repetitions 매개변수를 추가함).

2.1 TFQ의 노이즈가 있는 샘플링

TFQ 및 궤적 시뮬레이션을 사용하여 위의 플롯을 다시 생성하기 위해 tfq.layers.Sample을 사용할 수 있습니다.

"""Draw bitstring samples from `my_noisy_circuit`""" bitstrings = tfq.layers.Sample(backend='noisy')(my_noisy_circuit, repetitions=1000)
numeric_values = np.einsum('ijk,k->ij', bitstrings.to_tensor().numpy(), [1, 2])[0] freqs, _ = np.histogram(numeric_values, bins=[i+0.01 for i in range(-1,2** len(my_qubits))]) plt.figure(figsize=(10,5)) plt.title('Noisy Circuit Sampling') plt.xlabel('Bitstring') plt.ylabel('Frequency') plt.bar([i for i in range(2** len(my_qubits))], freqs, tick_label=['00','01','10','11'])

2.2 노이즈가 있는 샘플 기반 예상

노이즈가 있는 샘플을 기반으로 예상 계산을 수행하기 위해 tfq.layers.SampleExpectation을 사용할 수 있습니다.

some_observables = [cirq.X(my_qubits[0]), cirq.Z(my_qubits[0]), 3.0 * cirq.Y(my_qubits[1]) + 1] some_observables

샘플링을 통해 회로로부터 노이즈가 없는 예상 추정값을 계산합니다.

noiseless_sampled_expectation = tfq.layers.SampledExpectation(backend='noiseless')( my_circuit, operators=some_observables, repetitions=10000 ) noiseless_sampled_expectation.numpy()

이러한 값들을 다음과 같이 노이즈가 있는 버전과 비교합니다.

noisy_sampled_expectation = tfq.layers.SampledExpectation(backend='noisy')( [my_noisy_circuit, my_really_noisy_circuit], operators=some_observables, repetitions=10000 ) noisy_sampled_expectation.numpy()

노이즈가 있는 버전이 특히 ψZψ\langle \psi | Z | \psi \rangle의 정확도에 영향을 미쳤음을 확인할 수 있으며 이때 my_really_noisy_circuit은 0에 매우 빠르게 집중합니다.

2.3 노이즈 분석 예상 계산

노이즈가 있는 예상 계산을 수행하는 방법은 위의 설명과 거의 동일합니다.

noiseless_analytic_expectation = tfq.layers.Expectation(backend='noiseless')( my_circuit, operators=some_observables ) noiseless_analytic_expectation.numpy()
noisy_analytic_expectation = tfq.layers.Expectation(backend='noisy')( [my_noisy_circuit, my_really_noisy_circuit], operators=some_observables, repetitions=10000 ) noisy_analytic_expectation.numpy()

3. 하이브리드 모델과 양자 데이터 노이즈

이제 TFQ에서 노이즈가 있는 회로 시뮬레이션을 구현했으므로 노이즈가 있는 성능과 노이즈가 없는 성능을 비교하고 대조하여 노이즈가 양자 및 하이브리드 양자 클래식 모델에 미치는 영향을 실험할 수 있습니다. 모델이나 알고리즘이 노이즈에 강한지 확인하는 데 좋은 첫 번째 방법은 다음과 같은 회로 전체에 걸쳐 감극 모델에서 테스트하는 것입니다.

회로의 각 타임 슬라이스(모멘트라고도 함)에는 해당 타임 슬라이스에서 각 게이트 작업 후에 추가된 감극 채널이 있습니다. 감극 채널은 X,Y,Z{X, Y, Z } 중 하나를 확률 pp로 적용하거나 1p1-p 확률로 아무 것도 적용하지 않는(원래 작업 유지) 채널입니다.

3.1 데이터

이 예시에서는 tfq.datasets 모듈로 준비한 일부 회로를 학습 데이터로 사용할 수 있습니다.

qubits = cirq.GridQubit.rect(1, 8) circuits, labels, pauli_sums, _ = tfq.datasets.xxz_chain(qubits, 'closed') circuits[0]

약간의 도우미 함수를 작성하면 다음과 같이 노이즈가 있는 사례 대 노이즈가 없는 사례에 대한 데이터를 생성하는 데 도움이 됩니다.

def get_data(qubits, depolarize_p=0.): """Return quantum data circuits and labels in `tf.Tensor` form.""" circuits, labels, pauli_sums, _ = tfq.datasets.xxz_chain(qubits, 'closed') if depolarize_p >= 1e-5: circuits = [circuit.with_noise(cirq.depolarize(depolarize_p)) for circuit in circuits] tmp = list(zip(circuits, labels)) random.shuffle(tmp) circuits_tensor = tfq.convert_to_tensor([x[0] for x in tmp]) labels_tensor = tf.convert_to_tensor([x[1] for x in tmp]) return circuits_tensor, labels_tensor

3.2 모델 회로 정의하기

이제 회로 형태의 양자 데이터가 있으므로 이 데이터를 모델링하는 회로가 필요합니다. 데이터와 마찬가지로 선택적으로 노이즈를 포함하는 이 회로를 생성하는 도우미 함수를 작성할 수 있습니다.

def modelling_circuit(qubits, depth, depolarize_p=0.): """A simple classifier circuit.""" dim = len(qubits) ret = cirq.Circuit(cirq.H.on_each(*qubits)) for i in range(depth): # Entangle layer. ret += cirq.Circuit(cirq.CX(q1, q2) for (q1, q2) in zip(qubits[::2], qubits[1::2])) ret += cirq.Circuit(cirq.CX(q1, q2) for (q1, q2) in zip(qubits[1::2], qubits[2::2])) # Learnable rotation layer. # i_params = sympy.symbols(f'layer-{i}-0:{dim}') param = sympy.Symbol(f'layer-{i}') single_qb = cirq.X if i % 2 == 1: single_qb = cirq.Y ret += cirq.Circuit(single_qb(q) ** param for q in qubits) if depolarize_p >= 1e-5: ret = ret.with_noise(cirq.depolarize(depolarize_p)) return ret, [op(q) for q in qubits for op in [cirq.X, cirq.Y, cirq.Z]] modelling_circuit(qubits, 3)[0]

3.3 모델 구축 및 훈련

데이터 및 모델 회로가 구축되면 다음과 같이 노이즈가 있거나 노이즈가 없는 하이브리드 양자 tf.keras.Model을 모두 조합할 수 있는 최종 도우미 함수가 필요합니다.

def build_keras_model(qubits, depolarize_p=0.): """Prepare a noisy hybrid quantum classical Keras model.""" spin_input = tf.keras.Input(shape=(), dtype=tf.dtypes.string) circuit_and_readout = modelling_circuit(qubits, 4, depolarize_p) if depolarize_p >= 1e-5: quantum_model = tfq.layers.NoisyPQC(*circuit_and_readout, sample_based=False, repetitions=10)(spin_input) else: quantum_model = tfq.layers.PQC(*circuit_and_readout)(spin_input) intermediate = tf.keras.layers.Dense(4, activation='sigmoid')(quantum_model) post_process = tf.keras.layers.Dense(1)(intermediate) return tf.keras.Model(inputs=[spin_input], outputs=[post_process])

4. 성능 비교하기

4.1 노이즈가 없는 기준선

이제 데이터 생성 및 모델 구축 코드를 사용하여 노이즈가 없는 설정과 노이즈가 있는 설정으로 모델 성능을 비교하고 대조할 수 있습니다. 먼저 다음과 같이 노이즈가 없는 훈련을 참조로 실행할 수 있습니다.

training_histories = dict() depolarize_p = 0. n_epochs = 50 phase_classifier = build_keras_model(qubits, depolarize_p) phase_classifier.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.02), loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), metrics=['accuracy']) # Show the keras plot of the model tf.keras.utils.plot_model(phase_classifier, show_shapes=True, dpi=70)
noiseless_data, noiseless_labels = get_data(qubits, depolarize_p) training_histories['noiseless'] = phase_classifier.fit(x=noiseless_data, y=noiseless_labels, batch_size=16, epochs=n_epochs, validation_split=0.15, verbose=1)

그리고 다음과 같이 결과와 정확성을 살펴 봅니다.

loss_plotter = tfdocs.plots.HistoryPlotter(metric = 'loss', smoothing_std=10) loss_plotter.plot(training_histories)
acc_plotter = tfdocs.plots.HistoryPlotter(metric = 'accuracy', smoothing_std=10) acc_plotter.plot(training_histories)

4.2 노이즈가 있는 설정 비교

노이즈가 있는 구조로 새 모델을 빌드하고 위의 내용과 비교하면 코드가 거의 동일한 것을 확인할 수 있습니다.

depolarize_p = 0.001 n_epochs = 50 noisy_phase_classifier = build_keras_model(qubits, depolarize_p) noisy_phase_classifier.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.02), loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), metrics=['accuracy']) # Show the keras plot of the model tf.keras.utils.plot_model(noisy_phase_classifier, show_shapes=True, dpi=70)

참고: 모델 다이어그램에는 이제 tfq.layers.PQC 대신 tfq.layers.NoisyPQC가 있습니다. 이는 감극 확률이 더 이상 0이 아니기 때문입니다. 노이즈가 있는 시뮬레이션은 노이즈가 없는 시뮬레이션보다 훨씬 더 비싸기 때문에 훈련 시간이 훨씬 더 오래 걸립니다.

noisy_data, noisy_labels = get_data(qubits, depolarize_p) training_histories['noisy'] = noisy_phase_classifier.fit(x=noisy_data, y=noisy_labels, batch_size=16, epochs=n_epochs, validation_split=0.15, verbose=1)
loss_plotter.plot(training_histories)
acc_plotter.plot(training_histories)

성공: 노이즈가 있는 모델은 약간의 감극 노이즈가 있는 환경에서 여전히 훈련할 수 있었습니다. 훈련이 실패할 수 있는 방법과 시기를 확인하려면 다양한 노이즈 모델을 실험해야 합니다. 또한 tfq.layerstfq.noise의 경우에는 노이즈 있는 기능을 조심해야 합니다.