0

我遵循了以下教程:https ://www.tensorflow.org/quantum/tutorials/mnist 。我已将本教程修改为我能想到的最简单的示例:一个输入集,其中 x 从 0 线性增加到 1 并且 y = x < 0.3。然后我使用 PQC 和带有符号的单个 Rx 门,以及使用 Z 门的读数。

当检索优化的符号并手动调整它时,我可以很容易地找到一个提供 100% 准确度的值,但是当我让 Adam 优化器运行时,它会收敛到始终预测 1 或始终预测 -1。有人发现我做错了吗?(我很抱歉无法将代码分解为更小的示例)

import tensorflow as tf
import tensorflow_quantum as tfq

import cirq
import sympy
import numpy as np

# used to embed classical data in quantum circuits
def convert_to_circuit_cont(image):
    """Encode truncated classical image into quantum datapoint."""
    values = np.ndarray.flatten(image)
    qubits = cirq.GridQubit.rect(4, 1)
    circuit = cirq.Circuit()
    for i, value in enumerate(values):
        if value:
            circuit.append(cirq.rx(value).on(qubits[i]))
    return circuit

# define classical dataset
length = 1000
np.random.seed(42)

# create a linearly increasing set for x from 0 to 1 in 1/length steps
x_train_sorted = np.asarray([[x/length] for x in range(0,length)], dtype=np.float32)
# p is used to shuffle x and y similarly
p = np.random.permutation(len(x_train_sorted))
x_train = x_train_sorted[p]
# y = x < 0.3 in {-1, 1} for Hinge loss
y_train_sorted = np.asarray([1 if (x/length)<0.30 else -1 for x in range(0,length)])
y_train = y_train_sorted[p]
# test == train for this example
x_test = x_train_sorted[:]
y_test = y_train_sorted[:]

# convert classical data into quantum circuits
x_train_circ = [convert_to_circuit_cont(x) for x in x_train]
x_test_circ = [convert_to_circuit_cont(x) for x in x_test]
x_train_tfcirc = tfq.convert_to_tensor(x_train_circ)
x_test_tfcirc = tfq.convert_to_tensor(x_test_circ)

# define the PQC circuit, consisting out of 1 qubit with 1 gate (Rx) and 1 parameter
def create_quantum_model():
    data_qubits = cirq.GridQubit.rect(1, 1)  
    circuit = cirq.Circuit()
    a = sympy.Symbol("a")
    circuit.append(cirq.rx(a).on(data_qubits[0])),
    return circuit, cirq.Z(data_qubits[0])
model_circuit, model_readout = create_quantum_model()

# Build the Keras model.
model = tf.keras.Sequential([
    # The input is the data-circuit, encoded as a tf.string
    tf.keras.layers.Input(shape=(), dtype=tf.string),
    # The PQC layer returns the expected value of the readout gate, range [-1,1].
    tfq.layers.PQC(model_circuit, model_readout),
])

# used for logging progress during optimization
def hinge_accuracy(y_true, y_pred):
    y_true = tf.squeeze(y_true) > 0.0
    y_pred = tf.squeeze(y_pred) > 0.0
    result = tf.cast(y_true == y_pred, tf.float32)
return tf.reduce_mean(result)

# compile the model with Hinge loss and Adam, as done in the example. Have tried with various learning_rates
model.compile(
    loss = tf.keras.losses.Hinge(),
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.1),
    metrics=[hinge_accuracy])

EPOCHS = 20
BATCH_SIZE = 32
NUM_EXAMPLES = 1000

# fit the model
qnn_history = model.fit(
      x_train_tfcirc, y_train, 
      batch_size=32,
      epochs=EPOCHS,
      verbose=1,
      validation_data=(x_test_tfcirc, y_test),
      use_multiprocessing=False)

results = model.predict(x_test_tfcirc)
results_mapped = [-1 if x<=0 else 1 for x in results[:,0]]
print(np.sum(np.equal(results_mapped, y_test)))

经过 20 次优化后,我得到以下结果:

1000/1000 [==============================] - 0s 410us/sample - loss: 0.5589 - hinge_accuracy: 0.6982 - val_loss: 0.5530 - val_hinge_accuracy: 0.7070

这导致正确预测的 1000 个样本中有 700 个样本。在查看映射结果时,这是因为所有结果都被预测为 -1。查看原始结果时,它们从 -0.5484014 线性增加到 -0.99996257。

当使用 w = model.layers[0].get_weights() 检索权重,减去 0.8 并使用 model.layers[0].set_weights(w) 再次设置时,我得到 920/1000 正确。微调这个过程可以让我达到 1000/1000。

更新 1:我还打印了各个时期的权重更新:

4.916246, 4.242602, 3.3765688, 2.6855211, 2.3405066, 2.206207, 2.1734586, 2.1656137, 2.1510274, 2.1634471, 2.1683235, 2.188944, 2.1510284, 2.1591303, 2.1632445, 2.1542525, 2.1677444, 2.1702878, 2.163104, 2.1635907

我将权重设置为 1.36,该值给出 908/1000(而不是 700/100)。优化器远离它:

1.7992111, 2.0727847, 2.1370323, 2.15711, 2.1686404, 2.1603785, 2.183334, 2.1563332, 2.156857, 2.169908, 2.1658351, 2.170673, 2.1575692, 2.1505954, 2.1561477, 2.1754034, 2.1545155, 2.1635509, 2.1464484, 2.1707492

我注意到的一件事是铰链精度的值为 0.75,重量为 1.36,高于 2.17 的 0.7。如果是这种情况,我要么处于优化环境的不幸部分,全局最小值不对应于损失环境的最小值,要么损失值被错误地确定。这是我接下来要研究的。

4

1 回答 1

0

此示例的铰链损失函数的最小值与正确分类示例数的最大值不对应。请参阅这些参数值的图表。鉴于优化器致力于损失的最小值,而不是分类示例数量的最大值,代码(和框架/优化器)会做他们应该做的事情。或者,可以使用不同的损失函数来尝试找到更好的拟合。例如二值化 l1 损失。该函数将具有相同的全局最优值,但可能具有非常平坦的景观。

权重损失值

于 2020-06-29T10:47:33.840 回答