<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Copyright 2020 The TensorFlow Authors.
Step1:  量子卷积神经网络
<table class="tfo-notebook-buttons" align="left">
  <td><a target="_blank" href="https
Step2:  安装 TensorFlow Quantum：
Step3:  现在，导入 TensorFlow 和模块依赖项：
Step4:  1. 构建 QCNN
1.1 在 TensorFlow 计算图中组装电路
TensorFlow Quantum (TFQ) 提供了专为计算图中的电路构造而设计的层类。一个示例是从 tf.keras.Layer 继承的 tfq.layers.AddCircuit 层。此层可以追加或附加到电路的输入批次，如下图所示。
<img src="./images/qcnn_1.png" width="700">
下面的代码段使用了此层：
Step5:  检查输入张量：
Step6:  检查输出张量：
Step8:  虽然不使用 tfq.layers.AddCircuit 也可以运行下面的示例，但这是一个理解如何将复杂的功能嵌入 TensorFlow 计算图的好机会。
1.2 问题概述
您将准备簇态，并训练一个量子分类器来检测它是否处于“激发”状态。簇态是高度纠缠的，不过，这对经典计算机而言并非难以解决的问题。为了让您更清楚地理解，我们使用的这一数据集比论文中使用的更简单。
对于此分类任务，您将实现一个类似深度 <a href="https
Step9:  您可以看到，就像使用常规的机器学习一样，您创建了一个用于对模型进行基准测试的训练和测试集。利用以下代码段，您可以快速查看某些数据点：
Step11:  1.5 定义层
现在，我们在 TensorFlow 中定义上图中显示的层。
1.5.1 簇态
第一步是使用 <a href="https
Step12:  显示 <a href="https
Step16:  1.5.2 QCNN 层
按照 <a href="https
Step17:  要查看您创建的对象，请打印出单量子位酉电路：
Step18:  以及双量子位酉电路：
Step19:  以及双量子位池化电路：
Step21:  1.5.2.1 量子卷积
按照 <a href="https
Step22:  显示（高度水平的）电路：
Step24:  1.5.2.2 量子池化
量子池化层使用上面定义的双量子位池从 $N$ 个量子位池化为 $\frac{N}{2}$ 个量子位。
Step25:  检查池化组件电路：
Step27:  1.6 模型定义
现在，使用定义的层构造纯量子 CNN。首先创建八个量子位，再将其池化为一个量子位，然后测量 $\langle \hat{Z} \rangle$。
Step28:  1.7 训练模型
在整个批次上训练模型以简化此示例。
Step30:  2. 混合模型
您不必使用量子卷积将八个量子位池化为一个量子位，您可以执行一到两轮的量子卷积，然后将结果馈送到经典神经网络中。本部分探讨量子-经典混合模型。
2.1 使用单个量子滤波器的混合模型
应用一层量子卷积，在后跟密集连接的神经网络的所有位上读出 $\langle \hat{Z}_n \rangle$。
<img src="./images/qcnn_5.png" width="1000">
2.1.1 模型定义
Step31:  2.1.2 训练模型
Step32:  如您所见，在适当的经典模型的帮助下，混合模型通常比纯量子版本收敛得更快。
2.2 使用多个量子滤波器的混合卷积
现在，我们来试试使用多个量子卷积和一个经典神经网络的架构，将其组合在一起。
<img src="./images/qcnn_6.png" width="1000">
2.2.1 模型定义
Step33:  2.2.2 训练模型
<ASSISTANT_TASK:>
Python Code:
#@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.
Explanation: Copyright 2020 The TensorFlow Authors.
End of explanation
!pip install tensorflow==2.4.1
Explanation: 量子卷积神经网络
<table class="tfo-notebook-buttons" align="left">
  <td><a target="_blank" href="https://tensorflow.google.cn/quantum/tutorials/qcnn"><img src="https://tensorflow.google.cn/images/tf_logo_32px.png">在 TensorFlow.org 上查看</a></td>
  <td><a target="_blank" href="https://colab.research.google.com/github/tensorflow/docs-l10n/blob/master/site/zh-cn/quantum/tutorials/qcnn.ipynb"><img src="https://tensorflow.google.cn/images/colab_logo_32px.png">在 Google Colab 中运行</a></td>
  <td><a target="_blank" href="https://github.com/tensorflow/docs-l10n/blob/master/site/zh-cn/quantum/tutorials/qcnn.ipynb"><img src="https://tensorflow.google.cn/images/GitHub-Mark-32px.png">在 GitHub 上查看源代码</a></td>
  <td><a href="https://storage.googleapis.com/tensorflow_docs/docs-l10n/site/zh-cn/quantum/tutorials/qcnn.ipynb"><img src="https://tensorflow.google.cn/images/download_logo_32px.png">下载笔记本</a></td>
