import sys
import os
import pennylane as qml
from pennylane import numpy as np
import tensorflow as tf  # 确保 TensorFlow 在设置 floatx 后导入
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from tensorflow.python.keras.layers import Dense
from example_utils import get_parser
from importance_sampling.training import ConstantTimeImportanceTraining
from pennylane.qnn.keras import KerasLayer

# 设置 TensorFlow 的默认浮点类型为 float64
tf.keras.backend.set_floatx('float64')

# 重定向stdout以捕获打印输出
class Tee(object):
    def __init__(self, *files):
        self.files = files
    def write(self, obj):
        for f in self.files:
            f.write(obj)
            f.flush()
    def flush(self):
        for f in self.files:
            f.flush()

output_file = open('output.log', 'w', encoding='utf-8')
original_stdout = sys.stdout
sys.stdout = Tee(sys.stdout, output_file)

def save_plot(fig, filename):
    fig.savefig(filename)
    plt.close(fig)

def plot_history(history):
    # 绘制训练和验证准确率
    fig, ax = plt.subplots(figsize=(10, 5))
    ax.plot(history.history['accuracy'])
    ax.plot(history.history['val_accuracy'])
    ax.set_title('Model Accuracy')
    ax.set_ylabel('Accuracy')
    ax.set_xlabel('Epoch')
    ax.legend(['Train', 'Validation'], loc='upper left')
    save_plot(fig, 'accuracy_plot.png')

    # 绘制训练和验证损失
    fig, ax = plt.subplots(figsize=(10, 5))
    ax.plot(history.history['loss'])
    ax.plot(history.history['val_loss'])
    ax.set_title('Model Loss')
    ax.set_ylabel('Loss')
    ax.set_xlabel('Epoch')
    ax.legend(['Train', 'Validation'], loc='upper left')
    save_plot(fig, 'loss_plot.png')

def calculate_accuracy_fluctuation(history):
    val_accuracies = history.history['val_accuracy']
    mean_accuracy = np.mean(val_accuracies)
    fluctuation = np.sum(np.abs(val_accuracies - mean_accuracy))
    return mean_accuracy, fluctuation

# 定义设备，使用11个量子比特
dev = qml.device("default.qubit", wires=11, shots=None)

def encode_group(control_qubits, data_qubits, angles_q2, angles_q3):
    """
    模块化方法，用于对一组量子比特进行角度编码。

    参数：
    - control_qubits (list[int]): 控制比特的索引，例如 [0, 1]。
    - data_qubits (dict): 包含 'q2' 和 'q3' 的量子比特索引，例如 {'q2': 2, 'q3': 3}。
    - angles_q2 (list[float]): q2 在不同控制状态下的 Ry 旋转角度。
    - angles_q3 (list[float]): q3 在不同控制状态下的 Ry 旋转角度。
    """
    control_values = [[0, 0], [0, 1], [1, 0], [1, 1]]

    for cv, angle_q2, angle_q3 in zip(control_values, angles_q2, angles_q3):
        # 使用 control_values 直接控制 RY 旋转
        qml.ctrl(qml.RY, control=control_qubits, control_values=cv)(angle_q2, wires=data_qubits['q2'])
        qml.ctrl(qml.RY, control=control_qubits, control_values=cv)(angle_q3, wires=data_qubits['q3'])

def apply_controlled_swap(swap_qubit, q_swap1, q_swap2):
    """
    模块化方法，用于应用受控 SWAP 门。

    参数：
    - swap_qubit (int): 作为交换门控制比特的量子比特索引。
    - q_swap1 (int): 受交换操作影响的第一个量子比特索引。
    - q_swap2 (int): 受交换操作影响的第二个量子比特索引。
    """
    # 对 swap_qubit 应用 Hadamard 门
    qml.Hadamard(wires=swap_qubit)

    # 应用受控 SWAP 门
    qml.CSWAP(wires=[swap_qubit, q_swap1, q_swap2])

    # 再次对 swap_qubit 应用 Hadamard 门以恢复控制比特
    qml.Hadamard(wires=swap_qubit)

