이 페이지는 Cloud Translation API를 통해 번역되었습니다.
Switch to English

연구 도구

TensorFlow.org에서보기 Google Colab에서 실행 GitHub에서 소스보기 노트북 다운로드

TensorFlow Quantum은 양자 프리미티브를 TensorFlow 생태계로 가져옵니다. 이제 양자 연구원은 TensorFlow의 도구를 활용할 수 있습니다. 이 튜토리얼에서는 TensorBoard 를 양자 컴퓨팅 연구에 통합하는 방법을 자세히 살펴 봅니다. TensorFlow의 DCGAN 자습서 를 사용하면 Niu 등이 수행 한 것과 유사한 작업 실험 및 시각화를 빠르게 구축 할 수 있습니다 . . 광범위하게 말하면 다음을 수행합니다.

  1. GAN을 훈련시켜 양자 회로에서 나온 것처럼 보이는 샘플을 생성합니다.
  2. 훈련 진행 상황과 시간에 따른 분포 진화를 시각화합니다.
  3. 컴퓨팅 그래프를 탐색하여 실험을 벤치마킹합니다.
pip install -q tensorflow==2.3.1 tensorflow-quantum tensorboard_plugin_profile==2.3.0
%load_ext tensorboard
import datetime
import time
import cirq
import tensorflow as tf
import tensorflow_quantum as tfq
from tensorflow.keras import layers

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

1. 데이터 생성

데이터 수집부터 시작하십시오. TensorFlow Quantum을 사용하여 나머지 실험의 기본 데이터 소스가 될 비트 문자열 샘플을 빠르게 생성 할 수 있습니다. Niu et al. 깊이가 대폭 감소 된 임의 회로에서 샘플링을 에뮬레이션하는 것이 얼마나 쉬운 지 살펴볼 것입니다. 먼저 몇 가지 도우미를 정의합니다.

def generate_circuit(qubits):
    """Generate a random circuit on qubits."""
    random_circuit = cirq.generate_boixo_2018_supremacy_circuits_v2(
        qubits, cz_depth=2, seed=1234)
    return random_circuit

def generate_data(circuit, n_samples):
    """Draw n_samples samples from circuit into a tf.Tensor."""
    return tf.squeeze(tfq.layers.Sample()(circuit, repetitions=n_samples).to_tensor())

이제 회로와 샘플 데이터를 검사 할 수 있습니다.

qubits = cirq.GridQubit.rect(1, 5)
random_circuit_m = generate_circuit(qubits) + cirq.measure_each(*qubits)
SVGCircuit(random_circuit_m)
findfont: Font family ['Arial'] not found. Falling back to DejaVu Sans.

svg

samples = cirq.sample(random_circuit_m, repetitions=10)
print('10 Random bitstrings from this circuit:')
print(samples)
10 Random bitstrings from this circuit:
(0, 0)=1010101001
(0, 1)=1111110010
(0, 2)=0000000111
(0, 3)=0000000000
(0, 4)=1000000000

TensorFlow Quantum에서 다음을 사용하여 동일한 작업을 수행 할 수 있습니다.