</table>
本教程介绍如何实现一个简化的<a href="https://www.nature.com/articles/s41567-019-0648-8" class="external">量子卷积神经网络</a> (QCNN)，即对同样具有平移不变性的经典卷积神经网络的提议量子模拟。
本示例演示如何检测量子数据源的某些属性，例如设备的量子传感器或复杂模拟。量子数据源是可能有或可能没有激发的<a href="https://arxiv.org/pdf/quant-ph/0504097.pdf" class="external">簇态</a>，后者是 QCNN 将学习检测的对象（论文中使用的数据集是 SPT 阶段分类）。
设置
End of explanation
!pip install tensorflow-quantum
# Update package resources to account for version changes.
import importlib, pkg_resources
importlib.reload(pkg_resources)
Explanation: 安装 TensorFlow Quantum：
End of explanation
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
Explanation: 现在，导入 TensorFlow 和模块依赖项：
End of explanation
qubit = cirq.GridQubit(0, 0)
# Define some circuits.
circuit1 = cirq.Circuit(cirq.X(qubit))
circuit2 = cirq.Circuit(cirq.H(qubit))
# Convert to a tensor.
input_circuit_tensor = tfq.convert_to_tensor([circuit1, circuit2])
# Define a circuit that we want to append
y_circuit = cirq.Circuit(cirq.Y(qubit))
# Instantiate our layer
y_appender = tfq.layers.AddCircuit()
# Run our circuit tensor through the layer and save the output.
output_circuit_tensor = y_appender(input_circuit_tensor, append=y_circuit)
Explanation: 1. 构建 QCNN
1.1 在 TensorFlow 计算图中组装电路
TensorFlow Quantum (TFQ) 提供了专为计算图中的电路构造而设计的层类。一个示例是从 tf.keras.Layer 继承的 tfq.layers.AddCircuit 层。此层可以追加或附加到电路的输入批次，如下图所示。
<img src="./images/qcnn_1.png" width="700">
下面的代码段使用了此层：
End of explanation
print(tfq.from_tensor(input_circuit_tensor))
Explanation: 检查输入张量：
End of explanation
print(tfq.from_tensor(output_circuit_tensor))
Explanation: 检查输出张量：
End of explanation
def generate_data(qubits):
    Generate training and testing data.
    n_rounds = 20  # Produces n_rounds * n_qubits datapoints.
    excitations = []
    labels = []
    for n in range(n_rounds):
        for bit in qubits:
            rng = np.random.uniform(-np.pi, np.pi)
            excitations.append(cirq.Circuit(cirq.rx(rng)(bit)))
            labels.append(1 if (-np.pi / 2) <= rng <= (np.pi / 2) else -1)
    split_ind = int(len(excitations) * 0.7)
    train_excitations = excitations[:split_ind]
    test_excitations = excitations[split_ind:]
    train_labels = labels[:split_ind]
    test_labels = labels[split_ind:]
    return tfq.convert_to_tensor(train_excitations), np.array(train_labels), \
        tfq.convert_to_tensor(test_excitations), np.array(test_labels)
