# Neural Networks

## Network object

A neural network object describes how input data should be preprocessed to be able to perform a simple inference and get raw output features from any layer.

<table><thead><tr><th width="179">Parameter</th><th width="134">Type</th><th width="115">Attributes</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>int</td><td>read-only</td><td>The ID of the neural network.</td></tr><tr><td>name</td><td>string</td><td></td><td>A short name for your network.</td></tr><tr><td>description</td><td>string</td><td></td><td>A longer description of your network.</td></tr><tr><td>update_date</td><td>string</td><td>read-only</td><td>Date time (ISO 8601 format) of the last update of the network.</td></tr><tr><td>metadata</td><td>object</td><td></td><td>A JSON field containing any kind of information that you may find interesting to store.</td></tr><tr><td>framework</td><td>string</td><td>immutable</td><td><p>A string describing which framework to use for your network. Possible values are: </p><ul><li><code>tensorflow-1.x</code>: support Tensorflow models up to version 2.9</li></ul></td></tr><tr><td>preprocessing</td><td><a href="#pre-processing-object">object</a></td><td>immutable</td><td>A pre-processing object to describe how input data should be pre-processed.</td></tr><tr><td>postprocessings</td><td>array(<a href="#post-processing-object">object</a>)</td><td>immutable</td><td>An array of post-processing object to list output tensors.</td></tr><tr><td>task_id</td><td>int</td><td>read-only</td><td>ID of the task containing the deployment status of the network.</td></tr></tbody></table>

{% hint style="danger" %}
Once the network has been created, you cannot modify the `preprocessing` field anymore.
{% endhint %}

### Pre-processing object

This object describes how data should be preprocessed for each input of the network.

<table><thead><tr><th width="174.33333333333331">Parameter</th><th width="141">Type</th><th>Description</th></tr></thead><tbody><tr><td>inputs</td><td>array(<a href="#input-pre-processing">object</a>)</td><td>A list of Input Preprocessing Object. The order matters as input data will be fed in the same order at inference time.</td></tr><tr><td>batched_output</td><td>bool</td><td><em>[deprecated]</em> Set this value to <code>True</code></td></tr></tbody></table>

### **Input pre-processing**

<table><thead><tr><th width="174.33333333333331">Parameter</th><th width="143">Type</th><th>Description</th></tr></thead><tbody><tr><td>tensor_name</td><td>string</td><td>The name of the input tensor that this input will feed.</td></tr><tr><td>image</td><td><a href="#image-pre-processing">object</a></td><td>An Image Preprocessing Object. Currently, the only supported input type.</td></tr></tbody></table>

### **Image pre-processing**

<table><thead><tr><th width="175.33333333333331">Parameter</th><th width="146">Type</th><th>Description</th></tr></thead><tbody><tr><td>dimension_order</td><td>string</td><td><p>A value describing the order of the dimensions in a batch N = batch_size, C = Channel, H = Height, W = Width Possible values are:</p><ul><li><code>NCHW</code></li><li><code>NCWH</code></li><li><code>NHWC</code></li><li><code>NWHC</code></li></ul></td></tr><tr><td>resize_type</td><td>string</td><td><p></p><p>Possible values are:</p><ul><li><code>SQUASH</code>: image is resized to fit network input, losing aspect ratio.</li><li><code>CROP</code>: image is resized so that the smallest side fits the network input, the rest is cropped.</li><li><code>FILL</code>: image is resized so that the largest side fits the network input, the rest is filled with white.</li><li><code>NETWORK</code>: image is resized so that its largest side fits target_size (see below) and the network is reshaped accordingly.</li></ul></td></tr><tr><td>target_size</td><td>string</td><td><p></p><p>Target size of the input image. It might have multiple formats. In the following <code>W</code>, <code>H</code> and <code>N</code> denote integer numbers, <code>W</code> (and <code>H</code>) being used specifically for width (and height), respectively:</p><ul><li><code>WxH</code>: image is resized so that width and height fit the specified sizes.</li><li><code>N</code>: image is resized so that the largest side of the input image matches the specified number of pixels.</li></ul></td></tr><tr><td>color_channels</td><td>string</td><td>Might be <code>RGB</code>, <code>BGR</code> or <code>L</code> (for gray levels).</td></tr><tr><td>pixel_scaling</td><td>float</td><td>Pixel values will be normalized between 0 and <code>pixel_scaling</code> before mean subtraction.</td></tr></tbody></table>

### Post-processing object