# 定义一个量子节点 (QNode) 用于训练
@qml.qnode(dev, interface='tf', diff_method='backprop')
def quantum_neural_network(inputs, weights):
    """
    量子神经网络的 QNode，实现多组数据的编码和交换操作。

    参数：
    - inputs (array[float]): 输入特征向量。
    - weights (array[float]): 量子电路的参数权重。

    返回：
    - tensor: 每组交换控制比特的 Pauli-Z 期望值。
    """
    # 使用输入数据对量子态进行编码
    # 假设前4个量子比特对应于4个输入特征
    for i in range(len(inputs)):
        qml.RY(inputs[i], wires=i)

    # 控制比特为 q0 和 q1
    control_qubits = [0, 1]

    # 定义各组的量子比特索引和旋转角度
    encoding_data = [
        {
            'data_qubits': {'q2': 2, 'q3': 3},
            'swap_qubit': 4,
            'angles_q2': weights[0, 2, :],  # 使用权重调整角度
            'angles_q3': weights[0, 3, :]
        },
        {
            'data_qubits': {'q2': 5, 'q3': 6},
            'swap_qubit': 7,
            'angles_q2': weights[0, 5, :],
            'angles_q3': weights[0, 6, :]
        },
        {
            'data_qubits': {'q2': 8, 'q3': 9},
            'swap_qubit': 10,
            'angles_q2': weights[0, 8, :],
            'angles_q3': weights[0, 9, :]
        }
    ]

    # 对每组数据进行编码
    for data_set in encoding_data:
        data_qubits = data_set['data_qubits']
        angles_q2 = data_set['angles_q2']
        angles_q3 = data_set['angles_q3']
        encode_group(control_qubits, data_qubits, angles_q2, angles_q3)

    # 对每组数据应用交换操作
    for data_set in encoding_data:
        swap_qubit = data_set['swap_qubit']
        data_qubits = data_set['data_qubits']
        apply_controlled_swap(swap_qubit, data_qubits['q3'], data_qubits['q2'])

    # 保留 Rot 层以增加量子电路的表达能力
    for layer in range(weights.shape[0]):
        for qubit in range(weights.shape[1]):
            qml.Rot(weights[layer, qubit, 0],
                    weights[layer, qubit, 1],
                    weights[layer, qubit, 2],
                    wires=qubit)
        # 可选：添加纠缠门，如全连通的 CNOT
        for qubit in range(weights.shape[1] - 1):
            qml.CNOT(wires=[qubit, qubit + 1])

    # 测量每个交换控制比特的 Pauli-Z 期望值
    results = [qml.expval(qml.PauliZ(data_set['swap_qubit'])) for data_set in encoding_data]

    # 返回测量结果的元组
    return tuple(results)

# 定义一个辅助的 QNode 用于绘制量子电路
@qml.qnode(dev, interface='autograd', diff_method='backprop')
def quantum_neural_network_draw(inputs, weights):
    """
    辅助 QNode，仅用于绘制量子电路图。

    参数：
    - inputs (array[float]): 输入特征向量。
    - weights (array[float]): 量子电路的参数权重。

    返回：
    - tuple: 每组交换控制比特的 Pauli-Z 期望值。
    """
    # 使用输入数据对量子态进行编码
    # 假设前4个量子比特对应于4个输入特征
    for i in range(len(inputs)):
        qml.RY(inputs[i], wires=i)

    # 控制比特为 q0 和 q1
    control_qubits = [0, 1]

    # 定义各组的量子比特索引和旋转角度
    encoding_data = [
        {
            'data_qubits': {'q2': 2, 'q3': 3},
            'swap_qubit': 4,
            'angles_q2': weights[0, 2, :],
            'angles_q3': weights[0, 3, :]
        },
        {
            'data_qubits': {'q2': 5, 'q3': 6},
            'swap_qubit': 7,
            'angles_q2': weights[0, 5, :],
            'angles_q3': weights[0, 6, :]
        },
        {
            'data_qubits': {'q2': 8, 'q3': 9},
            'swap_qubit': 10,
            'angles_q2': weights[0, 8, :],
            'angles_q3': weights[0, 9, :]
        }
    ]

    # 对每组数据进行编码
    for data_set in encoding_data:
        data_qubits = data_set['data_qubits']
        angles_q2 = data_set['angles_q2']
        angles_q3 = data_set['angles_q3']
        encode_group(control_qubits, data_qubits, angles_q2, angles_q3)

    # 对每组数据应用交换操作
    for data_set in encoding_data:
        swap_qubit = data_set['swap_qubit']
        data_qubits = data_set['data_qubits']
        apply_controlled_swap(swap_qubit, data_qubits['q3'], data_qubits['q2'])

    # 保留 Rot 层以增加量子电路的表达能力
    for layer in range(weights.shape[0]):
        for qubit in range(weights.shape[1]):
            qml.Rot(weights[layer, qubit, 0],
                    weights[layer, qubit, 1],
                    weights[layer, qubit, 2],
                    wires=qubit)
        # 可选：添加纠缠门，如全连通的 CNOT
        for qubit in range(weights.shape[1] - 1):
            qml.CNOT(wires=[qubit, qubit + 1])

    # 测量每个交换控制比特的 Pauli-Z 期望值
    results = [qml.expval(qml.PauliZ(data_set['swap_qubit'])) for data_set in encoding_data]

    # 返回测量结果的元组
    return tuple(results)