Explanation: 虽然不使用 tfq.layers.AddCircuit 也可以运行下面的示例，但这是一个理解如何将复杂的功能嵌入 TensorFlow 计算图的好机会。
1.2 问题概述
您将准备簇态，并训练一个量子分类器来检测它是否处于“激发”状态。簇态是高度纠缠的，不过，这对经典计算机而言并非难以解决的问题。为了让您更清楚地理解，我们使用的这一数据集比论文中使用的更简单。
对于此分类任务，您将实现一个类似深度 <a href="https://arxiv.org/pdf/quant-ph/0610099.pdf" class="external">MERA</a> 的 QCNN 架构，因为：
就像 QCNN 一样，环上的簇态具有平移不变性。
簇态是高度纠缠的。
这种架构在减少纠缠方面应该会很有效，通过读出一个量子位来获得分类。
<img src="./images/qcnn_2.png" width="1000">
根据定义，“激发”簇态是指将 cirq.rx 门应用到其任何量子位的簇态。Qconv 和 QPool 在本教程的后续部分讨论。
1.3 为 TensorFlow 构建块
<img src="./images/qcnn_3.png" width="1000">
使用 TensorFlow Quantum 解决此问题的一种方式是实现以下几点：
模型的输入是一个电路张量，空电路或表明激发的特定量子位上的 X 门。
使用 tfq.layers.AddCircuit 层构造模型的其他量子组件。
使用 tfq.layers.PQC 层进行推断。它会读取 $\langle \hat{Z} \rangle$，并将其与激发态的标签 1 或非激发态的标签 -1 进行比较。
1.4 数据
在构建模型之前，您可以生成数据。在本例中，它将是簇态的激发（原论文使用的是一个更复杂的数据集）。激发通过 cirq.rx 门表示。我们将足够大的旋转视为激发，并使用 1 进行标记，不够大的旋转则使用 -1 标记，我们将其视为未激发。
End of explanation
sample_points, sample_labels, _, __ = generate_data(cirq.GridQubit.rect(1, 4))
print('Input:', tfq.from_tensor(sample_points)[0], 'Output:', sample_labels[0])
print('Input:', tfq.from_tensor(sample_points)[1], 'Output:', sample_labels[1])
Explanation: 您可以看到，就像使用常规的机器学习一样，您创建了一个用于对模型进行基准测试的训练和测试集。利用以下代码段，您可以快速查看某些数据点：
End of explanation
def cluster_state_circuit(bits):
    Return a cluster state on the qubits in `bits`.
    circuit = cirq.Circuit()
    circuit.append(cirq.H.on_each(bits))
    for this_bit, next_bit in zip(bits, bits[1:] + [bits[0]]):
        circuit.append(cirq.CZ(this_bit, next_bit))
    return circuit
Explanation: 1.5 定义层
现在，我们在 TensorFlow 中定义上图中显示的层。
1.5.1 簇态
第一步是使用 <a href="https://github.com/quantumlib/Cirq" class="external">Cirq</a>（Google 为量子电路编程提供的框架）定义<a href="https://arxiv.org/pdf/quant-ph/0504097.pdf" class="external">簇态</a>。由于这是模型的一个静态部分，因此使用 tfq.layers.AddCircuit 功能将其嵌入。
End of explanation
SVGCircuit(cluster_state_circuit(cirq.GridQubit.rect(1, 4)))
Explanation: 显示 <a href="https://cirq.readthedocs.io/en/stable/generated/cirq.GridQubit.html" class="external"><code>cirq.GridQubit</code></a> 的矩形的一个簇态电路：
End of explanation
def one_qubit_unitary(bit, symbols):
    Make a Cirq circuit enacting a rotation of the bloch sphere about the X,
    Y and Z axis, that depends on the values in `symbols`.
    
    return cirq.Circuit(
        cirq.X(bit)**symbols[0],
        cirq.Y(bit)**symbols[1],
        cirq.Z(bit)**symbols[2])
def two_qubit_unitary(bits, symbols):
    Make a Cirq circuit that creates an arbitrary two qubit unitary.
    circuit = cirq.Circuit()
    circuit += one_qubit_unitary(bits[0], symbols[0:3])
    circuit += one_qubit_unitary(bits[1], symbols[3:6])
    circuit += [cirq.ZZ(*bits)**symbols[6]]
    circuit += [cirq.YY(*bits)**symbols[7]]
    circuit += [cirq.XX(*bits)**symbols[8]]
    circuit += one_qubit_unitary(bits[0], symbols[9:12])
    circuit += one_qubit_unitary(bits[1], symbols[12:])
    return circuit
