# NeuralNetwork

This node runs neural inference on input data. Any OpenVINO neural networks can be run using this node, as long as the VPU
[supports all layers](https://docs.luxonis.com/software/ai-inference/conversion.md#supported-layers). This allows you to pick from
200+ pre-trained model from [Open Model Zoo](https://github.com/openvinotoolkit/open_model_zoo) and [DepthAI Model
Zoo](https://github.com/luxonis/depthai-model-zoo) and directly run it on the OAK device.

Neural network has to be in .blob format to be compatible with the VPU. Instructions on how to compile your neural network (NN) to
.blob can be found [here](https://docs.luxonis.com/software/ai-inference/conversion.md).

## How to place it

#### Python

```python
pipeline = dai.Pipeline()
nn = pipeline.create(dai.node.NeuralNetwork)
```

#### C++

```cpp
dai::Pipeline pipeline;
auto nn = pipeline.create<dai::node::NeuralNetwork>();
```

## Inputs and Outputs

## Passthrough mechanism

The passthrough mechanism is very useful when a node specifies its input to be non-blocking, where messages can be overwritten.
There we don't know on which message the node performed its operation (eg NN, was inference done on frame 25 or skipped 25 and
performed inference on 26). At the same time means that if: xlink and host input queues are blocking, and we receive both say
passthrough and output we can do a blocking get on both of those queues and be sure to always get matching frames. They might not
arrive at the same time, but both of them will arrive, and be in queue in correct spot to be taken out together.

## Usage

#### Python

```python
pipeline = dai.Pipeline()
nn = pipeline.create(dai.node.NeuralNetwork)
nn.setBlobPath(bbBlobPath)
cam.out.link(nn.input)

# Send NN out to the host via XLink
nnXout = pipeline.create(dai.node.XLinkOut)
nnXout.setStreamName("nn")
nn.out.link(nnXout.input)

with dai.Device(pipeline) as device:
  qNn = device.getOutputQueue("nn")

  nnData = qNn.get() # Blocking

  # NN can output from multiple layers. Print all layer names:
  print(nnData.getAllLayerNames())

  # Get layer named "Layer1_FP16" as FP16
  layer1Data = nnData.getLayerFp16("Layer1_FP16")

  # You can now decode the output of your NN
```

#### C++

```cpp
dai::Pipeline pipeline;
auto nn = pipeline.create<dai::node::NeuralNetwork>();
nn->setBlobPath(bbBlobPath);
cam->out.link(nn->input);

// Send NN out to the host via XLink
auto nnXout = pipeline.create<dai::node::XLinkOut>();
nnXout->setStreamName("nn");
nn->out.link(nnXout->input);

dai::Device device(pipeline);
// Start the pipeline
device.startPipeline();

auto qNn = device.getOutputQueue("nn");

auto nnData = qNn->get<dai::NNData>(); // Blocking

// NN can output from multiple layers. Print all layer names:
cout << nnData->getAllLayerNames();

// Get layer named "Layer1_FP16" as FP16
auto layer1Data = nnData->getLayerFp16("Layer1_FP16");

// You can now decode the output of your NN
```

## Examples of functionality

 * [Multi-Input Frame Concatenation](https://docs.luxonis.com/software/depthai/examples/concat_multi_input.md)
 * [Frame Normalization](https://docs.luxonis.com/software/depthai/examples/normalization_multi_input.md)
 * [DeeplabV3 experiment](https://github.com/luxonis/oak-examples/tree/master/gen2-deeplabv3_depth)
 * [Age/gender experiment](https://github.com/luxonis/oak-examples/blob/master/gen2-age-gender/main.py)
 * [EfficientDet demo](https://github.com/luxonis/oak-examples/blob/master/gen2-efficientDet/main.py)

## Reference

### depthai.node.NeuralNetwork(depthai.Node)

Kind: Class

NeuralNetwork node. Runs a neural inference on input data.

#### getNumInferenceThreads(self) -> int: int

Kind: Method

How many inference threads will be used to run the network

Returns:
Number of threads, 0, 1 or 2. Zero means AUTO

#### setBlob()

Kind: Method

#### setBlobPath(self, path: Path)

Kind: Method

Load network blob into assets and use once pipeline is started.

Throws:
Error if file doesn't exist or isn't a valid network blob.

Parameter ``path``:
Path to network blob

#### setNumInferenceThreads(self, numThreads: typing.SupportsInt)

Kind: Method

How many threads should the node use to run the network.

Parameter ``numThreads``:
Number of threads to dedicate to this node

#### setNumNCEPerInferenceThread(self, numNCEPerThread: typing.SupportsInt)

Kind: Method

How many Neural Compute Engines should a single thread use for inference

Parameter ``numNCEPerThread``:
Number of NCE per thread

#### setNumPoolFrames(self, numFrames: typing.SupportsInt)

Kind: Method

Specifies how many frames will be available in the pool

Parameter ``numFrames``:
How many frames will pool have

#### input

Kind: Property

Input message with data to be inferred upon Default queue is blocking with size
5

#### inputs

Kind: Property

Inputs mapped to network inputs. Useful for inferring from separate data sources
Default input is non-blocking with queue size 1 and waits for messages

#### out

Kind: Property

Outputs NNData message that carries inference results

#### passthrough

Kind: Property

Passthrough message on which the inference was performed.

Suitable for when input queue is set to non-blocking behavior.

#### passthroughs

Kind: Property

Passthroughs which correspond to specified input

### Need assistance?

Head over to [Discussion Forum](https://discuss.luxonis.com/) for technical support or any other questions you might have.