# 定义一个量子神经网络层
class QuantumNeuralNetworkLayer(tf.keras.layers.Layer):
    def __init__(self, n_qubits, n_layers, num_classes, **kwargs):
        super(QuantumNeuralNetworkLayer, self).__init__(**kwargs)
        self.n_qubits = n_qubits
        self.n_layers = n_layers
        self.num_classes = num_classes

        # Initialize weights
        weights_shape = (n_layers, n_qubits, 3)
        self.weights_qnn = self.add_weight(
            shape=weights_shape,
            initializer=tf.keras.initializers.GlorotUniform(),
            trainable=True,
            name='weights_qnn'
        )

    def call(self, inputs):
        # 使用 tf.map_fn 将 QNode 应用于每个样本
        q_output = tf.map_fn(
            lambda x: quantum_neural_network(x, self.weights_qnn),
            inputs,
            dtype=tf.float64  # 使用 float64 以匹配 PennyLane 的输出
        )
        return q_output

# 定义一个量子神经网络模型
class QuantumNeuralNetwork(tf.keras.Model):
    def __init__(self, n_qubits, n_layers, num_classes, **kwargs):
        super(QuantumNeuralNetwork, self).__init__(**kwargs)
        self.n_qubits = n_qubits
        self.n_layers = n_layers
        self.num_classes = num_classes

        # Quantum layer
        self.quantum_layer = QuantumNeuralNetworkLayer(n_qubits, n_layers, num_classes)

        # Classical layers
        self.dense_1 = Dense(64, activation='relu')  # 添加第一个经典 Dense 层
        self.batch_norm = tf.keras.layers.BatchNormalization()
        self.dropout = tf.keras.layers.Dropout(0.5)
        self.dense_2 = Dense(num_classes, activation='softmax')  # 输出层

    def call(self, inputs, training=False):
        q_output = self.quantum_layer(inputs)
        x = self.dense_1(q_output)
        x = self.batch_norm(x, training=training)
        x = self.dropout(x, training=training)
        return self.dense_2(x)

if __name__ == "__main__":
    parser = get_parser("Train model on Iris dataset")
    args = parser.parse_args()

    iris = load_iris()
    X = iris['data'].astype(np.float64)  # 转换为 float64
    y = iris['target'].reshape(-1, 1)

    encoder = OneHotEncoder(sparse_output=False)
    y = encoder.fit_transform(y).astype(np.float64)  # 转换为 float64

    x_train, x_test, y_train, y_test = train_test_split(
        X, y, test_size=0.3, random_state=116
    )

    learning_rate = 0.01  # 调整学习率
    epochs = 100
    batch_size = 8
    num_classes = 3
    n_qubits = 11  # 调整为11个量子比特（0到10）
    n_layers = 2

    model = QuantumNeuralNetwork(
        n_qubits=n_qubits,
        n_layers=n_layers,
        num_classes=num_classes
    )

    # 使用 Adam 优化器并应用梯度裁剪
    optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate, clipnorm=1.0)
    model.compile(
        optimizer=optimizer,
        loss='categorical_crossentropy',
        metrics=['accuracy']
    )

    def is_quantum_model(model):
        for layer in model.layers:
            if isinstance(layer, QuantumNeuralNetworkLayer):
                return True
        return False

    if is_quantum_model(model):
        print("The model contains a Quantum Neural Network (QNN) layer.")
    else:
        print("The model does not contain a Quantum Neural Network (QNN) layer.")

    print("\nQuantum Circuit Diagram:")
    sample_inputs = np.ones(4, dtype=np.float64) * 0.0  # 示例输入，对应4个特征
    sample_weights = np.zeros((n_layers, n_qubits, 3), dtype=np.float64)  # 示例权重
    print(qml.draw(quantum_neural_network_draw)(sample_inputs, sample_weights))  # 使用辅助 QNode

    if args.importance_training:
        wrapped_model = ConstantTimeImportanceTraining(model, score="loss")
        history = wrapped_model.fit(
            x_train, y_train,
            batch_size=batch_size,
            epochs=epochs,
            verbose=1,
            validation_data=(x_test, y_test)
        )
    else:
        history = model.fit(
            x_train, y_train,
            batch_size=batch_size,
            epochs=epochs,
            verbose=1,
            validation_data=(x_test, y_test)
        )

    score = model.evaluate(x_test, y_test, verbose=0)
    print('Test loss:', score[0])
    print('Test accuracy:', score[1])

    mean_accuracy, fluctuation = calculate_accuracy_fluctuation(history)
    print('Mean validation accuracy:', mean_accuracy)
    print('Accuracy fluctuation:', fluctuation)

    plot_history(history)

    # 关闭输出文件并恢复stdout
    sys.stdout = original_stdout
    output_file.close()