def two_qubit_pool(source_qubit, sink_qubit, symbols):
    Make a Cirq circuit to do a parameterized 'pooling' operation, which
    attempts to reduce entanglement down from two qubits to just one.
    pool_circuit = cirq.Circuit()
    sink_basis_selector = one_qubit_unitary(sink_qubit, symbols[0:3])
    source_basis_selector = one_qubit_unitary(source_qubit, symbols[3:6])
    pool_circuit.append(sink_basis_selector)
    pool_circuit.append(source_basis_selector)
    pool_circuit.append(cirq.CNOT(control=source_qubit, target=sink_qubit))
    pool_circuit.append(sink_basis_selector**-1)
    return pool_circuit
Explanation: 1.5.2 QCNN 层
按照 <a href="https://arxiv.org/abs/1810.03787" class="external">Cong 和 Lukin QCNN 论文</a>定义组成模型的层。这需要具备几个前提条件：
<a href="https://arxiv.org/abs/quant-ph/0507171" class="external">Tucci 论文</a>中提出的单或双量子位参数化酉矩阵。
一个通用的参数化双量子位池化运算。
End of explanation
SVGCircuit(one_qubit_unitary(cirq.GridQubit(0, 0), sympy.symbols('x0:3')))
Explanation: 要查看您创建的对象，请打印出单量子位酉电路：
End of explanation
SVGCircuit(two_qubit_unitary(cirq.GridQubit.rect(1, 2), sympy.symbols('x0:15')))
Explanation: 以及双量子位酉电路：
End of explanation
SVGCircuit(two_qubit_pool(*cirq.GridQubit.rect(1, 2), sympy.symbols('x0:6')))
Explanation: 以及双量子位池化电路：
End of explanation
def quantum_conv_circuit(bits, symbols):
    Quantum Convolution Layer following the above diagram.
    Return a Cirq circuit with the cascade of `two_qubit_unitary` applied
    to all pairs of qubits in `bits` as in the diagram above.
    
    circuit = cirq.Circuit()
    for first, second in zip(bits[0::2], bits[1::2]):
        circuit += two_qubit_unitary([first, second], symbols)
    for first, second in zip(bits[1::2], bits[2::2] + [bits[0]]):
        circuit += two_qubit_unitary([first, second], symbols)
    return circuit
Explanation: 1.5.2.1 量子卷积
按照 <a href="https://arxiv.org/abs/1810.03787" class="external">Cong 和 Lukin</a> 的论文所述，将一维量子卷积定义为对每对步长为 1 的相邻量子位的双量子位参数化酉的应用。
End of explanation
SVGCircuit(
    quantum_conv_circuit(cirq.GridQubit.rect(1, 8), sympy.symbols('x0:15')))
Explanation: 显示（高度水平的）电路：
End of explanation
def quantum_pool_circuit(source_bits, sink_bits, symbols):
    A layer that specifies a quantum pooling operation.
    A Quantum pool tries to learn to pool the relevant information from two
    qubits onto 1.
    
    circuit = cirq.Circuit()
    for source, sink in zip(source_bits, sink_bits):
        circuit += two_qubit_pool(source, sink, symbols)
    return circuit
Explanation: 1.5.2.2 量子池化
量子池化层使用上面定义的双量子位池从 $N$ 个量子位池化为 $\frac{N}{2}$ 个量子位。
End of explanation
test_bits = cirq.GridQubit.rect(1, 8)
SVGCircuit(
    quantum_pool_circuit(test_bits[:4], test_bits[4:], sympy.symbols('x0:6')))