generate_data(random_circuit_m, 10)
<tf.Tensor: shape=(10, 5), dtype=int8, numpy=
array([[0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0],
       [0, 1, 1, 0, 0],
       [0, 1, 1, 0, 0],
       [0, 1, 1, 0, 0],
       [1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [1, 0, 0, 0, 0],
       [1, 0, 1, 0, 0],
       [1, 0, 1, 0, 0]], dtype=int8)>

이제 다음을 사용하여 학습 데이터를 빠르게 생성 할 수 있습니다.

N_SAMPLES = 60000
N_QUBITS = 10
QUBITS = cirq.GridQubit.rect(1, N_QUBITS)
REFERENCE_CIRCUIT = generate_circuit(QUBITS)
all_data = generate_data(REFERENCE_CIRCUIT, N_SAMPLES)
all_data
<tf.Tensor: shape=(60000, 10), dtype=int8, numpy=
array([[0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       [0, 0, 0, ..., 0, 0, 0],
       ...,
       [1, 1, 1, ..., 1, 1, 1],
       [1, 1, 1, ..., 1, 1, 1],
       [1, 1, 1, ..., 1, 1, 1]], dtype=int8)>

훈련이 진행될 때 시각화 할 몇 가지 도우미 함수를 정의하는 것이 유용 할 것입니다. 사용할 두 가지 흥미로운 수량은 다음과 같습니다.

  1. 분포의 히스토그램을 생성 할 수 있도록 표본의 정수 값입니다.
  2. 샘플 세트의 선형 XEB 충실도 추정치로 샘플이 얼마나 "진정한 양자 랜덤"인지를 나타냅니다.
@tf.function
def bits_to_ints(bits):
    """Convert tensor of bitstrings to tensor of ints."""
    sigs = tf.constant([1 << i for i in range(N_QUBITS)], dtype=tf.int32)
    rounded_bits = tf.clip_by_value(tf.math.round(
        tf.cast(bits, dtype=tf.dtypes.float32)), clip_value_min=0, clip_value_max=1)
    return tf.einsum('jk,k->j', tf.cast(rounded_bits, dtype=tf.dtypes.int32), sigs)

@tf.function
def xeb_fid(bits):
    """Compute linear XEB fidelity of bitstrings."""
    final_probs = tf.squeeze(
        tf.abs(tfq.layers.State()(REFERENCE_CIRCUIT).to_tensor()) ** 2)
    nums = bits_to_ints(bits)
    return (2 ** N_QUBITS) * tf.reduce_mean(tf.gather(final_probs, nums)) - 1.0

여기서 XEB를 사용하여 배포 및 온 전성 검사를 시각화 할 수 있습니다.

plt.hist(bits_to_ints(all_data).numpy(), 50)
plt.show()

png

xeb_fid(all_data)
<tf.Tensor: shape=(), dtype=float32, numpy=-0.001962483>

2. 모델 구축

여기에서 양자 사례에 대한 DCGAN 자습서 의 관련 구성 요소를 사용할 수 있습니다. MNIST 숫자를 생성하는 대신 새 GAN을 사용하여 길이가 N_QUBITS 비트 N_QUBITS 샘플을 생성합니다.

LATENT_DIM = 100
def make_generator_model():
    """Construct generator model."""
    model = tf.keras.Sequential()
    model.add(layers.Dense(256, use_bias=False, input_shape=(LATENT_DIM,)))
    model.add(layers.Dense(128, activation='relu'))
    model.add(layers.Dropout(0.3))
    model.add(layers.Dense(64, activation='relu'))
    model.add(layers.Dense(N_QUBITS, activation='relu'))

    return model

def make_discriminator_model():
    """Constrcut discriminator model."""
    model = tf.keras.Sequential()
    model.add(layers.Dense(256, use_bias=False, input_shape=(N_QUBITS,)))
    model.add(layers.Dense(128, activation='relu'))
    model.add(layers.Dropout(0.3))
    model.add(layers.Dense(32, activation='relu'))
    model.add(layers.Dense(1))

    return model

다음으로 생성기 및 판별 기 모델을 인스턴스화하고 손실을 정의하고 기본 학습 루프에 사용할 train_step 함수를 만듭니다.

discriminator = make_discriminator_model()
generator = make_generator_model()
cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)
def discriminator_loss(real_output, fake_output):
    """Compute discriminator loss."""
    real_loss = cross_entropy(tf.ones_like(real_output), real_output)
    fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)
    total_loss = real_loss + fake_loss
    return total_loss

def generator_loss(fake_output):
    """Compute generator loss."""
    return cross_entropy(tf.ones_like(fake_output), fake_output)

generator_optimizer = tf.keras.optimizers.Adam(1e-4)
discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)
BATCH_SIZE=256

@tf.function
def train_step(images):
    """Run train step on provided image batch."""
    noise = tf.random.normal([BATCH_SIZE, LATENT_DIM])
    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
        generated_images = generator(noise, training=True)

        real_output = discriminator(images, training=True)
        fake_output = discriminator(generated_images, training=True)

        gen_loss = generator_loss(fake_output)
        disc_loss = discriminator_loss(real_output, fake_output)

    gradients_of_generator = gen_tape.gradient(
        gen_loss, generator.trainable_variables)
    gradients_of_discriminator = disc_tape.gradient(
        disc_loss, discriminator.trainable_variables)

    generator_optimizer.apply_gradients(
        zip(gradients_of_generator, generator.trainable_variables))
    discriminator_optimizer.apply_gradients(
        zip(gradients_of_discriminator, discriminator.trainable_variables))

    return gen_loss, disc_loss