print("脚本执行完成。查看 'output.log' 获取打印输出，查看当前目录获取保存的图表。")
上述代码报错To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
Traceback (most recent call last):
  File "C:\代码备份库\importance-sampling-master-yuanweihua-QNN-pennylane\examples\yuanweihua_renew_usesoftmax_NQNN.py", line 355, in <module>
    history = wrapped_model.fit(
  File "C:\代码备份库\importance-sampling-master-yuanweihua-QNN-pennylane\importance_sampling\training.py", line 132, in fit
    return self.fit_dataset(
  File "C:\代码备份库\importance-sampling-master-yuanweihua-QNN-pennylane\importance_sampling\training.py", line 273, in fit_dataset
    loss_value, metrics_results, scores = self.train_batch(x_batch, y_batch, w)
  File "C:\代码备份库\importance-sampling-master-yuanweihua-QNN-pennylane\importance_sampling\training.py", line 336, in train_batch
    y_pred = self.model.model(x, training=True)
  File "C:\Users\liuwenjing\.conda\envs\pennylane3\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "C:\代码备份库\importance-sampling-master-yuanweihua-QNN-pennylane\examples\yuanweihua_renew_usesoftmax_NQNN.py", line 295, in call
    q_output = self.quantum_layer(inputs)
  File "C:\代码备份库\importance-sampling-master-yuanweihua-QNN-pennylane\examples\yuanweihua_renew_usesoftmax_NQNN.py", line 270, in call
    q_output = tf.map_fn(
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filejpvnma68.py", line 6, in <lambda>
    tf__lam = lambda x: ag__.with_function_scope(lambda lscope: ag__.converted_call(quantum_neural_network, (x, self.weights_qnn), None, lscope), 'lscope', ag__.STD)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filejpvnma68.py", line 6, in <lambda>
    tf__lam = lambda x: ag__.with_function_scope(lambda lscope: ag__.converted_call(quantum_neural_network, (x, self.weights_qnn), None, lscope), 'lscope', ag__.STD)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filexf5nwm7n.py", line 384, in tf____call__
    ag__.if_stmt(ag__.converted_call(ag__.ld(qml).active_return, (), None, fscope), if_body_20, else_body_20, get_state_20, set_state_20, ('do_return', 'retval_', 'self.device', "self.execute_kwargs['grad_on_execution']", 'self.gradient_fn', 'self.gradient_kwargs', 'self.interface'), 7)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filexf5nwm7n.py", line 88, in if_body_20
    res = ag__.converted_call(ag__.ld(qml).execute, ([ag__.ld(self).tape],), dict(device=ag__.ld(self).device, gradient_fn=ag__.ld(self).gradient_fn, interface=ag__.ld(self).interface, gradient_kwargs=ag__.ld(self).gradient_kwargs, override_shots=ag__.ld(override_shots), **ag__.ld(self).execute_kwargs), fscope)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_fileaxbgx7mu.py", line 505, in tf__execute
    ag__.if_stmt(ag__.not_(ag__.converted_call(ag__.ld(qml).active_return, (), None, fscope)), if_body_17, else_body_17, get_state_19, set_state_19, ('do_return', 'retval_', '_execute', 'cache', 'expand_fn', 'gradient_fn', 'gradient_kwargs', 'interface', 'tapes'), 2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_fileaxbgx7mu.py", line 490, in else_body_17
    ag__.if_stmt(ag__.ld(gradient_fn) is None, if_body_16, else_body_16, get_state_18, set_state_18, ('do_return', 'retval_', '_execute', 'gradient_fn', 'tapes'), 2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_fileaxbgx7mu.py", line 480, in else_body_16
    ag__.if_stmt(ag__.or_(lambda : ag__.ld(gradient_fn) == 'backprop', lambda : ag__.ld(interface) is None), if_body_15, else_body_15, get_state_17, set_state_17, ('do_return', 'retval_', '_execute', 'gradient_fn', 'tapes'), 2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_fileaxbgx7mu.py", line 286, in if_body_15
    retval_ = ag__.converted_call(ag__.ld(batch_fn), (ag__.converted_call(ag__.converted_call(ag__.ld(qml).interfaces.cache_execute, (ag__.ld(batch_execute), ag__.ld(cache)), dict(return_tuple=False, expand_fn=ag__.ld(expand_fn)), fscope), (ag__.ld(tapes),), None, fscope),), None, fscope)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_file9rxxqk87.py", line 373, in wrapper
    ag__.if_stmt(ag__.or_(lambda : ag__.ld(cache) is None, lambda : ag__.and_(lambda : ag__.converted_call(ag__.ld(isinstance), (ag__.ld(cache), ag__.ld(bool)), None, fscope_2), lambda : ag__.not_(ag__.ld(cache)))), if_body_14, else_body_14, get_state_16, set_state_16, ('do_return_2', 'retval__2', 'res'), 2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_file9rxxqk87.py", line 291, in else_body_14
    ag__.if_stmt(ag__.not_(ag__.ld(execution_tapes)), if_body_10, else_body_10, get_state_11, set_state_11, ('do_return_2', 'res', 'retval__2'), 3)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_file9rxxqk87.py", line 289, in else_body_10
    res = ag__.converted_call(ag__.ld(fn), (ag__.converted_call(ag__.ld(execution_tapes).values, (), None, fscope_2),), dict(**ag__.ld(kwargs)), fscope_2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_file9rxxqk87.py", line 66, in fn
    retval__1 = ag__.converted_call(ag__.ld(original_fn), (ag__.ld(tapes),), dict(**ag__.ld(kwargs)), fscope_1)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_fileprk7vcs8.py", line 20, in inner
    retval__1 = ag__.converted_call(ag__.ld(func), tuple(ag__.ld(args)), dict(**ag__.ld(kwds)), fscope_1)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_fileooplhnce.py", line 82, in tf__batch_execute
    ag__.if_stmt(ag__.not_(ag__.converted_call(ag__.ld(qml).active_return, (), None, fscope)), if_body_1, else_body_1, get_state_2, set_state_2, ('do_return', 'retval_'), 2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_fileooplhnce.py", line 58, in else_body_1
    ag__.for_stmt(ag__.ld(circuits), None, loop_body, get_state, set_state, (), {'iterate_names': 'circuit'})
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_fileooplhnce.py", line 54, in loop_body
    res = ag__.converted_call(ag__.ld(self).execute, (ag__.ld(circuit),), None, fscope)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filefwao4ysq.py", line 111, in tf__execute
    ag__.if_stmt(ag__.not_(ag__.converted_call(ag__.ld(qml).active_return, (), None, fscope)), if_body_3, else_body_3, get_state_3, set_state_3, ('do_return', 'retval_', 'self._num_executions', 'self._samples'), 4)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filefwao4ysq.py", line 54, in else_body_3
    ag__.converted_call(ag__.ld(self).apply, (ag__.ld(circuit).operations,), dict(rotations=ag__.converted_call(ag__.ld(self)._get_diagonalizing_gates, (ag__.ld(circuit),), None, fscope), **ag__.ld(kwargs)), fscope)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filexhfeixtr.py", line 108, in tf__apply
    ag__.for_stmt(ag__.converted_call(ag__.ld(enumerate), (ag__.ld(operations),), None, fscope), None, loop_body, get_state_7, set_state_7, ('self._state',), {'iterate_names': '(i, operation)'})
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filexhfeixtr.py", line 104, in loop_body
    ag__.if_stmt(ag__.converted_call(ag__.ld(isinstance), (ag__.ld(operation), ag__.ld(QubitStateVector)), None, fscope), if_body_6, else_body_6, get_state_6, set_state_6, ('self._debugger.snapshots[operation.tag]', 'self._state'), 2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filexhfeixtr.py", line 103, in else_body_6
    ag__.if_stmt(ag__.converted_call(ag__.ld(isinstance), (ag__.ld(operation), ag__.ld(BasisState)), None, fscope), if_body_5, else_body_5, get_state_5, set_state_5, ('self._debugger.snapshots[operation.tag]', 'self._state'), 2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filexhfeixtr.py", line 102, in else_body_5
    ag__.if_stmt(ag__.converted_call(ag__.ld(isinstance), (ag__.ld(operation), ag__.ld(Snapshot)), None, fscope), if_body_4, else_body_4, get_state_4, set_state_4, ('self._debugger.snapshots[operation.tag]', 'self._state'), 2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filexhfeixtr.py", line 101, in else_body_4
    ag__.if_stmt(ag__.converted_call(ag__.ld(isinstance), (ag__.ld(operation), ag__.ld(ParametrizedEvolution)), None, fscope), if_body_3, else_body_3, get_state_3, set_state_3, ('self._state',), 1)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filexhfeixtr.py", line 100, in else_body_3
    ag__.ld(self)._state = ag__.converted_call(ag__.ld(self)._apply_operation, (ag__.ld(self)._state, ag__.ld(operation)), None, fscope)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filex76y30qg.py", line 115, in tf___apply_operation
    ag__.if_stmt(ag__.ld(operation).__class__.__name__ == 'Identity', if_body_3, else_body_3, get_state_3, set_state_3, ('do_return', 'retval_'), 2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filex76y30qg.py", line 110, in else_body_3
    ag__.if_stmt(ag__.ld(operation).__class__.__name__ in ag__.ld(self)._apply_ops, if_body_2, else_body_2, get_state_2, set_state_2, ('do_return', 'retval_'), 2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filex76y30qg.py", line 106, in else_body_2
    ag__.if_stmt(ag__.ld(operation) in ag__.ld(diagonal_in_z_basis), if_body_1, else_body_1, get_state_1, set_state_1, ('do_return', 'retval_'), 2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filex76y30qg.py", line 105, in else_body_1
    ag__.if_stmt(ag__.converted_call(ag__.ld(len), (ag__.ld(wires),), None, fscope) <= 2, if_body, else_body, get_state, set_state, ('do_return', 'retval_'), 2)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filex76y30qg.py", line 92, in if_body
    retval_ = ag__.converted_call(ag__.ld(self)._apply_unitary_einsum, (ag__.ld(state), ag__.ld(matrix), ag__.ld(wires)), None, fscope)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filed3wsrzix.py", line 25, in tf___apply_unitary_einsum
    batch_size = ag__.converted_call(ag__.ld(self)._get_batch_size, (ag__.ld(mat), (ag__.ld(dim), ag__.ld(dim)), ag__.ld(dim) ** 2), None, fscope)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filewgt0wgg4.py", line 50, in tf___get_batch_size
    ag__.if_stmt(ag__.not_(ag__.converted_call(ag__.ld(qml).math.is_abstract, (ag__.ld(tensor),), None, fscope)), if_body_1, else_body_1, get_state_1, set_state_1, (), 0)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filewgt0wgg4.py", line 46, in if_body_1
    raise ag__.ld(err)
  File "C:\Users\LIUWEN~1\AppData\Local\Temp\__autograph_generated_filewgt0wgg4.py", line 36, in tf___get_batch_size
    ag__.if_stmt(ag__.or_(lambda : ag__.ld(ndim) > ag__.converted_call(ag__.ld(len), (ag__.ld(expected_shape),), None, fscope), lambda : ag__.ld(size) > ag__.ld(expected_size)), if_body, else_body, get_state, set_state, ('do_return', 'retval_'), 2)
ValueError: Exception encountered when calling layer "quantum_neural_network_layer" "                 f"(type QuantumNeuralNetworkLayer).

in user code:

    File "C:\代码备份库\importance-sampling-master-yuanweihua-QNN-pennylane\examples\yuanweihua_renew_usesoftmax_NQNN.py", line 271, in None  *
        lambda x: quantum_neural_network(x, self.weights_qnn)
    File "C:\Users\liuwenjing\.conda\envs\pennylane3\lib\site-packages\pennylane\qnode.py", line 867, in __call__  *
        res = qml.execute(
    File "C:\Users\liuwenjing\.conda\envs\pennylane3\lib\site-packages\pennylane\interfaces\execution.py", line 407, in execute  *
        qml.interfaces.cache_execute(
    File "C:\Users\liuwenjing\.conda\envs\pennylane3\lib\site-packages\pennylane\_qubit_device.py", line 588, in batch_execute  *
        res = self.execute(circuit)
    File "C:\Users\liuwenjing\.conda\envs\pennylane3\lib\site-packages\pennylane\_qubit_device.py", line 318, in execute  *
        self.apply(circuit.operations, rotations=self._get_diagonalizing_gates(circuit), **kwargs)
    File "C:\Users\liuwenjing\.conda\envs\pennylane3\lib\site-packages\pennylane\devices\default_qubit.py", line 276, in apply  *
        self._state = self._apply_operation(self._state, operation)
    File "C:\Users\liuwenjing\.conda\envs\pennylane3\lib\site-packages\pennylane\devices\default_qubit.py", line 322, in _apply_operation  *
        return self._apply_unitary_einsum(state, matrix, wires)
    File "C:\Users\liuwenjing\.conda\envs\pennylane3\lib\site-packages\pennylane\devices\default_qubit.py", line 839, in _apply_unitary_einsum  *
        batch_size = self._get_batch_size(mat, (dim, dim), dim**2)
    File "C:\Users\liuwenjing\.conda\envs\pennylane3\lib\site-packages\pennylane\devices\default_qubit_tf.py", line 196, in _get_batch_size  *
        if ndim > len(expected_shape) or size > expected_size:

    ValueError: the else branch must also have a return statement.


Call arguments received by layer "quantum_neural_network_layer" "                 f"(type QuantumNeuralNetworkLayer):
  • inputs=tf.Tensor(shape=(8, 4), dtype=float64)
报错的原因是什么？如下是环境信息
absl-py                      2.1.0
appdirs                      1.4.4
astunparse                   1.6.3
autograd                     1.7.0
autoray                      0.6.12
blinker                      1.8.2
cachetools                   5.5.0
certifi                      2024.8.30
charset-normalizer           3.3.2
contourpy                    1.3.0
cycler                       0.12.1
dill                         0.3.9
docplex                      2.28.240
flatbuffers                  24.3.25
fonttools                    4.54.1
gast                         0.4.0
google-auth                  2.35.0
google-auth-oauthlib         0.4.6
google-pasta                 0.2.0
grpcio                       1.66.2
h5py                         3.12.1
idna                         3.10
importlib_metadata           8.5.0
importlib_resources          6.4.5
joblib                       1.4.2
keras                        2.10.0
Keras-Preprocessing          1.1.2
kiwisolver                   1.4.7
libclang                     18.1.1
Markdown                     3.7
MarkupSafe                   2.1.5
matplotlib                   3.9.2
mpmath                       1.3.0
networkx                     3.2.1
numpy                        1.23.5
oauthlib                     3.2.2
opt_einsum                   3.4.0
packaging                    24.1
pbr                          6.1.0
PennyLane                    0.30.0
PennyLane-Lightning          0.31.0
pillow                       10.4.0
pip                          24.2
protobuf                     3.19.6
psutil                       6.0.0
pyasn1                       0.6.1
pyasn1_modules               0.4.1
pydot                        3.0.2
pydotplus                    2.0.2
pyparsing                    3.1.4
python-dateutil              2.9.0.post0
qiskit                       1.0.2
qiskit-aer                   0.14.0.1
qiskit-algorithms            0.3.0
qiskit-optimization          0.6.1
requests                     2.32.3
requests-oauthlib            2.0.0
rsa                          4.9
rustworkx                    0.15.1
scikit-learn                 1.5.2
scipy                        1.13.1
semantic-version             2.10.0
setuptools                   75.1.0
six                          1.16.0
stevedore                    5.3.0
symengine                    0.11.0
sympy                        1.13.3
tensorboard                  2.10.1
tensorboard-data-server      0.6.1
tensorboard-plugin-wit       1.8.1
tensorflow                   2.10.0
tensorflow-estimator         2.10.0
tensorflow-io-gcs-filesystem 0.31.0
termcolor                    2.4.0
threadpoolctl                3.5.0
toml                         0.10.2
typing_extensions            4.12.2
urllib3                      2.2.3
Werkzeug                     3.0.4
wheel                        0.44.0
wrapt                        1.16.0
zipp                         3.20.2