Explanation: 检查池化组件电路：
End of explanation
def create_model_circuit(qubits):
    Create sequence of alternating convolution and pooling operators 
    which gradually shrink over time.
    model_circuit = cirq.Circuit()
    symbols = sympy.symbols('qconv0:63')
    # Cirq uses sympy.Symbols to map learnable variables. TensorFlow Quantum
    # scans incoming circuits and replaces these with TensorFlow variables.
    model_circuit += quantum_conv_circuit(qubits, symbols[0:15])
    model_circuit += quantum_pool_circuit(qubits[:4], qubits[4:],
                                          symbols[15:21])
    model_circuit += quantum_conv_circuit(qubits[4:], symbols[21:36])
    model_circuit += quantum_pool_circuit(qubits[4:6], qubits[6:],
                                          symbols[36:42])
    model_circuit += quantum_conv_circuit(qubits[6:], symbols[42:57])
    model_circuit += quantum_pool_circuit([qubits[6]], [qubits[7]],
                                          symbols[57:63])
    return model_circuit
# Create our qubits and readout operators in Cirq.
cluster_state_bits = cirq.GridQubit.rect(1, 8)
readout_operators = cirq.Z(cluster_state_bits[-1])
# Build a sequential model enacting the logic in 1.3 of this notebook.
# Here you are making the static cluster state prep as a part of the AddCircuit and the
# "quantum datapoints" are coming in the form of excitation
excitation_input = tf.keras.Input(shape=(), dtype=tf.dtypes.string)
cluster_state = tfq.layers.AddCircuit()(
    excitation_input, prepend=cluster_state_circuit(cluster_state_bits))
quantum_model = tfq.layers.PQC(create_model_circuit(cluster_state_bits),
                               readout_operators)(cluster_state)
qcnn_model = tf.keras.Model(inputs=[excitation_input], outputs=[quantum_model])
# Show the keras plot of the model
tf.keras.utils.plot_model(qcnn_model,
                          show_shapes=True,
                          show_layer_names=False,
                          dpi=70)
Explanation: 1.6 模型定义
现在，使用定义的层构造纯量子 CNN。首先创建八个量子位，再将其池化为一个量子位，然后测量 $\langle \hat{Z} \rangle$。
End of explanation
# Generate some training data.
train_excitations, train_labels, test_excitations, test_labels = generate_data(
    cluster_state_bits)
# Custom accuracy metric.
@tf.function
def custom_accuracy(y_true, y_pred):
    y_true = tf.squeeze(y_true)
    y_pred = tf.map_fn(lambda x: 1.0 if x >= 0 else -1.0, y_pred)
    return tf.keras.backend.mean(tf.keras.backend.equal(y_true, y_pred))
qcnn_model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.02),
                   loss=tf.losses.mse,
                   metrics=[custom_accuracy])
history = qcnn_model.fit(x=train_excitations,
                         y=train_labels,
                         batch_size=16,
                         epochs=25,
                         verbose=1,
                         validation_data=(test_excitations, test_labels))
plt.plot(history.history['loss'][1:], label='Training')
plt.plot(history.history['val_loss'][1:], label='Validation')
plt.title('Training a Quantum CNN to Detect Excited Cluster States')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
Explanation: 1.7 训练模型
在整个批次上训练模型以简化此示例。
End of explanation
# 1-local operators to read out
readouts = [cirq.Z(bit) for bit in cluster_state_bits[4:]]
def multi_readout_model_circuit(qubits):
    Make a model circuit with less quantum pool and conv operations.
    model_circuit = cirq.Circuit()
    symbols = sympy.symbols('qconv0:21')
    model_circuit += quantum_conv_circuit(qubits, symbols[0:15])
    model_circuit += quantum_pool_circuit(qubits[:4], qubits[4:],
                                          symbols[15:21])
    return model_circuit
# Build a model enacting the logic in 2.1 of this notebook.
excitation_input_dual = tf.keras.Input(shape=(), dtype=tf.dtypes.string)
cluster_state_dual = tfq.layers.AddCircuit()(
    excitation_input_dual, prepend=cluster_state_circuit(cluster_state_bits))
quantum_model_dual = tfq.layers.PQC(
    multi_readout_model_circuit(cluster_state_bits),
    readouts)(cluster_state_dual)
d1_dual = tf.keras.layers.Dense(8)(quantum_model_dual)
d2_dual = tf.keras.layers.Dense(1)(d1_dual)
hybrid_model = tf.keras.Model(inputs=[excitation_input_dual], outputs=[d2_dual])
# Display the model architecture
tf.keras.utils.plot_model(hybrid_model,
                          show_shapes=True,
                          show_layer_names=False,
                          dpi=70)
