NatML
Search…
MLArrayFeature
class NatSuite.ML.Features.MLArrayFeature<T> : MLFeature, IMLFeature where T : unmanaged
This is a multidimensional array feature, a.k.a a tensor. Most models which accept tensors will accept an array feature in NatML.

Creating the Feature

The array feature can be created from a managed array (T[]) or native buffer (T*):

From a Managed Array

1
/// <summary>
2
/// Create an array feature.
3
/// </summary>
4
/// <param name="data">Feature data.</param>
5
MLArrayFeature (T[] data);
Copied!
An array feature can be created from a single array. When the feature is created with this constructor, its type will not have any shape information.
When a shapeless array feature is used for prediction with an MLModel, NatML will assume that its shape exactly matches what the model expects.
1
/// <summary>
2
/// Create an array feature.
3
/// </summary>
4
/// <param name="data">Feature data.</param>
5
/// <param name="shape">Feature shape.</param>
6
MLArrayFeature (T[] data, int[] shape);
Copied!
An array feature can be created with the feature data along with a corresponding shape. When this constructor is used, the element type of the feature is inferred from the generic type parameter T.
1
/// <summary>
2
/// Create an array feature.
3
/// </summary>
4
/// <param name="data">Feature data.</param>
5
/// <param name="type">Feature type.</param>
6
MLArrayFeature (T[] data, MLFeatureType type);
Copied!
In rare cases where it is useful to fully specify the feature type, the constructor above can be used.

From a Native Buffer

The array feature provides variants of the above constructors where the data argument is a typed native buffer instead of a managed array. These can be useful for making predictions on arrays from native code or external libraries like OpenCV:
1
/// <summary>
2
/// Create an array feature.
3
/// </summary>
4
/// <param name="data">Feature data.</param>
5
MLArrayFeature (T* data);
6
7
/// <summary>
8
/// Create an array feature.
9
/// </summary>
10
/// <param name="data">Feature data.</param>
11
/// <param name="shape">Feature shape.</param>
12
MLArrayFeature (T* data, int[] shape);
13
14
/// <summary>
15
/// Create an array feature.
16
/// </summary>
17
/// <param name="data">Feature data.</param>
18
/// <param name="type">Feature shape.</param>
19
MLArrayFeature (T* data, MLFeatureType type);
Copied!
The native buffer type T must be unmanaged.

From a Native Feature

1
/// <summary>
2
/// Create an array feature from a native feature.
3
/// Note that this does NOT take ownership of the native feature.
4
/// As such the native feature must be explicitly released by the client.
5
/// </summary>
6
/// <param name="nativeFeature">Backing native feature. This MUST be an array feature.</param>
7
MLArrayFeature (IntPtr nativeFeature);
Copied!
An array feature can be created from a native feature. This constructor is useful for working with output prediction data from a model when authoring a predictor:
1
// Make a prediction with one or more native input features
2
IMLModel model = ...;
3
IntPtr[] outputFeatures = model.Predict(...);
4
// Create an array feature from a native array feature
5
var feature = new MLArrayFeature<float>(outputFeatures[0]);
Copied!
This constructor creates a view of the native feature data, resulting in no allocations.
The native feature MUST be an array feature.

Inspecting the Feature

The array feature provides information about its shape.

Feature Type

1
/// <summary>
2
/// Feature type.
3
/// </summary>
4
MLFeatureType type { get; }
Copied!
Refer to the Inspecting the Feature section of the MLFeature class for more information.
The type is always an MLArrayType.

Feature Shape

1
/// <summary>
2
/// Feature shape.
3
/// </summary>
4
int[] shape { get; }
Copied!
The feature shape is a convenience property which provides the shape from the feature type.
The shape can be null if the feature was created with no shape.

Element Count

1
/// <summary>
2
/// Feature element count.
3
/// </summary>
4
int elementCount { get; }
Copied!
The element count is a convenience property which provides the element count from the feature type.
The elementCount will be zero when the feature does not have a shape.

Accessing Feature Data

Currently, the array feature provides accessors for reading feature data, but not writing feature data.

Multi-Indexing

1
/// <summary>
2
/// Get a value at a specified multi-index.
3
/// </summary>
4
/// <param name="idx">Multi-index.</param>
5
T this [params int[] idx] { get; }
Copied!
The array feature provides support for multi-indexing. This is a common pattern for working with tensors in machine learning:
1
// With an array feature
2
var feature = new MLArrayFeature<float>(...);
3
// You can index across multiple dimensions
4
var logit = feature[0,12,29,1];
Copied!
Multiple indexing requires the array feature to have a valid shape.
The array feature does not perform bounds checking for performance, so make sure not to index incorrectly.
The array feature also supports linear indexing, in which case it accesses the elements of the feature assuming a flat shape:
1
// You can also index linearly, disregarding the shape
2
var logit = feature[392];
Copied!

CopyTo

1
/// <summary>
2
/// Copy feature data to a buffer.
3
/// </summary>
4
/// <param name="array">Destination array.</param>
5
/// <param name="startIndex">Start index to copy into destination array.</param>
6
/// <param name="length">Number of elements to copy. Pass `0` to use destination array length.</param>
7
void CopyTo (T[] array, int startIndex = 0, int length = 0);
Copied!
The array feature can copy its data to a buffer of the same type. There is also an overload that takes a raw pointer for working with native buffers:
1
/// <summary>
2
/// Copy feature data to a buffer.
3
/// </summary>
4
/// <param name="buffer">Destination buffer.</param>
5
/// <param name="length">Number of elements to copy.</param>
6
public unsafe void CopyTo (T* buffer, int length);
Copied!

Viewing Operations

The array feature supports viewing operations. Each of these operations do not allocate any memory; they simply return a shallow feature that has the proper shape.

Permute

1
/// <summary>
2
/// Permute the dimensions of this array feature.
3
/// This operation is a generalization of the transpose operation.
4
/// </summary>
5
/// <param name="dims">Permuted dimensions.</param>
6
/// <returns>Array feature with permuted dimensions.</returns>
7
MLArrayFeature<T> Permute (params int[] dims);
Copied!
The array feature's dimensions can be permuted, allowing different dimensions to be swapped (like transposing):
1
// Create an array feature
2
var feature = new MLArrayFeature<float>(..., new [] { 3, 5 });
3
Debug.Log(feature.shape); // (3,5)
4
// Transpose it by permuting dimensions
5
var transposedFeature = feature.Permute(1, 0);
6
Debug.Log(transposedFeature.shape); // (5,3)
Copied!

View

1
/// <summary>
2
/// Create a view of this array feature with a different shape.
3
/// The element count of the new shape MUST match that of the feature.
4
/// </summary>
5
/// <param name="shape">New shape.</param>
6
/// <returns>Array feature with new shape.</returns>
7
MLArrayFeature<T> View (params int[] shape);
Copied!
The array feature supports creating a view of the feature data with a different shape:
1
// Create an array feature
2
var feature = new MLArrayFeature<float>(..., new [] { 5, 30 });
3
Debug.Log(feature.shape); // (5,30)
4
// View the feature with a different shape
5
var viewedFeature = feature.View(5, 10, 3);
6
Debug.Log(viewedFeature.shape); // (5,10,3)
Copied!
The element count of the view shape must match the element count of the feature.
Last modified 2mo ago