AIfES 2  2.0.0
ailayer_dense_default.h File Reference

Default implementation of the Dense layer . More...

Go to the source code of this file.

Typedefs

typedef struct ailayer_dense ailayer_dense_f32_t
 
typedef struct ailayer_dense ailayer_dense_q31_t
 
typedef struct ailayer_dense ailayer_dense_q7_t
 

Functions

ailayer_tailayer_dense_f32_default (ailayer_dense_f32_t *layer, ailayer_t *input_layer)
 Initializes and connect a Dense layer with the F32 default implementation. More...
 
ailayer_tailayer_dense_wt_f32_default (ailayer_dense_f32_t *layer, ailayer_t *input_layer)
 Initializes and connect a Dense layer with the F32 default implementation. More...
 
ailayer_tailayer_dense_q31_default (ailayer_dense_q31_t *layer, ailayer_t *input_layer)
 Initializes and connect a Dense layer with the Q31 default implementation. More...
 
ailayer_tailayer_dense_q7_default (ailayer_dense_q7_t *layer, ailayer_t *input_layer)
 Initializes and connect a Dense layer with the Q7 default implementation. More...
 
ailayer_tailayer_dense_wt_q7_default (ailayer_dense_q7_t *layer, ailayer_t *input_layer)
 Initializes and connect a Dense layer with the Q7 default implementation for transposed weights tensor. More...
 
void ailayer_dense_init_params_f32_default (ailayer_t *self)
 F32 default implementation of the ailayer.init_params function for the Conv2D layer More...
 
void ailayer_dense_init_params_q31_default (ailayer_t *self)
 Q31 default implementation of the ailayer.init_params function for the Conv2D layer More...
 
void ailayer_dense_quantize_q7_from_f32 (ailayer_dense_f32_t *f32_layer_ptr, ailayer_dense_q7_t *q7_layer_ptr)
 Convert a F32 dense layer to a Q7 representation. More...
 

Detailed Description

Default implementation of the Dense layer .

Version
2.2.0

Hardware independent implementations of the Dense layer in F32 , Q31 and Q7 data-type. For more information about the Dense layer refer to ailayer_dense.h.

Function Documentation

◆ ailayer_dense_f32_default()

ailayer_t* ailayer_dense_f32_default ( ailayer_dense_f32_t layer,
ailayer_t input_layer 
)

Initializes and connect a Dense layer with the F32 default implementation.

Example: Create the layer structure with pretrained weights:
In C:

// Use constant data only for inference. For training remove the const qualifier!!
const float weights_data_dense[] = {-10.1164f, -8.4212f, 5.4396f, 7.297f, -7.6482f, -9.0155f};
const float bias_data_dense[] = {-2.9653f, 2.3677f, -1.5968f};
ailayer_dense_f32_t dense_layer = {
.neurons = 3,
.weights.data = (float *) weights_data_dense,
.bias.data = (float *) bias_data_dense
};
General Dense layer structure.
Definition: ailayer_dense.h:71
uint32_t neurons
Layer neurons count (number of outputs).
Definition: ailayer_dense.h:80

In C, C++ and on Arduino:

// Use constant data only for inference. For training remove the const qualifier!!
const float weights_data_dense[] = {-10.1164f, -8.4212f, 5.4396f, 7.297f, -7.6482f, -9.0155f};
const float bias_data_dense[] = {-2.9653f, 2.3677f, -1.5968f};
ailayer_dense_f32_t dense_layer = AILAYER_DENSE_F32_M(3, weights_data_dense, bias_data_dense);

Example: Create the layer structure for automatic parameter distribution:
In C:

ailayer_dense_f32_t dense_layer = {
.neurons = 3
};

In C, C++ and on Arduino:

ailayer_dense_f32_t dense_layer = AILAYER_DENSE_F32_A(3);

Example: Initialize and connect the layer:

x = ailayer_dense_f32_default(&dense_layer, x);
ailayer_t * ailayer_dense_f32_default(ailayer_dense_f32_t *layer, ailayer_t *input_layer)
Initializes and connect a Dense layer with the F32 default implementation.
Parameters
*layerThe layer structure to initialize.
*input_layerThe prior layer.
Returns
The (successfully) initialized layer structure.

◆ ailayer_dense_init_params_f32_default()