Explanation: 2. 混合模型
您不必使用量子卷积将八个量子位池化为一个量子位，您可以执行一到两轮的量子卷积，然后将结果馈送到经典神经网络中。本部分探讨量子-经典混合模型。
2.1 使用单个量子滤波器的混合模型
应用一层量子卷积，在后跟密集连接的神经网络的所有位上读出 $\langle \hat{Z}_n \rangle$。
<img src="./images/qcnn_5.png" width="1000">
2.1.1 模型定义
End of explanation
hybrid_model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.02),
                     loss=tf.losses.mse,
                     metrics=[custom_accuracy])
hybrid_history = hybrid_model.fit(x=train_excitations,
                                  y=train_labels,
                                  batch_size=16,
                                  epochs=25,
                                  verbose=1,
                                  validation_data=(test_excitations,
                                                   test_labels))
plt.plot(history.history['val_custom_accuracy'], label='QCNN')
plt.plot(hybrid_history.history['val_custom_accuracy'], label='Hybrid CNN')
plt.title('Quantum vs Hybrid CNN performance')
plt.xlabel('Epochs')
plt.legend()
plt.ylabel('Validation Accuracy')
plt.show()
Explanation: 2.1.2 训练模型
End of explanation
excitation_input_multi = tf.keras.Input(shape=(), dtype=tf.dtypes.string)
cluster_state_multi = tfq.layers.AddCircuit()(
    excitation_input_multi, prepend=cluster_state_circuit(cluster_state_bits))
# apply 3 different filters and measure expectation values
quantum_model_multi1 = tfq.layers.PQC(
    multi_readout_model_circuit(cluster_state_bits),
    readouts)(cluster_state_multi)
quantum_model_multi2 = tfq.layers.PQC(
    multi_readout_model_circuit(cluster_state_bits),
    readouts)(cluster_state_multi)
quantum_model_multi3 = tfq.layers.PQC(
    multi_readout_model_circuit(cluster_state_bits),
    readouts)(cluster_state_multi)
# concatenate outputs and feed into a small classical NN
concat_out = tf.keras.layers.concatenate(
    [quantum_model_multi1, quantum_model_multi2, quantum_model_multi3])
dense_1 = tf.keras.layers.Dense(8)(concat_out)
dense_2 = tf.keras.layers.Dense(1)(dense_1)
multi_qconv_model = tf.keras.Model(inputs=[excitation_input_multi],
                                   outputs=[dense_2])
# Display the model architecture
tf.keras.utils.plot_model(multi_qconv_model,
                          show_shapes=True,
                          show_layer_names=True,
                          dpi=70)
Explanation: 如您所见，在适当的经典模型的帮助下，混合模型通常比纯量子版本收敛得更快。
2.2 使用多个量子滤波器的混合卷积
现在，我们来试试使用多个量子卷积和一个经典神经网络的架构，将其组合在一起。
<img src="./images/qcnn_6.png" width="1000">
2.2.1 模型定义
End of explanation
multi_qconv_model.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.02),
    loss=tf.losses.mse,
    metrics=[custom_accuracy])
multi_qconv_history = multi_qconv_model.fit(x=train_excitations,
                                            y=train_labels,
                                            batch_size=16,
                                            epochs=25,
                                            verbose=1,
                                            validation_data=(test_excitations,
                                                             test_labels))
plt.plot(history.history['val_custom_accuracy'][:25], label='QCNN')
plt.plot(hybrid_history.history['val_custom_accuracy'][:25], label='Hybrid CNN')
plt.plot(multi_qconv_history.history['val_custom_accuracy'][:25],
         label='Hybrid CNN \n Multiple Quantum Filters')
plt.title('Quantum vs Hybrid CNN performance')
plt.xlabel('Epochs')
plt.legend()
plt.ylabel('Validation Accuracy')
plt.show()
Explanation: 2.2.2 训练模型
End of explanation
<END_TASK>