View source on GitHub 
Differentiate a circuit with respect to its inputs by adjoint method.
Inherits From: Differentiator
The Adjoint differentiator follows along with the methods described here: arXiv:1912.10877 and doi: 10.1111/j.1365246X.2006.02978.x. The Adjoint method differentiates the input circuits in roughly one forward and backward pass over the circuits, to calculate the gradient of a symbol only a constant number of gate operations need to be applied to the circuits state. When the number of parameters in a circuit is very large, this differentiator performs much better than all the others found in TFQ.
my_op = tfq.get_expectation_op()
adjoint_differentiator = tfq.differentiators.Adjoint()
# Get an expectation op, with this differentiator attached.
op = adjoint_differentiator.generate_differentiable_op(
analytic_op=my_op
)
qubit = cirq.GridQubit(0, 0)
circuit = tfq.convert_to_tensor([
cirq.Circuit(cirq.X(qubit) ** sympy.Symbol('alpha'))
])
psums = tfq.convert_to_tensor([[cirq.Z(qubit)]])
symbol_values_array = np.array([[0.123]], dtype=np.float32)
# Calculate tfq gradient.
symbol_values_tensor = tf.convert_to_tensor(symbol_values_array)
with tf.GradientTape() as g:
g.watch(symbol_values_tensor)
expectations = op(circuit, ['alpha'], symbol_values_tensor, psums
)
grads = g.gradient(expectations, symbol_values_tensor)
grads
tf.Tensor([[1.1839]], shape=(1, 1), dtype=float32)
Methods
differentiate_analytic
@tf.function
differentiate_analytic( programs, symbol_names, symbol_values, pauli_sums, forward_pass_vals, grad )
differentiate_sampled
differentiate_sampled(
programs, symbol_names, symbol_values, pauli_sums, num_samples,
forward_pass_vals, grad
)
Specify how to differentiate a circuit with sampled expectation.
This is called at graph runtime by TensorFlow. differentiate_sampled
should calculate the gradient of a batch of circuits and return it
formatted as indicated below. See
tfq.differentiators.ForwardDifference
for an example.
Args  

programs

tf.Tensor of strings with shape [batch_size] containing
the string representations of the circuits to be executed.

symbol_names

tf.Tensor of strings with shape [n_params], which
is used to specify the order in which the values in
symbol_values should be placed inside of the circuits in
programs .

symbol_values

tf.Tensor of real numbers with shape
[batch_size, n_params] specifying parameter values to resolve
into the circuits specified by programs, following the ordering
dictated by symbol_names .

pauli_sums

tf.Tensor of strings with shape [batch_size, n_ops]
containing the string representation of the operators that will
be used on all of the circuits in the expectation calculations.

num_samples

tf.Tensor of positive integers representing the
number of samples per term in each term of pauli_sums used
during the forward pass.

forward_pass_vals

tf.Tensor of real numbers with shape
[batch_size, n_ops] containing the output of the forward pass
through the op you are differentiating.

grad

tf.Tensor of real numbers with shape [batch_size, n_ops]
representing the gradient backpropagated to the output of the
op you are differentiating through.

Returns  

A tf.Tensor with the same shape as symbol_values representing
the gradient backpropageted to the symbol_values input of the op
you are differentiating through.

generate_differentiable_op
generate_differentiable_op(
*, sampled_op=None, analytic_op=None
)
Generate a differentiable op by attaching self to an op.
See tfq.differentiators.Differentiator
. This has been partially
reimplemented by the Adjoint differentiator to disallow the
sampled_op
input.
Args  

sampled_op

A callable op that you want to make differentiable
using this differentiator's differentiate_sampled method.

analytic_op

A callable op that you want to make differentiable
using this differentiators differentiate_analytic method.

Returns  

A callable op that who's gradients are now registered to be
a call to this differentiators differentiate_* function.

refresh
refresh()
Refresh this differentiator in order to use it with other ops.