void ailayer_dense_init_params_f32_default ( ailayer_t self)

F32 default implementation of the ailayer.init_params function for the Conv2D layer

Implementation of ailayer.init_params.

The function will initialize the weights and bias depending on the following activation function.

Activation function Weights-init Bias-init
None, tanh, logistic, softmax Glorot Zeros
ReLu and variants He Zeros
Parameters
*selfThe layer structure

◆ ailayer_dense_init_params_q31_default()

void ailayer_dense_init_params_q31_default ( ailayer_t self)

Q31 default implementation of the ailayer.init_params function for the Conv2D layer

Implementation of ailayer.init_params.

The function will initialize the weights and bias depending on the following activation function.

Activation function Weights-init Bias-init
None, tanh, logistic, softmax Glorot Zeros
ReLu and variants He Zeros
Parameters
*selfThe layer structure

◆ ailayer_dense_q31_default()

ailayer_t* ailayer_dense_q31_default ( ailayer_dense_q31_t layer,
ailayer_t input_layer 
)

Initializes and connect a Dense layer with the Q31 default implementation.

Example: Create the layer structure with pretrained weights:
In C:

// Use constant data only for inference. For training remove the const qualifier!!
// Weights (32 bit quantized)
const aimath_q31_params_t weights_q_params_dense = { .shift = 26, .zero_point = 0 };
const int32_t weights_data_dense[] = {-484203965, -294377834, -415073361, 234042792, 514922145, -408068817};
// Bias (32 bit quantized)
const aimath_q31_params_t bias_q_params_dense = { .shift = 26, .zero_point = 0 };
const int32_t bias_data_dense[] = {-91841604, 133375416, 185587399};
// Result (32 bit quantized)
const aimath_q31_params_t result_q_params_dense = { .shift = 24, .zero_point = 0 };
ailayer_dense_q31_t dense_layer = {
.neurons = 3,
.weights = {
.tensor_params = (aimath_q31_params_t *) &weights_q_params_dense,
.data = (int32_t *) weights_data_dense
},
.bias = {
.tensor_params = (aimath_q31_params_t *) &bias_q_params_dense,
.data = (int32_t *) bias_data_dense
},
.base.result.tensor_params = (aimath_q31_params_t *) &result_q_params_dense
};
Parameters used for the quantized Q31 values, used as property of a tensor.
Definition: aimath_q31.h:149
uint16_t shift
The scaling factor of the quantization (The total scale is calculated with )
Definition: aimath_q31.h:150

In C, C++ and on Arduino:

// Use constant data only for inference. For training remove the const qualifier!!
// Weights (32 bit quantized)
const aimath_q31_params_t weights_q_params_dense = { .shift = 26, .zero_point = 0 };
const int32_t weights_data_dense[] = {-484203965, -294377834, -415073361, 234042792, 514922145, -408068817};
// Bias (32 bit quantized)
const aimath_q31_params_t bias_q_params_dense = { .shift = 26, .zero_point = 0 };
const int32_t bias_data_dense[] = {-91841604, 133375416, 185587399};
// Result (32 bit quantized)
const aimath_q31_params_t result_q_params_dense = { .shift = 24, .zero_point = 0 };
ailayer_dense_q31_t dense_layer = AILAYER_DENSE_Q31_M(3,
weights_data_dense, &weights_q_params_dense,
bias_data_dense, &bias_q_params_dense,
&result_q_params_dense);

Example: Create the layer structure for automatic parameter distribution:
In C:

ailayer_dense_q31_t dense_layer = {
.neurons = 3
};

In C, C++ and on Arduino:

ailayer_dense_q31_t dense_layer = AILAYER_DENSE_Q31_A(3);

Example: Initialize and connect the layer:

x = ailayer_dense_q31_default(&dense_layer, x);
ailayer_t * ailayer_dense_q31_default(ailayer_dense_q31_t *layer, ailayer_t *input_layer)
Initializes and connect a Dense layer with the Q31 default implementation.
Parameters
*layerThe layer structure to initialize.
*input_layerThe prior layer.
Returns
The (successfully) initialized layer structure.

◆ ailayer_dense_q7_default()

ailayer_t* ailayer_dense_q7_default ( ailayer_dense_q7_t layer,
ailayer_t input_layer 
)

Initializes and connect a Dense layer with the Q7 default implementation.