이제 모델에 필요한 모든 빌딩 블록이 준비되었으므로 TensorBoard 시각화를 통합하는 학습 기능을 설정할 수 있습니다. 먼저 TensorBoard 파일 작성기를 설정합니다.

logdir = "tb_logs/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
file_writer = tf.summary.create_file_writer(logdir + "/metrics")
file_writer.set_as_default()

tf.summary 모듈을 사용하여 이제 기본 train 함수 내부에 scalar , histogram (및 기타) 로깅을 TensorBoard에 통합 할 수 있습니다.

def train(dataset, epochs, start_epoch=1):
    """Launch full training run for the given number of epochs."""
    # Log original training distribution.
    tf.summary.histogram('Training Distribution', data=bits_to_ints(dataset), step=0)

    batched_data = tf.data.Dataset.from_tensor_slices(dataset).shuffle(N_SAMPLES).batch(512)
    t = time.time()
    for epoch in range(start_epoch, start_epoch + epochs):
        for i, image_batch in enumerate(batched_data):
            # Log batch-wise loss.
            gl, dl = train_step(image_batch)
            tf.summary.scalar(
                'Generator loss', data=gl, step=epoch * len(batched_data) + i)
            tf.summary.scalar(
                'Discriminator loss', data=dl, step=epoch * len(batched_data) + i)

        # Log full dataset XEB Fidelity and generated distribution.
        generated_samples = generator(tf.random.normal([N_SAMPLES, 100]))
        tf.summary.scalar(
        'Generator XEB Fidelity Estimate', data=xeb_fid(generated_samples), step=epoch)
        tf.summary.histogram(
        'Generator distribution', data=bits_to_ints(generated_samples), step=epoch)
        # Log new samples drawn from this particular random circuit.
        random_new_distribution = generate_data(REFERENCE_CIRCUIT, N_SAMPLES)
        tf.summary.histogram(
        'New round of True samples', data=bits_to_ints(random_new_distribution), step=epoch)

    if epoch % 10 == 0:
        print('Epoch {}, took {}(s)'.format(epoch, time.time() - t))
        t = time.time()

3. 교육 및 성과 시각화

이제 TensorBoard 대시 보드를 다음과 같이 시작할 수 있습니다.

%tensorboard --logdir tb_logs/

train 호출하면 TensoBoard 대시 보드가 교육 루프에 제공된 모든 요약 통계로 자동 업데이트됩니다.

train(all_data, epochs=50)
Epoch 50, took 31.1910080909729(s)

훈련이 실행되는 동안 (그리고 완료되면) 스칼라 수량을 조사 할 수 있습니다.

히스토그램 탭으로 전환하면 생성기 네트워크가 양자 분포에서 샘플을 재생성 할 때 얼마나 잘하는지 확인할 수 있습니다.

실험과 관련된 요약 통계의 실시간 모니터링을 허용하는 것 외에도 TensorBoard는 실험을 프로파일 링하여 성능 병목 현상을 식별하는 데 도움을 줄 수 있습니다. 성능 모니터링으로 모델을 다시 실행하려면 다음을 수행 할 수 있습니다.

tf.profiler.experimental.start(logdir)
train(all_data, epochs=10, start_epoch=50)
tf.profiler.experimental.stop()

TensorBoard는 tf.profiler.experimental.starttf.profiler.experimental.stop 사이의 모든 코드를 프로파일 링합니다. 이 프로필 데이터는 TensorBoard의 profile 페이지에서 볼 수 있습니다.

깊이를 높이거나 다양한 종류의 양자 회로를 실험 해보십시오. TensorFlow Quantum 실험에 통합 할 수있는 하이퍼 파라미터 튜닝 과 같은 TensorBoard 의 다른 모든 훌륭한 기능을 확인하십시오.