This object maps output tensors to a specific function in order to interpret them thanks to [recognition versions](https://docs.deepomatic.com/deepomatic-api-v0.7/recognition-version).

{% hint style="info" %}
You must specify exactly one of the `tensors_output` or `standard_output` fields. When we specify an expected tensor size in the description of those fields, we omit the first dimension of the tensor (i.e. the batch size).
{% endhint %}

<table><thead><tr><th width="177.33333333333331">Attribute</th><th width="129">Type</th><th>Description</th></tr></thead><tbody><tr><td>tensors_output</td><td><a href="#standard-post-processing">object</a></td><td>A simple ordered list of tensor names.</td></tr><tr><td>standard_output</td><td><a href="#standard-post-processing-deprecated">object</a></td><td><em>[deprecated]</em> A post-processing specific to detection.</td></tr></tbody></table>

#### Default post-processing

<table><thead><tr><th width="181">Attribute</th><th width="126.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>tensors</td><td>array(string)</td><td>A simple ordered list of tensor names.</td></tr></tbody></table>

#### Standard post-processing (deprecated)

<table><thead><tr><th width="184">Attribute</th><th width="125.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td>boxes_tensor</td><td>string</td><td>The name of the output tensor containing the boxes. It must be of size <code>N x 4</code>where <code>N</code> is the number of detected regions and the 4 columns correspond to <code>xmin</code>, <code>ymin</code>, <code>xmax</code> and <code>ymax</code>coordinates of the bounding boxes, <code>xmin</code>and <code>ymin</code> being the coordinates of the upper-left corner.</td></tr><tr><td>scores_tensor</td><td>string</td><td>The name of the output tensor containing the scores for each label and box. It must be of size <code>N x K</code> where <code>K</code>is the number of labels in the recognition specification.</td></tr></tbody></table>

## Create a network

### Definition

Creates a new custom network after you have trained a model of your own on your infrastructure.

{% tabs %}
{% tab title="cURL" %}

```bash
POST https://api.deepomatic.com/v0.7/networks
```

{% endtab %}

{% tab title="Python" %}

```python
import os
from deepomatic.api.client import Client
client = Client(api_key=os.getenv('DEEPOMATIC_API_KEY'))

client.Network.create(...)
```

{% endtab %}
{% endtabs %}

### Arguments

<table><thead><tr><th width="192">Parameter</th><th width="92">Type</th><th width="96" align="center">Default</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>string</td><td align="center"></td><td>A short name for your network.</td></tr><tr><td>description</td><td>string</td><td align="center"></td><td>A longer description of your network.</td></tr><tr><td>metadata</td><td>object</td><td align="center">{}</td><td>A JSON field containing any kind of information that you may find interesting to store.</td></tr><tr><td>framework</td><td>string</td><td align="center"></td><td><p>A string describing which framework to use for your network. Possible values are:</p><ul><li><code>tensorflow-1.x</code>: Tensorflow: currently version 2.9</li></ul></td></tr><tr><td>preprocessing</td><td><a href="#pre-processing-object">object</a></td><td align="center"></td><td>A preprocessing object to describe how input data should be pre-processed.</td></tr><tr><td><em>&#x3C;additionnal-files></em></td><td>file</td><td align="center"></td><td>Extra files for network graph and weights, as well as mean files needed by the preprocessing. See below.</td></tr></tbody></table>

{% hint style="danger" %}
Once the network has been created, you cannot modify the `preprocessing` field anymore.
{% endhint %}

### Code sample

{% tabs %}
{% tab title="cURL" %}

```bash
# We download the Caffe a GoogleNet pre-trained network
curl -o /tmp/deploy.prototxt https://raw.githubusercontent.com/BVLC/caffe/master/models/bvlc_googlenet/deploy.prototxt
curl -o /tmp/snapshot.caffemodel http://dl.caffe.berkeleyvision.org/bvlc_googlenet.caffemodel
curl -o /tmp/caffe_ilsvrc12.tar.gz http://dl.caffe.berkeleyvision.org/caffe_ilsvrc12.tar.gz
tar -zxvf /tmp/caffe_ilsvrc12.tar.gz -C /tmp

# Now proceed to upload
curl https://api.deepomatic.com/v0.7/networks \
-H "X-API-KEY: ${DEEPOMATIC_API_KEY}" \
-F name='my new network' \
-F description='trained with more images' \
-F metadata='{"author": "me", "project": "Go to mars"}' \
-F framework='nv-caffe-0.x-mod' \
-F preprocessing='{"inputs": [{"tensor_name": "data","image": {"dimension_order":"NCHW", "target_size":"224x224", "resize_type":"SQUASH", "mean_file": "mean_file_1.binaryproto", "color_channels": "BGR", "pixel_scaling": 255.0, "data_type": "FLOAT32"}}], "batched_output": true}' \
-F deploy.prototxt=@/tmp/deploy.prototxt \
-F snapshot.caffemodel=@/tmp/snapshot.caffemodel \
-F mean_file_1.binaryproto=@/tmp/imagenet_mean.binaryproto
```

{% endtab %}

{% tab title="Python" %}

```python
import os
import sys
import tempfile
import shutil
import hashlib
import requests
import zipfile

from deepomatic.api.client import Client

if sys.version_info >= (3, 0):
    from urllib.request import urlretrieve
else:
    from urllib import urlretrieve

# Initialize the client
client = Client(api_key=os.getenv('DEEPOMATIC_API_KEY'))

# Helper function to download demo resources for the Caffe pre-trained networks
def download_file(url):
    _, ext = os.path.splitext(url)
    filename = os.path.join(tempfile.gettempdir(),
                            hashlib.sha1(url.encode()).hexdigest() + ext)
    print("Downloading {} to {}".format(url, filename))
    if os.path.exists(filename):  # avoid redownloading
        return filename
    r = requests.get(url, stream=True)
    r.raise_for_status()
    with open(filename, 'wb') as f:
        r.raw.decode_content = True
        shutil.copyfileobj(r.raw, f)
    return filename


# We download the Tensorflow Inception v3 pre-trained network
extract_dir = tempfile.gettempdir()
net_zip = download_file('https://s3-eu-west-1.amazonaws.com/deepo-public/run-demo-networks/imagenet-inception-v3/network.zip')
preproc_zip = download_file('https://s3-eu-west-1.amazonaws.com/deepo-public/run-demo-networks/imagenet-inception-v3/preprocessing.zip')

model_file_name = 'saved_model.pb'
variables_file_name = 'variables.index'
variables_data_file_name = 'variables.data-00000-of-00001'
mean_file_name = 'mean.proto.bin'

model_file = os.path.join(extract_dir, model_file_name)
mean_file = os.path.join(extract_dir, mean_file_name)
variables_file = os.path.join(extract_dir + '/variables/', variables_file_name)
variables_data_file = os.path.join(extract_dir + '/variables/', variables_data_file_name)

print("Extracting archive...")
if not os.path.exists(model_file):
    with zipfile.ZipFile(net_zip) as f:
        f.extractall(extract_dir)
if not os.path.exists(mean_file):
    with zipfile.ZipFile(preproc_zip) as f:
        f.extractall(extract_dir)

"""
Here, we specify the network preprocessing. Please refer to the documentation to see what each
field is used for.
"""
preprocessing = {
    "inputs": [
        {
            "tensor_name": "map/TensorArrayStack/TensorArrayGatherV3:0",
            "image": {
                "dimension_order": "NHWC",
                "target_size": "299x299",
                "resize_type": "CROP",
                "mean_file": mean_file_name,
                "color_channels": "BGR",
                "pixel_scaling": 2.0,
                "data_type": "FLOAT32"
            }
        }
    ],
    "batched_output": True
}

"""
We now register the three files needed by our network
"""
files = {
    model_file_name: open(model_file, 'rb'),
    variables_file_name: open(variables_file, 'rb'),
    variables_data_file_name: open(variables_data_file, 'rb'),
    mean_file_name: open(mean_file, 'rb')
}

"""
We now upload our new network via the 'client.Network().create(...)' network.
Please refere to the documentation for a description of each parameter.
"""
print("Uploading model to API...")
network = client.Network.create(name="My first network",
                                framework='tensorflow-1.x',
                                preprocessing=preprocessing,
                                files=files)
network_id = network['id']
print("Network ID = {}".format(network_id))
```

{% endtab %}
{% endtabs %}

### Network files

You will need to provide several additional files to create the network.

#### **TensorFlow files**

You need to specify at least one of those files for the **tensorflow-1.x** framework:

* `saved_model.pb`: the file that specifies the the network architecture.
* `saved_model.pbtxt`: same as above but serialised in it text format.

If the saved model does not embed the variables weights, you will need to specify additional files:

* `variables.data-00000-of-00001`: the file that specifies variables' weights. It is usually located in a *variables* directory. Numbers can change but must respect those of your original file.
* `variables.index`: the index of variables. It is usually located in a *variables* directory.

#### **Pre-processing files**

You might also include any additional file as required by you various input types, for exemple any mean file named as you like and whose name is referred by the `mean_file` parameter field of a [pre-processing object](#pre-processing-object) as long it has one of the supported extensions, see the [documentation](#network-object).

{% hint style="success" %}
Please refer to the **Saving mean files** code sample bellow to find out how to save you mean files before sending them to the API.
{% endhint %}

#### Saving mean files

In order to save numpy tensor means to files before sending them to the API, please proceed like this:

{% code title="Python" %}

```python
import numpy as np

# example mean file when `dimension_order == "HWC"` and H = 1, W = 1 and C = 3
# typically, your mean image as been compute on the training images and you already
# have this tensor available.
example_mean_file = np.ones((1, 1, 3))

# Save this mean to 'mean.npy'
with open('mean.npy', 'wb') as f:
    np.save(f, mean, allow_pickle=False)

# You can now use `"mean_file": "mean.npy"` in the preprocessing JSON
# {
#   ...
#   "mean_file": "mean.npy"
#   ...
# }
```

{% endcode %}

### Response

A [neural network object](#network-object), example response:

{% code title="JSON" %}

```javascript
{
    "id": 42,
    "name": "My first network",
    "description": "A neural network trained on some data",
    "task_id": 123,
    "update_date": "2018-02-16T16:37:25.148189Z",
    "metadata": {
        "any": "value"
    },
    "preprocessing": {
        "inputs": [
            {
                "tensor_name": "data",
                "image": {
                    "dimension_order": "NCHW",
                    "target_size": "224x224",
                    "resize_type": "SQUASH",
                    "mean_file": "mean.proto.bin",
                    "color_channels": "BGR",
                    "pixel_scaling": 255.0,
                    "data_type": "FLOAT32"
                }
            }
        ],
        "batched_output": true
    }
}
```

{% endcode %}

## List networks

### Code sample

Lists all public and private networks:

{% tabs %}
{% tab title="cURL" %}

```bash
# For public networks:
curl https://api.deepomatic.com/v0.7/networks/public \
-H "X-API-KEY: ${DEEPOMATIC_API_KEY}"

# For private networks:
curl https://api.deepomatic.com/v0.7/networks \
-H "X-API-KEY: ${DEEPOMATIC_API_KEY}"
```

{% endtab %}

{% tab title="Python" %}

```python
import os
from deepomatic.api.client import Client
client = Client(api_key=os.getenv('DEEPOMATIC_API_KEY'))

# For public networks:
for network in client.Network.list(public=True):
    print(network)

# For private networks:
for network in client.Network.list():
    print(network)
```

{% endtab %}
{% endtabs %}

### Response

A paginated list of responses.

<table><thead><tr><th width="146.33333333333331">Parameter</th><th width="139">Type</th><th>Description</th></tr></thead><tbody><tr><td>count</td><td>int</td><td>The total number of results.</td></tr><tr><td>next</td><td>string</td><td>The URL to the next page.</td></tr><tr><td>previous</td><td>string</td><td>The URL to the previous page.</td></tr><tr><td>results</td><td>array(<a href="#network-object">object</a>)</td><td>A list of your neural networks objects</td></tr></tbody></table>

Example response

{% code title="JSON" %}

```javascript
{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "name": "Alexnet",
            "description": "Alexnet",
            "task_id": "123",
            "update_date": "2018-02-16T13:45:36.078955Z",
            "metadata": {},
            "preprocessing": {
                "inputs": [
                    {
                        "tensor_name": "data",
                        "image": {
                            "dimension_order": "NCHW",
                            "target_size": "224x224",
                            "resize_type": "SQUASH",
                            "mean_file": "data_mean.proto.bin",
                            "color_channels": "BGR",
                            "pixel_scaling": 255.0,
                            "data_type": "FLOAT32"
                        }
                    }
                ],
                "batched_output": true
            }
        }
    ]
}
```

{% endcode %}

## Retrieve a network

### Definition

Retrieve a neural network by ID:

{% tabs %}
{% tab title="cURL" %}

```bash
# To retrieve a public network, use:
GET https://api.deepomatic.com/v0.7/networks/public/{NETWORK_ID}

# To retrieve your own network, use:
GET https://api.deepomatic.com/v0.7/networks/{NETWORK_ID}
```

{% endtab %}

{% tab title="Python" %}

```python
import os
from deepomatic.api.client import Client
client = Client(api_key=os.getenv('DEEPOMATIC_API_KEY'))

# {NETWORK_ID} may be a string for a public
# network or an integer for your own network.
client.Network.retrieve({NETWORK_ID})
```

{% endtab %}
{% endtabs %}

### Arguments

<table><thead><tr><th width="147">Parameter</th><th width="88">Type</th><th width="96">Default</th><th>Description</th></tr></thead><tbody><tr><td>network_id</td><td>int</td><td></td><td>The ID of the neural network to get.</td></tr></tbody></table>

### Code sample

{% tabs %}
{% tab title="cURL" %}

```bash
# For a public network:
curl https://api.deepomatic.com/v0.7/networks/public/imagenet-inception-v1 \
-H "X-API-KEY: ${DEEPOMATIC_API_KEY}"

# For a private network:
curl https://api.deepomatic.com/v0.7/networks/42 \
-H "X-API-KEY: ${DEEPOMATIC_API_KEY}"
```

{% endtab %}

{% tab title="Python" %}

```python
import os
from deepomatic.api.client import Client
client = Client(api_key=os.getenv('DEEPOMATIC_API_KEY'))

# For a public network:
client.Network.retrieve("imagenet-inception-v1")

# For a private network:
client.Network.retrieve(42)
```

{% endtab %}
{% endtabs %}

### Response

A [neural networks object](#network-object).

{% code title="JSON" %}

```javascript
{
    "id": 1,
    "name": "Alexnet",
    "description": "Alexnet",
    "task_id": "123",
    "update_date": "2018-02-16T13:45:36.078955Z",
    "metadata": {},
    "preprocessing": {
        "inputs": [
            {
                "tensor_name": "data",
                "image": {
                    "dimension_order": "NCHW",
                    "target_size": "224x224",
                    "resize_type": "SQUASH",
                    "mean_file": "data_mean.proto.bin",
                    "color_channels": "BGR",
                    "pixel_scaling": 255.0,
                    "data_type": "FLOAT32"
                }
            }
        ],
        "batched_output": true
    }
}
```

{% endcode %}

## Edit a network

### Definition

Updates the specified network by setting the values of the parameters passed. Any parameters not provided will be left unchanged.

This request accepts only the `name` and `metadata`arguments. Other values are immutable.

{% tabs %}
{% tab title="cURL" %}

```bash
PATCH https://api.deepomatic.com/v0.7/networks/{NETWORK_ID}
```

{% endtab %}

{% tab title="Python" %}

```python
import os
from deepomatic.api.client import Client
client = Client(api_key=os.getenv('DEEPOMATIC_API_KEY'))

network = client.Network.retrieve({NETWORK_ID})
network.update(...)
```

{% endtab %}
{% endtabs %}

### Arguments

<table><thead><tr><th width="136">Parameter</th><th width="104">Type</th><th width="116">Attributes</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>string</td><td>optionnal</td><td>A short name for your network.</td></tr><tr><td>description</td><td>string</td><td>optionnal</td><td>A longer description of your network.</td></tr><tr><td>metadata</td><td>object</td><td>optionnal</td><td>A JSON field containing any kind of information that you may find interesting to store.</td></tr></tbody></table>

### Code sample

{% tabs %}
{% tab title="cURL" %}

```bash
curl https://api.deepomatic.com/v0.7/networks/42 \
-H "X-API-KEY: ${DEEPOMATIC_API_KEY}" \
-d '{"name": "new name", "description":"new description"}' \
-X PATCH
```

{% endtab %}

{% tab title="Python" %}

```python
import os
from deepomatic.api.client import Client
client = Client(api_key=os.getenv('DEEPOMATIC_API_KEY'))

network = client.Network.retrieve(42)
network.update(
    name="new name",
    description="new description"
)
```

{% endtab %}
{% endtabs %}

### Response

A [neural networks object](#network-object).

## Delete a network

### Definition

Permanently deletes a network. This cannot be undone.

{% tabs %}
{% tab title="cURL" %}

```bash
DELETE https://api.deepomatic.com/v0.7/networks/{NETWORK_ID}
```

{% endtab %}

{% tab title="Python" %}

```python
import os
from deepomatic.api.client import Client
client = Client(api_key=os.getenv('DEEPOMATIC_API_KEY'))

network = client.Network.retrieve({NETWORK_ID})
network.delete()
```

{% endtab %}
{% endtabs %}

{% hint style="danger" %}
Attached resources such as **recognition versions** will also be suppressed.
{% endhint %}

### Arguments

<table><thead><tr><th width="134">Parameter</th><th width="113">Type</th><th width="99">Default</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>int</td><td></td><td>The Neural Network ID to delete.</td></tr></tbody></table>

### Code sample

{% tabs %}
{% tab title="cURL" %}

```bash
curl https://api.deepomatic.com/v0.7/networks/42 \
-H "X-API-KEY: ${DEEPOMATIC_API_KEY}" \
-X DELETE
```

{% endtab %}

{% tab title="Python" %}

```python
import os
from deepomatic.api.client import Client
client = Client(api_key=os.getenv('DEEPOMATIC_API_KEY'))

network = client.Network.retrieve(42)
network.delete()
```

{% endtab %}
{% endtabs %}

### Response

Return 204 (no content).