Example: Create the layer structure with pretrained weights:
In C:

// Use constant data only for inference. For training remove the const qualifier!!
// Weights (8 bit quantized)
const aimath_q7_params_t weights_q_params_dense = { .shift = 3, .zero_point = 0 };
const int8_t weights_data_dense[] = {-81, -67, 44, 58, -61, -72};
// Bias (32 bit quantized)
const aimath_q31_params_t bias_q_params_dense = { .shift = 10, .zero_point = 0 };
const int32_t bias_data_dense[] = {-3036, 2425, -1635};
// Result (8 bit quantized)
const aimath_q7_params_t result_q_params_dense = { .shift = 3, .zero_point = 41 };
ailayer_dense_q7_t dense_layer = {
.neurons = 3,
.weights = {
.tensor_params = (aimath_q7_params_t *) &weights_q_params_dense,
.data = (int8_t *) weights_data_dense
},
.bias = {
.tensor_params = (aimath_q31_params_t *) &bias_q_params_dense,
.data = (int32_t *) bias_data_dense
},
.base.result.tensor_params = (aimath_q7_params_t *) &result_q_params_dense
};
Parameters used for the quantized Q7 values, used as property of a tensor.
Definition: aimath_q7.h:148
uint16_t shift
The scaling factor of the quantization (The total scale is calculated with )
Definition: aimath_q7.h:149

In C, C++ and on Arduino:

// Use constant data only for inference. For training remove the const qualifier!!
// Weights (8 bit quantized)
const aimath_q7_params_t weights_q_params_dense = { .shift = 3, .zero_point = 0 };
const int8_t weights_data_dense[] = {-81, -67, 44, 58, -61, -72};
// Bias (32 bit quantized)
const aimath_q31_params_t bias_q_params_dense = { .shift = 10, .zero_point = 0 };
const int32_t bias_data_dense[] = {-3036, 2425, -1635};
// Result (8 bit quantized)
const aimath_q7_params_t result_q_params_dense = { .shift = 3, .zero_point = 41 };
ailayer_dense_q7_t dense_layer = AILAYER_DENSE_Q7_M(3,
weights_data_dense, &weights_q_params_dense,
bias_data_dense, &bias_q_params_dense,
&result_q_params_dense);

Example: Create the layer structure for automatic parameter distribution:
In C:

ailayer_dense_q7_t dense_layer = {
.neurons = 3
};

In C, C++ and on Arduino:

ailayer_dense_q7_t dense_layer = AILAYER_DENSE_Q7_A(3);

Example: Initialize and connect the layer:

x = ailayer_dense_q7_default(&dense_layer, x);
ailayer_t * ailayer_dense_q7_default(ailayer_dense_q7_t *layer, ailayer_t *input_layer)
Initializes and connect a Dense layer with the Q7 default implementation.
Parameters
*layerThe layer structure to initialize.
*input_layerThe prior layer.
Returns
The (successfully) initialized layer structure.

◆ ailayer_dense_quantize_q7_from_f32()

void ailayer_dense_quantize_q7_from_f32 ( ailayer_dense_f32_t f32_layer_ptr,
ailayer_dense_q7_t q7_layer_ptr 
)

Convert a F32 dense layer to a Q7 representation.

The weights get 8 bit quantied and the bias gets 32 bit quantized for optimal results.

Quantizsation parameters for the previous layer need to be calculated before calling this function.

Parameters
*f32_layer_ptrThe source layer structure.
*q7_layer_ptrThe destination layer structure.

◆ ailayer_dense_wt_f32_default()

ailayer_t* ailayer_dense_wt_f32_default ( ailayer_dense_f32_t layer,
ailayer_t input_layer 
)

Initializes and connect a Dense layer with the F32 default implementation.

This implementation is the same as ailayer_dense_f32_default() but with a transposed weights matrix/tensor. This may lead to a speedup in runtime and makes hardware accelerator usage easier.

Example: Create the layer structure with pretrained weights:
In C:

// Use constant data only for inference. For training remove the const qualifier!!
const float weights_data_dense[] = {-10.1164f, 7.297f, -8.4212f, -7.6482f, 5.4396f, -9.0155f};
const float bias_data_dense[] = {-2.9653f, 2.3677f, -1.5968f};
ailayer_dense_f32_t dense_layer = {
.neurons = 3,
.weights.data = (float *) weights_data_dense,
.bias.data = (float *) bias_data_dense
};

