# Fraud Detection code using Strawberryfields

**URL:** <https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030>\
**Category:** PennyLane Strawberry Fields\
**Created:** [May 10, 2021, 4:28am UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030 "2021-05-10T04:28:48Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Satanik\_Mitra](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/satanik_mitra/32/499_2.png) [@Satanik\_Mitra](https://discuss.pennylane.ai/u/Satanik_Mitra)\
**Post date:** [May 10, 2021, 4:28am UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/1 "2021-05-10T04:28:48Z")

</div>

Hello, @nathan or @Maria_Schuld or @Tom_Bromley I am working on the github repo of fraud detection code. [https://github.com/XanaduAI/quantum-neural-networks/blob/master/fraud\_detection/fraud\_detection.py](https://github.com/XanaduAI/quantum-neural-networks/blob/master/fraud_detection/fraud_detection.py)  
I am getting an error when ever I am executing -

```
# construct the two-mode Strawberry Fields engine
eng, q = sf.Engine(mode_number)

# construct the circuit
with eng:
    input_qnn_layer()

    for i in range(depth):
        qnn_layer(i)

# run the engine (in batch mode)
state = eng.run("tf", cutoff_dim=cutoff, eval=False, batch_size=batch_size)
# extract the state
ket = state.ket()

```

I am getting error like -

> TypeError Traceback (most recent call last)  
> in ()  
> 3 # ===================================================================================  
> 4 # construct the two-mode Strawberry Fields engine  
> ----\> 5 eng, q = sf.Engine(mode\_number)  
> 6  
> 7 # construct the circuit  
> /usr/local/lib/python3.7/dist-packages/strawberryfields/engine.py in **init** (self, backend, backend\_options)  
> 66 self.backend = backend  
> 67 else:  
> —\> 68 raise TypeError(“backend must be a string or a BaseBackend instance.”)  
> 69  
> 70 @abc.abstractmethod  
> TypeError: backend must be a string or a BaseBackend instance.

I have modified the code as per the latest coding convention of strawberryfield plugins -

```
eng= sf.Engine(backend="tf")

q = sf.Program(mode_number)

# construct the circuit

with eng:

    input_qnn_layer()

    for i in range(depth):

        qnn_layer(i)

# run the engine (in batch mode)

state = eng.run("tf", cutoff_dim=cutoff, eval=False, batch_size=batch_size)

# extract the state

ket = state.ket()

```

However getting an error like -

> AttributeError Traceback (most recent call last)  
> in ()  
> 8  
> 9 # construct the circuit  
> —\> 10 with eng:  
> 11 input\_qnn\_layer()  
> 12  
> AttributeError: **enter**

Please suggest something.

---

<div class="post-metadata">

**Author:** ![Maria\_Schuld](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/maria_schuld/32/166_2.png) [@Maria\_Schuld](https://discuss.pennylane.ai/u/Maria_Schuld)\
**Post date:** [May 10, 2021, 1:10pm UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/2 "2021-05-10T13:10:08Z")

</div>

Hey @Satanik_Mitra,

I am having trouble reproducing your error but would like to help!

Could you post a minimum working example, i.e., a small code block that I can just copy & paste and execute, including all imports and variables? And can you confirm your SF version (`import strawberryfields as sf` and then print the output of `sf.about()`) ? Thanks!

PS: Maybe reinstalling SF can solve the problem…your errors look like something is very genuinely wrong with running your code.

---

<div class="post-metadata">

**Author:** ![Satanik\_Mitra](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/satanik_mitra/32/499_2.png) [@Satanik\_Mitra](https://discuss.pennylane.ai/u/Satanik_Mitra)\
**Post date:** [May 11, 2021, 9:49am UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/3 "2021-05-11T09:49:23Z")

</div>

```
import numpy as np
import os

import tensorflow as tf

import strawberryfields as sf
from strawberryfields.ops import Dgate, BSgate, Kgate, Sgate, Rgate
import sys
sys.path.append("..")
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

# ===================================================================================
# Hyperparameters
# ===================================================================================

# Two modes required: one for "genuine" transactions and one for "fradulent"
mode_number = 2
# Number of photonic quantum layers
depth = 4

# Fock basis truncation
cutoff = 10
# Number of batches in optimization
reps = 30000

# Label for simulation
simulation_label = 1

# Number of batches to use in the optimization
batch_size = 24

# Random initialization of gate parameters
sdev_photon = 0.1
sdev = 1

# Variable clipping values
disp_clip = 5
sq_clip = 5
kerr_clip = 1

# If loading from checkpoint, previous batch number reached
ckpt_val = 0

# Number of repetitions between each output to TensorBoard
tb_reps = 100
# Number of repetitions between each model save
savr_reps = 1000

model_string = str(simulation_label)

# Target location of output
folder_locator = './outputs/'

# Locations of TensorBoard and model save outputs
board_string = folder_locator + 'tensorboard/' + model_string + '/'
checkpoint_string = folder_locator + 'models/' + model_string + '/'

# ===================================================================================
# Loading the training data
# ===================================================================================

# Data outputted from data_processor.py
data_genuine = np.loadtxt('creditcard_genuine_1.csv', delimiter=',')
data_fraudulent = np.loadtxt('creditcard_fraudulent_1.csv', delimiter=',')

# Combining genuine and fraudulent data
data_combined = np.append(data_genuine, data_fraudulent, axis=0)
data_points = len(data_combined)

# ===================================================================================
# Setting up the classical NN input
# ===================================================================================

# Input neurons
input_neurons = 10
# Widths of hidden layers
nn_architecture = [10, 10]
# Output neurons of classical part
output_neurons = 14

# Defining classical network parameters
input_classical_layer = tf.placeholder(tf.float32, shape=[batch_size, input_neurons])

layer_matrix_1 = tf.Variable(tf.random_normal(shape=[input_neurons, nn_architecture[0]]))
offset_1 = tf.Variable(tf.random_normal(shape=[nn_architecture[0]]))

layer_matrix_2 = tf.Variable(tf.random_normal(shape=[nn_architecture[0], nn_architecture[1]]))
offset_2 = tf.Variable(tf.random_normal(shape=[nn_architecture[1]]))

layer_matrix_3 = tf.Variable(tf.random_normal(shape=[nn_architecture[1], output_neurons]))
offset_3 = tf.Variable(tf.random_normal(shape=[output_neurons]))

# Creating hidden layers and output
layer_1 = tf.nn.elu(tf.matmul(input_classical_layer, layer_matrix_1) + offset_1)
layer_2 = tf.nn.elu(tf.matmul(layer_1, layer_matrix_2) + offset_2)

output_layer = tf.nn.elu(tf.matmul(layer_2, layer_matrix_3) + offset_3)

# ===================================================================================
# Defining QNN parameters
# ===================================================================================

# Number of beamsplitters in interferometer
bs_in_interferometer = int(1.0 * mode_number * (mode_number - 1) / 2)

with tf.name_scope('variables'):
    bs_variables = tf.Variable(tf.random_normal(shape=[depth, bs_in_interferometer, 2, 2]
                                                , stddev=sdev))
    phase_variables = tf.Variable(tf.random_normal(shape=[depth, mode_number, 2], stddev=sdev))

    sq_magnitude_variables = tf.Variable(tf.random_normal(shape=[depth, mode_number]
                                                          , stddev=sdev_photon))
    sq_phase_variables = tf.Variable(tf.random_normal(shape=[depth, mode_number]
                                                      , stddev=sdev))
    disp_magnitude_variables = tf.Variable(tf.random_normal(shape=[depth, mode_number]
                                                            , stddev=sdev_photon))
    disp_phase_variables = tf.Variable(tf.random_normal(shape=[depth, mode_number]
                                                        , stddev=sdev))
    kerr_variables = tf.Variable(tf.random_normal(shape=[depth, mode_number], stddev=sdev_photon))

parameters = [layer_matrix_1, offset_1, layer_matrix_2, offset_2, layer_matrix_3, offset_3, bs_variables,
              phase_variables, sq_magnitude_variables, sq_phase_variables, disp_magnitude_variables,
              disp_phase_variables, kerr_variables]

# ===================================================================================
# Constructing quantum layers
# ===================================================================================

# Defining input QNN layer, whose parameters are set by the outputs of the classical network
def input_qnn_layer():
    with tf.name_scope('inputlayer'):
        Sgate(tf.clip_by_value(output_layer[:, 0], -sq_clip, sq_clip), output_layer[:, 1]) | q[0]
        Sgate(tf.clip_by_value(output_layer[:, 2], -sq_clip, sq_clip), output_layer[:, 3]) | q[1]

        BSgate(output_layer[:, 4], output_layer[:, 5]) | (q[0], q[1])

        Rgate(output_layer[:, 6]) | q[0]
        Rgate(output_layer[:, 7]) | q[1]

        Dgate(tf.clip_by_value(output_layer[:, 8], -disp_clip, disp_clip), output_layer[:, 9]) \
        | q[0]
        Dgate(tf.clip_by_value(output_layer[:, 10], -disp_clip, disp_clip), output_layer[:, 11]) \
        | q[1]

        Kgate(tf.clip_by_value(output_layer[:, 12], -kerr_clip, kerr_clip)) | q[0]
        Kgate(tf.clip_by_value(output_layer[:, 13], -kerr_clip, kerr_clip)) | q[1]

# Defining standard QNN layers
def qnn_layer(layer_number):
    with tf.name_scope('layer_{}'.format(layer_number)):
        BSgate(bs_variables[layer_number, 0, 0, 0], bs_variables[layer_number, 0, 0, 1]) \
        | (q[0], q[1])

        for i in range(mode_number):
            Rgate(phase_variables[layer_number, i, 0]) | q[i]

        for i in range(mode_number):
            Sgate(tf.clip_by_value(sq_magnitude_variables[layer_number, i], -sq_clip, sq_clip),
                  sq_phase_variables[layer_number, i]) | q[i]

        BSgate(bs_variables[layer_number, 0, 1, 0], bs_variables[layer_number, 0, 1, 1]) \
        | (q[0], q[1])

        for i in range(mode_number):
            Rgate(phase_variables[layer_number, i, 1]) | q[i]

        for i in range(mode_number):
            Dgate(tf.clip_by_value(disp_magnitude_variables[layer_number, i], -disp_clip,
                                   disp_clip), disp_phase_variables[layer_number, i]) | q[i]

        for i in range(mode_number):
            Kgate(tf.clip_by_value(kerr_variables[layer_number, i], -kerr_clip, kerr_clip)) | q[i]

# ===================================================================================
# Defining QNN
# ===================================================================================

# construct the two-mode Strawberry Fields engine
eng, q = sf.Engine(mode_number)

# construct the circuit
with eng:
    input_qnn_layer()

    for i in range(depth):
        qnn_layer(i)

# run the engine (in batch mode)
state = eng.run("tf", cutoff_dim=cutoff, eval=False, batch_size=batch_size)
# extract the state
ket = state.ket()

```

@Maria_Schuld Now in the defining QNN part I am getting the error. I have to change the tensorflow version as the placeholder method is not working with current TF version. My strawberryField version is -

> Strawberry Fields: a Python library for continuous-variable quantum circuits.  
> Copyright 2018-2020 Xanadu Quantum Technologies Inc.
> 
> Python version: 3.7.10  
> Platform info: Linux-5.4.109±x86\_64-with-Ubuntu-18.04-bionic  
> Installation path: /usr/local/lib/python3.7/dist-packages/strawberryfields  
> Strawberry Fields version: 0.18.0  
> Numpy version: 1.19.5  
> Scipy version: 1.4.1  
> SymPy version: 1.7.1  
> NetworkX version: 2.5.1  
> The Walrus version: 0.15.1  
> Blackbird version: 0.3.0  
> TensorFlow version: 2.4.1

---

<div class="post-metadata">

**Author:** ![Maria\_Schuld](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/maria_schuld/32/166_2.png) [@Maria\_Schuld](https://discuss.pennylane.ai/u/Maria_Schuld)\
**Post date:** [May 11, 2021, 12:53pm UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/4 "2021-05-11T12:53:15Z")

</div>

Thanks for the details! It’s quite a task to bring this old code example up to scratch with latest StrawberryFields & TensorFlow code 🙂

While I haven’t gotten the entire code example to work, there are a few obvious things you could try and fix:

The latest [SF syntax](https://strawberryfields.ai/photonics/) requires you to use the program as a context and then create an engine with the right cutoff defined, i.e.,

```auto
prog = sf.Program(mode_number)

# construct the circuit
with prog.context as q:

    # construct circuit here

# run the engine 
eng = sf.Engine(backend="tf", backend_options={"cutoff_dim": 5})
state = eng.run(prog)

```

Furthermore, if I see it correctly, you will have to pass `q` (which is the program) to the functions that define the layers. Otherwise these functions cannot know what `q` - the quantum register - actually is. So, maybe try

```python
# construct the circuit
with prog.context as q:

    input_qnn_layer(q)

    for i in range(depth):
        qnn_layer(q, i)

```

and define the layers with the expression `def input_qnn_layer(q):`, so they use the `q` from the program’s context.

I hope these observations will help you to make it work, if not let me know 🙂

And one more tip: when you are debugging, just delete all the clutter and reduce the circuit to a single gate. If the error persists you can use the small piece of code to find the errors, and only add more complexity once the errors are all solved. This will also make our life a lot easier!

---

<div class="post-metadata">

**Author:** ![Maria\_Schuld](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/maria_schuld/32/166_2.png) [@Maria\_Schuld](https://discuss.pennylane.ai/u/Maria_Schuld)\
**Post date:** [May 11, 2021, 1:17pm UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/5 "2021-05-11T13:17:09Z")

</div>

Oh and one more comment: You may find it easier to switch to PennyLane, where [this demo](https://pennylane.ai/qml/demos/quantum_neural_net.html) describes a similar example.

---

<div class="post-metadata">

**Author:** ![Satanik\_Mitra](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/satanik_mitra/32/499_2.png) [@Satanik\_Mitra](https://discuss.pennylane.ai/u/Satanik_Mitra)\
**Post date:** [May 11, 2021, 1:24pm UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/6 "2021-05-11T13:24:42Z")

</div>

Thank You so much @Maria_Schuld for such a wonderful response. I do implement the changes and come back to you in case any error appears 🙂 🙂

---

<div class="post-metadata">

**Author:** ![Satanik\_Mitra](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/satanik_mitra/32/499_2.png) [@Satanik\_Mitra](https://discuss.pennylane.ai/u/Satanik_Mitra)\
**Post date:** [May 11, 2021, 2:02pm UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/7 "2021-05-11T14:02:46Z")

</div>

One more thing @Maria_Schuld can you confirm me which strawberryfield and tensorflow version have you used while writing the original code. I was checking the link - [https://github.com/XanaduAI/strawberryfields/releases](https://github.com/XanaduAI/strawberryfields/releases)  
If possible I can downgrade the strawberry version.

---

<div class="post-metadata">

**Author:** ![Maria\_Schuld](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/maria_schuld/32/166_2.png) [@Maria\_Schuld](https://discuss.pennylane.ai/u/Maria_Schuld)\
**Post date:** [May 11, 2021, 2:35pm UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/8 "2021-05-11T14:35:29Z")

</div>

Oh yes, good idea. You find the versions in the `requirements.txt` [file](https://github.com/XanaduAI/quantum-neural-networks/blob/master/requirements.txt) of the repo:

```auto
strawberryfields==0.10
tensorflow==1.3

```

---

<div class="post-metadata">

**Author:** ![Satanik\_Mitra](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/satanik_mitra/32/499_2.png) [@Satanik\_Mitra](https://discuss.pennylane.ai/u/Satanik_Mitra)\
**Post date:** [May 13, 2021, 4:39pm UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/9 "2021-05-13T16:39:58Z")

</div>

@Maria_Schuld it seems downgrading is difficult. however I am going with the current version of tf and strawberryfields. I have implemented the circuit as per your suggestion that is -

```
prog = sf.Program(mode_number)

# construct the circuit
with prog.context as q:

input_qnn_layer(q)

for i in range(depth):
    qnn_layer(q,i)

# run the engine 
eng = sf.Engine(backend="tf", backend_options={"cutoff_dim": 5})
state = eng.run(prog) 

```

I am getting an error like

> ValueError: The custom\_gradient decorator currently supports keywords arguments only when eager execution is enabled.

---

<div class="post-metadata">

**Author:** ![Tom\_Bromley](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/tom_bromley/32/129_2.png) [@Tom\_Bromley](https://discuss.pennylane.ai/u/Tom_Bromley)\
**Post date:** [May 17, 2021, 12:15pm UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/10 "2021-05-17T12:15:22Z")

</div>

Hey @Satanik_Mitra!

> it seems downgrading is difficult.

Yes potentially, are you struggling with getting the old version of TF? You can download wheels for TF v0.3 [here](https://pypi.org/project/tensorflow/1.3.0/#files) - note that we also suggest using Python 3.5 or 3.6 (see [here](https://github.com/XanaduAI/quantum-neural-networks#requirements)).

If you’re just curious to get the code running, it might be simpler to downgrade your dependencies. However, it would be nice to get the fraud detection code updated and compatible with more recent versions of SF and TF. Regarding your `custom_gradient decorator` error, this is likely due to

```python
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

```

Ideally, we won’t need to import the v1-compatible version of TensorFlow. If you remove these lines, you’ll get errors like:

```bash
AttributeError: module 'tensorflow' has no attribute 'placeholder'

```

This means a comprehensive update of the script is needed to follow the TF 2.0 [style](https://www.tensorflow.org/guide/effective_tf2). The best resource for doing this within the context of SF is our ML tutorial [here](https://strawberryfields.ai/photonics/demos/run_tutorial_machine_learning.html).

If you do manage to successfully update the fraud detection code, we’d be very happy if you make a [pull request](https://github.com/XanaduAI/quantum-neural-networks/pulls) to the repo!

Thanks,  
Tom

---

<div class="post-metadata">

**Author:** ![Satanik\_Mitra](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/satanik_mitra/32/499_2.png) [@Satanik\_Mitra](https://discuss.pennylane.ai/u/Satanik_Mitra)\
**Post date:** [May 31, 2021, 9:58am UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/11 "2021-05-31T09:58:02Z")

</div>

Hi @Tom_Bromley and @Maria_Schuld I have successfully executed the code for fraud detection with tensorflow=1.3.0 and SF=0.10. However, I am trying to implement it with current version of SF and TF. I will let you know if I succeed.  
Meanwhile, I was wondering about one thing in fraud detection. Why 10 features are chosen from the dataset, why can’t we choose 14 instead? If you kindly put some light onto it.

---

<div class="post-metadata">

**Author:** ![Tom\_Bromley](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/tom_bromley/32/129_2.png) [@Tom\_Bromley](https://discuss.pennylane.ai/u/Tom_Bromley)\
**Post date:** [May 31, 2021, 11:27am UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/12 "2021-05-31T11:27:42Z")

</div>

Hi @Satanik_Mitra!

> Why 10 features are chosen from the dataset, why can’t we choose 14 instead?

I believe we just used 10 to keep things manageable, and it may well work if you increase to 14 features. In fact, the [original dataset](https://www.kaggle.com/mlg-ulb/creditcardfraud) has 28 features, so you could include all of those as long as you ensure there are 14 features input into the quantum part of the network.

However, bear in mind that the 28 features are a result of a PCA, and (this needs to be double checked) the features are ordered by importance. We take the first 10 features, and each new feature added after that may have a diminished usefulness when training the model.

---

<div class="post-metadata">

**Author:** ![Satanik\_Mitra](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/satanik_mitra/32/499_2.png) [@Satanik\_Mitra](https://discuss.pennylane.ai/u/Satanik_Mitra)\
**Post date:** [May 31, 2021, 2:22pm UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/13 "2021-05-31T14:22:34Z")

</div>

Thanks a lot @Tom_Bromley 🙂

---

<div class="post-metadata">

**Author:** ![josh](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/josh/32/100_2.png) [@josh](https://discuss.pennylane.ai/u/josh)\
**Post date:** [June 1, 2021, 12:45pm UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/14 "2021-06-01T12:45:49Z")

</div>

Glad to see you have it solved @Satanik_Mitra 🙂 I’m going to close this post as your question is resolved - feel free to begin a new post if you have any other questions!

---

<div class="post-metadata">

**Author:** ![josh](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/josh/32/100_2.png) [@josh](https://discuss.pennylane.ai/u/josh)\
**Post date:** [June 1, 2021, 12:45pm UTC](https://discuss.pennylane.ai/t/fraud-detection-code-using-strawberryfields/1030/15 "2021-06-01T12:45:54Z")

</div>

Closed on June 1, 2021, 12:45pm UTC