In C, C++ and on Arduino:

// Use constant data only for inference. For training remove the const qualifier!!
const float weights_data_dense[] = {-10.1164f, 7.297f, -8.4212f, -7.6482f, 5.4396f, -9.0155f};
const float bias_data_dense[] = {-2.9653f, 2.3677f, -1.5968f};
ailayer_dense_f32_t dense_layer = AILAYER_DENSE_F32_M(3, weights_data_dense, bias_data_dense);

Example: Create the layer structure for automatic parameter distribution:
In C:

ailayer_dense_f32_t dense_layer = {
.neurons = 3
};

In C, C++ and on Arduino:

ailayer_dense_f32_t dense_layer = AILAYER_DENSE_F32_A(3);

Example: Initialize and connect the layer:

x = ailayer_dense_f32_wt_default(&dense_layer, x);
Parameters
*layerThe layer structure to initialize.
*input_layerThe prior layer.
Returns
The (successfully) initialized layer structure.

◆ ailayer_dense_wt_q7_default()

ailayer_t* ailayer_dense_wt_q7_default ( ailayer_dense_q7_t layer,
ailayer_t input_layer 
)

Initializes and connect a Dense layer with the Q7 default implementation for transposed weights tensor.

This implementation is the same as ailayer_dense_q7_default() but with a transposed weights matrix/tensor. This may lead to a speedup in runtime and makes hardware accelerator usage easier.

Example: Create the layer structure with pretrained weights:
In C:

// Use constant data only for inference. For training remove the const qualifier!!
// Weights (8 bit quantized)
const aimath_q7_params_t weights_q_params_dense = { .shift = 3, .zero_point = 0 };
const int8_t weights_data_dense[] = {-81, 58, -67, -61, 44, -72};
// Bias (32 bit quantized)
const aimath_q31_params_t bias_q_params_dense = { .shift = 10, .zero_point = 0 };
const int32_t bias_data_dense[] = {-3036, 2425, -1635};
// Result (8 bit quantized)
const aimath_q7_params_t result_q_params_dense = { .shift = 3, .zero_point = 41 };
ailayer_dense_q7_t dense_layer = {
.neurons = 3,
.weights = {
.tensor_params = (aimath_q7_params_t *) &weights_q_params_dense,
.data = (int8_t *) weights_data_dense
},
.bias = {
.tensor_params = (aimath_q31_params_t *) &bias_q_params_dense,
.data = (int32_t *) bias_data_dense
},
.base.result.tensor_params = (aimath_q7_params_t *) &result_q_params_dense
};

In C, C++ and on Arduino:

// Use constant data only for inference. For training remove the const qualifier!!
// Weights (8 bit quantized)
const aimath_q7_params_t weights_q_params_dense = { .shift = 3, .zero_point = 0 };
const int8_t weights_data_dense[] = {-81, 58, -67, -61, 44, -72};
// Bias (32 bit quantized)
const aimath_q31_params_t bias_q_params_dense = { .shift = 10, .zero_point = 0 };
const int32_t bias_data_dense[] = {-3036, 2425, -1635};
// Result (8 bit quantized)
const aimath_q7_params_t result_q_params_dense = { .shift = 3, .zero_point = 41 };
ailayer_dense_q7_t dense_layer = AILAYER_DENSE_Q7_M(3,
weights_data_dense, &weights_q_params_dense,
bias_data_dense, &bias_q_params_dense,
&result_q_params_dense);

Example: Create the layer structure for automatic parameter distribution:
In C:

ailayer_dense_q7_t dense_layer = {
.neurons = 3
};

In C, C++ and on Arduino:

ailayer_dense_q7_t dense_layer = AILAYER_DENSE_Q7_A(3);

Example: Initialize and connect the layer:

x = ailayer_dense_wt_q7_default(&dense_layer, x);
ailayer_t * ailayer_dense_wt_q7_default(ailayer_dense_q7_t *layer, ailayer_t *input_layer)
Initializes and connect a Dense layer with the Q7 default implementation for transposed weights ten...
Parameters
*layerThe layer structure to initialize.
*input_layerThe prior layer.
Returns
The (successfully) initialized layer structure.