Commit fb765cdd authored by Marius Rockschies's avatar Marius Rockschies

first commit

parents
#include <avr/pgmspace.h>
#include "structure.h"
#include <stdbool.h>
#define PRINT(txt)Serial.println(F(txt)); // F("string") puts string in flash, but apparently they need more memory in flash than in ram
#define PRINT_VAL(txt,val)Serial.print(F(txt));Serial.print(F(":"));Serial.println(val);
void infer_input_layer(float *res,input_t * input,struct layer* thisLayer,bool last_round){
int16_t y_indptr_i;
int16_t y_indptr_i_p_1;
result_t entry;
int16_t k;
//PRINT_VAL("input[2] ",input[2])
//PRINT_VAL("indices_0 in fu",pgm_read_word(&thisLayer->indices[0]))
for(uint16_t i=0; i!=thisLayer->cols; i++) { // run over columns
y_indptr_i = pgm_read_word(&thisLayer->indptr[i]);
y_indptr_i_p_1 = pgm_read_word(&thisLayer->indptr[i + 1]);
entry=0;
k=0;
//PRINT_VAL("runs",y_indptr_i_p_1-y_indptr_i)
for(uint16_t j=0; j!=(y_indptr_i_p_1-y_indptr_i); j++)
{
entry+=pgm_read_float_near(&thisLayer->centroids[pgm_read_byte(&thisLayer->data[y_indptr_i+k])]) * pgm_read_float_near(&input[pgm_read_word(&thisLayer->indices[y_indptr_i+j])]);
k++;
}
res[i]=entry + pgm_read_float_near(&thisLayer->bias[i]);
if(last_round == false) res[i]= res[i]<0 ? 0 : res[i]; // ReLu (except last_round)
}
}
void infer_layer(float *res,input_t * input,struct layer* thisLayer,bool last_round){
int16_t y_indptr_i;
int16_t y_indptr_i_p_1;
result_t entry;
int16_t k;
//PRINT_VAL("input[2] ",input[2])
//PRINT_VAL("indices_0 in fu",pgm_read_word(&thisLayer->indices[0]))
for(uint16_t i=0; i!=thisLayer->cols; i++) { // run over columns
y_indptr_i = pgm_read_word(&thisLayer->indptr[i]);
y_indptr_i_p_1 = pgm_read_word(&thisLayer->indptr[i + 1]);
entry=0;
k=0;
//PRINT_VAL("runs",y_indptr_i_p_1-y_indptr_i)
for(uint16_t j=0; j!=(y_indptr_i_p_1-y_indptr_i); j++)
{
entry+=pgm_read_float_near(&thisLayer->centroids[pgm_read_byte(&thisLayer->data[y_indptr_i+k])]) * (input[pgm_read_word(&thisLayer->indices[y_indptr_i+j])]);
k++;
}
res[i]=entry + pgm_read_float_near(&thisLayer->bias[i]);
if(last_round == false) res[i]= res[i]<0 ? 0 : res[i]; // ReLu (except last_round)
}
}
uint16_t softmax(result_t *vec,uint16_t vec_size){
uint16_t max = 0;
result_t max_elem = vec[0];
PRINT_VAL("r_0",vec[0])
for(unsigned int i=1; i<vec_size; i++) {
PRINT_VAL("r_i",vec[i])
if(vec[i]>max_elem) {
max_elem=vec[i];
max=i;
}
}
return max;
}
uint16_t softmax_light(result_t *vec,uint16_t vec_size){
uint16_t max = 0;
result_t max_elem = vec[0];
for(unsigned int i=1; i<vec_size; i++) {
if(vec[i]>max_elem) {
max_elem=vec[i];
max=i;
}
}
return max;
}
void infer_input_layer_rel_per_col(float *res,input_t * input,struct layer* thisLayer,bool last_round){
int16_t y_indptr_i;
int16_t y_indptr_i_p_1;
result_t entry;
int16_t k;
uint16_t index_val;
uint16_t index_iter;
uint16_t offset;
y_indptr_i = pgm_read_byte(&thisLayer->indptr[0]);
for(uint16_t i=0; i!=thisLayer->cols; i++) { // run over columns
y_indptr_i_p_1 = pgm_read_byte(&thisLayer->indptr[i + 1]) + y_indptr_i;
index_iter = 0;
offset = y_indptr_i;
index_val = pgm_read_byte(&thisLayer->indices[offset]);
entry=0;
k=0;
PRINT_VAL("runs",(y_indptr_i_p_1-y_indptr_i))
for(uint16_t j=0; j!=(y_indptr_i_p_1-y_indptr_i); j++)
{
index_iter = index_iter + 1;
entry+=pgm_read_float_near(&thisLayer->centroids[pgm_read_byte(&thisLayer->data[y_indptr_i+k])])*pgm_read_float_near(&input[index_val]);
k++;
//the last item is 'array out of bounds'
//but it doesn't matter since we dont need then index_val anymore
//if((index_iter+offset)<thisLayer->num_elem)
{
index_val += pgm_read_byte(&thisLayer->indices[index_iter+offset]);
}
}
res[i]=entry + pgm_read_float_near(&thisLayer->bias[i]);
if(last_round == false) res[i]= res[i]<0 ? 0 : res[i]; // ReLu (except last_round)
y_indptr_i = y_indptr_i_p_1;
}
}
void infer_layer_rel_per_col(float *res,input_t * input,struct layer* thisLayer,bool last_round){
int16_t y_indptr_i;
int16_t y_indptr_i_p_1;
result_t entry;
int16_t k;
uint16_t index_val;
uint16_t index_iter;
uint16_t offset;
y_indptr_i = pgm_read_byte(&thisLayer->indptr[0]);
for(uint16_t i=0; i!=thisLayer->cols; i++) { // run over columns
y_indptr_i_p_1 = pgm_read_byte(&thisLayer->indptr[i + 1]) + y_indptr_i;
index_iter = 0;
offset = y_indptr_i;
index_val = pgm_read_byte(&thisLayer->indices[offset]);
entry=0;
k=0;
//PRINT_VAL("runs",(y_indptr_i_p_1-y_indptr_i))
for(uint16_t j=0; j!=(y_indptr_i_p_1-y_indptr_i); j++)
{
index_iter = index_iter + 1;
entry+=pgm_read_float_near(&thisLayer->centroids[pgm_read_byte(&thisLayer->data[y_indptr_i+k])]) * input[index_val];
k++;
//the last item is 'array out of bounds'
//but it doesn't matter since we dont need then index_val anymore
//if((index_iter+offset)<thisLayer->num_elem)
{
index_val += pgm_read_byte(&thisLayer->indices[index_iter+offset]);
}
}
res[i]=entry + pgm_read_float_near(&thisLayer->bias[i]);
if(last_round == false) res[i]= res[i]<0 ? 0 : res[i]; // ReLu (except last_round)
y_indptr_i = y_indptr_i_p_1;
}
}
void setup() {
Serial.begin(9600);
unsigned long start = millis(); //micros();
infer_model();
unsigned long end = millis(); //micros();
unsigned long delta = end - start;
PRINT_VAL("runtime in ms",delta)
}
void loop() {
//Serial.print(" \n loop ");
//delay(65537);// wait 65 sec
}
/* abs_indices
* typedef uint8_t data_t;
* typedef uint16_t indices_t;
* typedef uint16_t indptr_t;
*/
static const PROGMEM input_t input_vector[] = {
0.0400390625,0.044921875,0.0458984375,0.046875,0.0302734375,0.0498046875,0.0439453125,0.03125,0.02734375,0.0400390625,0.044921875,0.0458984375,0.046875,0.03125,0.048828125,0.0439453125,0.03125,0.02734375,0.0400390625,0.044921875,0.0458984375,0.046875,0.0302734375,0.0498046875,0.0439453125,0.03125,0.02734375,0.041015625,0.044921875,0.0458984375,0.046875,0.03125,0.048828125,0.0439453125,0.03125,0.02734375,0.0400390625,0.044921875,0.0458984375,0.0478515625,0.0302734375,0.0498046875,0.0439453125,0.03125,0.02734375,0.041015625,0.044921875,0.0458984375,0.046875,0.03125,0.048828125,0.0439453125,0.0302734375,0.02734375,0.0400390625,0.0458984375,0.046875,0.0478515625,0.03125,0.0498046875,0.04296875,0.03125,0.02734375,0.0419921875,0.044921875,0.046875,0.0478515625,0.0322265625,0.0498046875,0.0439453125,0.03125,0.0283203125,0.0390625,0.0390625,0.0341796875,0.046875,0.029296875,0.04296875,0.0439453125,0.03125,0.0263671875,0.0224609375,0.0185546875,0.015625,0.0341796875,0.017578125,0.0224609375,0.0390625,0.0224609375,0.0166015625,0.0087890625,0.009765625,0.009765625,0.0146484375,0.0078125,0.0107421875,0.0166015625,0.0087890625,0.0087890625,0.0078125,0.009765625,0.0087890625,0.0107421875,0.005859375,0.0107421875,0.0087890625,0.005859375,0.005859375,0.0078125,0.0087890625,0.0107421875,0.0107421875,0.005859375,0.01171875,0.009765625,0.005859375,0.0048828125,0.005859375,0.0078125,0.0107421875,0.0087890625,0.00390625,0.01171875,0.0078125,0.0048828125,0.0048828125,0.0146484375,0.0166015625,0.017578125,0.01171875,0.005859375,0.013671875,0.0078125,0.0048828125,0.0048828125,0.03125,0.0341796875,0.0361328125,0.029296875,0.0185546875,0.03125,0.01953125,0.01171875,0.0107421875,0.0361328125,0.0400390625,0.041015625,0.0400390625,0.0263671875,0.0419921875,0.03515625,0.0234375,0.01953125,0.0380859375,0.0419921875,0.04296875,0.04296875,0.0283203125,0.046875,0.0400390625,0.02734375,0.0234375,0.0380859375,0.04296875,0.044921875,0.044921875,0.029296875,0.046875,0.0419921875,0.0283203125,0.0244140625,0.0390625,0.04296875,0.044921875,0.0458984375,0.029296875,0.0478515625,0.04296875,0.029296875,0.0263671875
};
static const PROGMEM data_t l1data[] = {
38,63,32,38,38,66,38,66,22,71,1,66,71,48,5,50,71,33,61,50,22,5,47,5,48,31,48,5,66,69,34,5,1,61,32,34,71,49,50,61,37,50,28,34,26,49,61,45,30,64,31,66,37,49,11,6,31,37,35,41,66,39,49,7,39,33,6,22,38,3,14,20,17,21,24,13,51,63,28,27,40,31,3,66,66,53,25,19,7,68,71,43,4,58,40,14,5,53,8,5,64,37,22,15,15,26,47,22,22,49,48,48,48,38,61,34,32,15,5,22,5,69,15,37,64,12,66,53,14,45,54,32,17,28,56,64,5,64,56,12,26,7,56,24,65,62,50,28,44,66,27,32,24,44,63,65,54,32,70,17,65,14,1,51,45,2,45,65,28,0,66,25,9,27,44,57,28,25,31,46,59,26,55,4,31,27,7,53,50,63,66,48,61,71,26,63,26,48,1,48,22,1,61,69,33,64,49,34,33,15,69,26,63,66,63,63,34,1,49,47,0,7,56,31,17,48,53,71,47,62,69,8,50,51,34,12,62,48,0,42,47,48,7,56,26,0,42,36,54,16,46,15,40,24,4,1,71,51,48,8,42,18,55,7,4,30,23,43,10,53,29,49,67,62,6,26,15,38,12,5,51,65,24,53,51,36,51,56,42,14,42,24,5,5,71,38,5,63,50,26,26,66,50,26,71,26,61,15,26,71,61,48,15,61,69,15,49,50,34,37,22,71,6,33,52,42,37,69,15,20,12,15,47,69,30,47,22,47,64,32,49,64,41,60,50,11,69,35,66,60,52,6,48,40,5,53,38,42,14,42,14,36,8,51,8,53,65,45,53,56,36,8,58,8,8,36,17,8,36,51,17,28,28,58,51
};
static const PROGMEM indices_t l1indices[] = {
14,17,20,23,25,26,28,29,31,32,34,35,37,38,39,40,41,42,43,44,45,47,48,49,50,51,52,53,54,57,58,59,60,61,62,63,66,69,70,71,78,79,83,84,85,87,88,92,93,94,96,98,99,100,102,103,105,106,108,109,110,111,112,113,114,115,116,117,118,119,121,122,124,128,129,130,131,132,133,134,135,136,137,138,139,141,143,145,146,147,148,150,151,152,155,156,158,159,160,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,22,24,27,30,33,36,39,43,47,50,53,54,56,59,62,63,66,69,71,72,75,78,80,85,88,89,91,93,95,97,98,99,100,101,102,104,110,112,114,119,120,123,124,126,127,128,129,130,131,133,134,135,136,137,138,139,141,142,143,144,145,146,147,148,149,150,152,153,155,157,158,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,23,29,32,35,40,47,50,53,56,57,59,60,62,63,65,66,67,68,69,71,72,74,75,76,77,78,83,84,87,92,100,101,102,110,111,112,113,116,119,122,123,124,125,128,129,130,131,133,134,136,137,140,141,143,144,145,146,147,149,150,151,153,155,156,157,159,160,162,165,1,2,4,5,7,8,10,11,15,18,24,27,34,42,43,49,50,51,52,53,58,60,61,63,64,67,73,74,76,77,80,81,82,83,84,85,86,87,88,89,90,92,93,94,95,97,98,99,100,101,104,108,109,110,114,115,116,119,122,123,125,127,128,131,133,134,136,137,138,139,140,142,143,145,146,147,148,150,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179
};
static const PROGMEM indptr_t l1indptr[] = {
0,0,99,211,211,211,280,385
};
static const PROGMEM bias_t l1bias[] = {
0.0,0.8240007,0.27818334,-0.028505156,0.0,0.30571762,-0.019097645
};
static const PROGMEM centroids_t l1centroids[] = {
-0.6091326,1.1544632,-2.7181253,3.4637375,-1.490266,0.7174766,2.0116851,1.6114458,-1.0044917,-3.4502697,4.3674045,2.5887744,0.8943553,-2.2883925,-0.8186699,1.3342146,-1.9475718,-1.236646,-4.0898423,4.8740177,2.313604,3.102096,0.99249953,-3.0929885,-0.7399791,-2.4247787,0.7997777,-1.6614203,-1.1123214,4.0974493,1.8672209,1.5582743,0.5940207,1.2334217,1.07328,3.263013,-0.8960103,1.4106567,0.6364488,2.4818087,1.722732,2.7288141,-0.67012286,-3.3147504,-1.8397764,-1.2896681,-2.603855,1.5100975,0.9565257,1.2731769,0.8484981,-1.0603094,2.2010407,-0.9550365,-1.3544887,-2.2017088,-0.8578405,-3.543814,-1.1826918,-3.1856337,1.9388856,1.0333351,-1.4310844,0.6808479,1.115299,-0.7811437,0.75932217,2.412011,-2.02562,1.1820384,-2.4945176,0.93032146
};
static const PROGMEM data_t l2data[] = {
5,14,11,7,1,8,8,9,8,6,1,1,10,7,0,10,2,6,15,13,16,4,3,12
};
static const PROGMEM indices_t l2indices[] = {
2,5,6,2,5,6,2,5,6,2,5,6,1,2,5,1,2,5,6,6,1,2,5,6
};
static const PROGMEM indptr_t l2indptr[] = {
0,0,3,3,3,6,9,9,9,12,15,15,19,20,24
};
static const PROGMEM bias_t l2bias[] = {
0.0,1.1705769,0.0,-0.05115324,-0.30785635,0.4890881,0.0,0.0,0.5528819,0.35367748,0.0,0.6129579,2.1262314,-0.040457238
};
static const PROGMEM centroids_t l2centroids[] = {
-4.0959272,3.6488497,-0.9236635,0.94058615,-3.2587473,4.3805623,-2.2276075,2.8330913,-1.5195354,5.591604,1.5016177,-2.6098866,2.6273212,-1.1805472,0.6909139,3.4480338,1.1299152
};
static const PROGMEM data_t l3data[] = {
7,5,22,18,18,18,15,2,27,23,24,18,2,3,20,28,10,24,4,26,8,29,9,22,30,10,26,18,0,15,17,14,10,4,16,6,31,2,1,14,10,10,1,33,13,4,4,25,10,23,18,19,12,23,0,32,11,4,12,5,30,27,26,4,18,9,9,9,21,26,32,22,4,4
};
static const PROGMEM indices_t l3indices[] = {
1,4,5,8,11,13,1,4,8,9,12,13,1,4,5,9,11,12,4,8,9,12,1,4,5,9,13,4,5,9,11,12,1,4,5,8,9,12,13,1,4,5,8,11,13,1,4,8,9,11,12,13,1,4,5,9,12,13,4,5,8,9,11,12,4,8,11,12,13,1,5,8,9,12
};
static const PROGMEM indptr_t l3indptr[] = {
0,6,12,18,22,27,32,39,45,52,58,64,69,74
};
static const PROGMEM bias_t l3bias[] = {
0.86791193,-2.6828299,-0.36853942,-0.53019726,-0.6187474,0.21290475,-0.8195542,-0.10345005,-0.14564928,1.6003072,1.6979442,-0.25290063,0.81711614
};
static const PROGMEM centroids_t l3centroids[] = {
1.9296963,-4.2026935,-1.242715,-6.844192,0.8142515,-8.504618,-3.0173397,-5.5240264,-2.1782897,-0.5713181,1.2250775,2.6010547,-1.6944175,-6.0483313,1.4777825,-3.7521539,-4.5861135,-3.4082592,1.0037675,-2.5965583,-5.086602,-0.8844546,-2.3722873,-1.5356833,-3.9148102,-6.363704,0.61429125,1.5885859,2.1697469,-1.8899634,-1.0591958,1.7754889,-1.3746911,-8.653148
};
const struct layer l3 = {13,385,34,l3data,l3indices,l3indptr,l3bias,l3centroids,NULL};
const struct layer l2 = {14,24,17,l2data,l2indices,l2indptr,l2bias,l2centroids,&l3};
const struct layer l1 = {7,74,72,l1data,l1indices,l1indptr,l1bias,l1centroids,&l2};
model model_instance = {3,180,input_vector,&l1};
/* rel_indices_per_col
* typedef uint8_t data_t;
* typedef uint8_t indices_t;
* typedef uint8_t indptr_t;
*/
/*
static const PROGMEM input_t input_vector[] = {
0.0400390625,0.044921875,0.0458984375,0.046875,0.0302734375,0.0498046875,0.0439453125,0.03125,0.02734375,0.0400390625,0.044921875,0.0458984375,0.046875,0.03125,0.048828125,0.0439453125,0.03125,0.02734375,0.0400390625,0.044921875,0.0458984375,0.046875,0.0302734375,0.0498046875,0.0439453125,0.03125,0.02734375,0.041015625,0.044921875,0.0458984375,0.046875,0.03125,0.048828125,0.0439453125,0.03125,0.02734375,0.0400390625,0.044921875,0.0458984375,0.0478515625,0.0302734375,0.0498046875,0.0439453125,0.03125,0.02734375,0.041015625,0.044921875,0.0458984375,0.046875,0.03125,0.048828125,0.0439453125,0.0302734375,0.02734375,0.0400390625,0.0458984375,0.046875,0.0478515625,0.03125,0.0498046875,0.04296875,0.03125,0.02734375,0.0419921875,0.044921875,0.046875,0.0478515625,0.0322265625,0.0498046875,0.0439453125,0.03125,0.0283203125,0.0390625,0.0390625,0.0341796875,0.046875,0.029296875,0.04296875,0.0439453125,0.03125,0.0263671875,0.0224609375,0.0185546875,0.015625,0.0341796875,0.017578125,0.0224609375,0.0390625,0.0224609375,0.0166015625,0.0087890625,0.009765625,0.009765625,0.0146484375,0.0078125,0.0107421875,0.0166015625,0.0087890625,0.0087890625,0.0078125,0.009765625,0.0087890625,0.0107421875,0.005859375,0.0107421875,0.0087890625,0.005859375,0.005859375,0.0078125,0.0087890625,0.0107421875,0.0107421875,0.005859375,0.01171875,0.009765625,0.005859375,0.0048828125,0.005859375,0.0078125,0.0107421875,0.0087890625,0.00390625,0.01171875,0.0078125,0.0048828125,0.0048828125,0.0146484375,0.0166015625,0.017578125,0.01171875,0.005859375,0.013671875,0.0078125,0.0048828125,0.0048828125,0.03125,0.0341796875,0.0361328125,0.029296875,0.0185546875,0.03125,0.01953125,0.01171875,0.0107421875,0.0361328125,0.0400390625,0.041015625,0.0400390625,0.0263671875,0.0419921875,0.03515625,0.0234375,0.01953125,0.0380859375,0.0419921875,0.04296875,0.04296875,0.0283203125,0.046875,0.0400390625,0.02734375,0.0234375,0.0380859375,0.04296875,0.044921875,0.044921875,0.029296875,0.046875,0.0419921875,0.0283203125,0.0244140625,0.0390625,0.04296875,0.044921875,0.0458984375,0.029296875,0.0478515625,0.04296875,0.029296875,0.0263671875
};
static const PROGMEM data_t l1data[] = {
38,63,32,38,38,66,38,66,22,71,1,66,71,48,5,50,71,33,61,50,22,5,47,5,48,31,48,5,66,69,34,5,1,61,32,34,71,49,50,61,37,50,28,34,26,49,61,45,30,64,31,66,37,49,11,6,31,37,35,41,66,39,49,7,39,33,6,22,38,3,14,20,17,21,24,13,51,63,28,27,40,31,3,66,66,53,25,19,7,68,71,43,4,58,40,14,5,53,8,5,64,37,22,15,15,26,47,22,22,49,48,48,48,38,61,34,32,15,5,22,5,69,15,37,64,12,66,53,14,45,54,32,17,28,56,64,5,64,56,12,26,7,56,24,65,62,50,28,44,66,27,32,24,44,63,65,54,32,70,17,65,14,1,51,45,2,45,65,28,0,66,25,9,27,44,57,28,25,31,46,59,26,55,4,31,27,7,53,50,63,66,48,61,71,26,63,26,48,1,48,22,1,61,69,33,64,49,34,33,15,69,26,63,66,63,63,34,1,49,47,0,7,56,31,17,48,53,71,47,62,69,8,50,51,34,12,62,48,0,42,47,48,7,56,26,0,42,36,54,16,46,15,40,24,4,1,71,51,48,8,42,18,55,7,4,30,23,43,10,53,29,49,67,62,6,26,15,38,12,5,51,65,24,53,51,36,51,56,42,14,42,24,5,5,71,38,5,63,50,26,26,66,50,26,71,26,61,15,26,71,61,48,15,61,69,15,49,50,34,37,22,71,6,33,52,42,37,69,15,20,12,15,47,69,30,47,22,47,64,32,49,64,41,60,50,11,69,35,66,60,52,6,48,40,5,53,38,42,14,42,14,36,8,51,8,53,65,45,53,56,36,8,58,8,8,36,17,8,36,51,17,28,28,58,51
};
static const PROGMEM indices_t l1indices[] = {
14,3,3,3,2,1,2,1,2,1,2,1,2,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,3,1,1,1,1,1,1,3,3,1,1,7,1,4,1,1,2,1,4,1,1,2,2,1,1,2,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,2,1,2,4,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,2,1,1,3,1,2,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,3,3,3,3,3,4,4,3,3,1,2,3,3,1,3,3,2,1,3,3,2,5,3,1,2,2,2,2,1,1,1,1,1,2,6,2,2,5,1,3,1,2,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,1,2,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,23,6,3,3,5,7,3,3,3,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1,1,1,5,1,3,5,8,1,1,8,1,1,1,3,3,3,1,1,1,3,1,1,1,2,1,2,1,3,1,2,1,1,1,1,2,1,1,2,2,1,1,2,1,2,3,1,1,2,1,2,1,2,1,4,3,6,3,7,8,1,6,1,1,1,1,5,2,1,2,1,3,6,1,2,1,3,1,1,1,1,1,1,1,1,1,1,2,1,1,1,2,1,1,1,1,3,4,1,1,4,1,1,3,3,1,2,2,1,3,2,1,2,1,1,1,1,2,1,2,1,1,1,2,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
};
static const PROGMEM indptr_t l1indptr[] = {
0,0,99,112,0,0,69,105
};
static const PROGMEM bias_t l1bias[] = {
0.0,0.8240007,0.27818334,-0.028505156,0.0,0.30571762,-0.019097645
};
static const PROGMEM centroids_t l1centroids[] = {
-0.6091326,1.1544632,-2.7181253,3.4637375,-1.490266,0.7174766,2.0116851,1.6114458,-1.0044917,-3.4502697,4.3674045,2.5887744,0.8943553,-2.2883925,-0.8186699,1.3342146,-1.9475718,-1.236646,-4.0898423,4.8740177,2.313604,3.102096,0.99249953,-3.0929885,-0.7399791,-2.4247787,0.7997777,-1.6614203,-1.1123214,4.0974493,1.8672209,1.5582743,0.5940207,1.2334217,1.07328,3.263013,-0.8960103,1.4106567,0.6364488,2.4818087,1.722732,2.7288141,-0.67012286,-3.3147504,-1.8397764,-1.2896681,-2.603855,1.5100975,0.9565257,1.2731769,0.8484981,-1.0603094,2.2010407,-0.9550365,-1.3544887,-2.2017088,-0.8578405,-3.543814,-1.1826918,-3.1856337,1.9388856,1.0333351,-1.4310844,0.6808479,1.115299,-0.7811437,0.75932217,2.412011,-2.02562,1.1820384,-2.4945176,0.93032146
};
static const PROGMEM data_t l2data[] = {
5,14,11,7,1,8,8,9,8,6,1,1,10,7,0,10,2,6,15,13,16,4,3,12
};
static const PROGMEM indices_t l2indices[] = {
2,3,1,2,3,1,2,3,1,2,3,1,1,1,3,1,1,3,1,6,1,1,3,1
};
static const PROGMEM indptr_t l2indptr[] = {
0,0,3,0,0,3,3,0,0,3,3,0,4,1,4
};
static const PROGMEM bias_t l2bias[] = {
0.0,1.1705769,0.0,-0.05115324,-0.30785635,0.4890881,0.0,0.0,0.5528819,0.35367748,0.0,0.6129579,2.1262314,-0.040457238
};
static const PROGMEM centroids_t l2centroids[] = {
-4.0959272,3.6488497,-0.9236635,0.94058615,-3.2587473,4.3805623,-2.2276075,2.8330913,-1.5195354,5.591604,1.5016177,-2.6098866,2.6273212,-1.1805472,0.6909139,3.4480338,1.1299152
};
static const PROGMEM data_t l3data[] = {
7,5,22,18,18,18,15,2,27,23,24,18,2,3,20,28,10,24,4,26,8,29,9,22,30,10,26,18,0,15,17,14,10,4,16,6,31,2,1,14,10,10,1,33,13,4,4,25,10,23,18,19,12,23,0,32,11,4,12,5,30,27,26,4,18,9,9,9,21,26,32,22,4,4
};
static const PROGMEM indices_t l3indices[] = {
1,3,1,3,3,2,1,3,4,1,3,1,1,3,1,4,2,1,4,4,1,3,1,3,1,4,4,4,1,4,2,1,1,3,1,3,1,3,1,1,3,1,3,3,2,1,3,4,1,2,1,1,1,3,1,4,3,1,4,1,3,1,2,1,4,4,3,1,1,1,4,3,1,3
};
static const PROGMEM indptr_t l3indptr[] = {
0,6,6,6,4,5,5,7,6,7,6,6,5,5
};
static const PROGMEM bias_t l3bias[] = {
0.86791193,-2.6828299,-0.36853942,-0.53019726,-0.6187474,0.21290475,-0.8195542,-0.10345005,-0.14564928,1.6003072,1.6979442,-0.25290063,0.81711614
};
static const PROGMEM centroids_t l3centroids[] = {
1.9296963,-4.2026935,-1.242715,-6.844192,0.8142515,-8.504618,-3.0173397,-5.5240264,-2.1782897,-0.5713181,1.2250775,2.6010547,-1.6944175,-6.0483313,1.4777825,-3.7521539,-4.5861135,-3.4082592,1.0037675,-2.5965583,-5.086602,-0.8844546,-2.3722873,-1.5356833,-3.9148102,-6.363704,0.61429125,1.5885859,2.1697469,-1.8899634,-1.0591958,1.7754889,-1.3746911,-8.653148
};
const struct layer l3 = {13,385,34,l3data,l3indices,l3indptr,l3bias,l3centroids,NULL};
const struct layer l2 = {14,24,17,l2data,l2indices,l2indptr,l2bias,l2centroids,&l3};
const struct layer l1 = {7,74,72,l1data,l1indices,l1indptr,l1bias,l1centroids,&l2};
model model_instance = {3,180,input_vector,&l1};
*/
void infer_model(){
//PRINT("check pointer equivalence")
//PRINT_VAL(" model_instance.in",(int)model_instance.in)
//PRINT_VAL("input_vector",(int)input_vector)
struct layer* iter = model_instance.layers;
result_t* result1 = (result_t*) malloc(iter->cols*sizeof(result_t));
infer_input_layer(result1,model_instance.in,iter,false);
PRINT_VAL("result ",softmax(result1,iter->cols))
PRINT("")
iter=iter->next_layer;
result_t* result2= (result_t*) malloc(iter->cols*sizeof(result_t));
infer_layer(result2,result1,iter,false);
PRINT_VAL("result ",softmax(result2,iter->cols))
PRINT("")
free(result1);
iter=iter->next_layer;
result_t* result3= (result_t*) malloc(iter->cols*sizeof(result_t));
infer_layer(result3,result2,iter,true);
PRINT_VAL("result ",softmax(result3,iter->cols))
PRINT("")
free(result2);
// Implemented in a loop (Optimized but less readable)
/*
result_t* input;
result_t* result;
for(uint8_t i=0;i!=model_instance.n;i++)
{
result = (result_t*) malloc(iter->cols*sizeof(result_t));
if(i==0) infer_input_layer(result,model_instance.in,iter,false);
else if(i==model_instance.n-1)infer_layer(result,input,iter,true);
else infer_layer(result,input,iter,false);
if(i!=0)free(input);
if(i!=model_instance.n-1)
iter=iter->next_layer;
input=result;
}
PRINT_VAL("result ",softmax(result,iter->cols))
*/
}
#ifndef structure
#define structure
#include <stdint.h> // for precise types [e.g. uint16]
/* result_t = input_t = centroids_t = bias_t
* because calculation is always with these types
* result = activation function ( input * centroids + bias )
*/
typedef float calculation_t;
typedef calculation_t result_t;
typedef calculation_t bias_t;
typedef calculation_t centroids_t;
typedef calculation_t input_t;
typedef uint8_t data_t;
typedef uint16_t indices_t;
typedef uint16_t indptr_t;
struct layer {
uint16_t cols; // #indptr = #columns = #bias (we use csc and need therefore the number of columns)
uint16_t num_elem; // #data and #indices
uint16_t num_cen; // #centroids
data_t * data;
indices_t *indices;
indptr_t *indptr; // points to the beginning element of each column (we use csc and therefore indptr = column pointer)
bias_t *bias;
centroids_t *centroids;
struct layer* next_layer;
};//__attribute__((packed));
struct model {
uint8_t n; // numbers of layers
uint16_t in_size; // input layer size
input_t * in; // input layer
struct layer *layers; // list implemenation
};
#endif
#include "structure.h"
#include "mat.h"
#define PRINT(txt)Serial.println(F(txt)); // F("string") puts string in flash, but apparently they need more memory in flash than in ram
#define PRINT_VAL(txt,val)Serial.print(F(txt));Serial.print(F(":"));Serial.println(val);
void infer_input_layer(float *res,input_t * input,struct layer* thisLayer,bool last_round){
int16_t y_indptr_i;
int16_t y_indptr_i_p_1;
result_t entry;
int16_t k;
//PRINT_VAL("input[2] ",input[2])
//PRINT_VAL("indices_0 in fu",pgm_read_word(&thisLayer->indices[0]))
for(uint16_t i=0; i!=thisLayer->cols; i++) { // run over columns
y_indptr_i = pgm_read_word(&thisLayer->indptr[i]);
y_indptr_i_p_1 = pgm_read_word(&thisLayer->indptr[i + 1]);
entry=0;
k=0;
//PRINT_VAL("runs",y_indptr_i_p_1-y_indptr_i)
for(uint16_t j=0; j!=(y_indptr_i_p_1-y_indptr_i); j++)
{
entry+=pgm_read_float_near(&thisLayer->centroids[pgm_read_byte(&thisLayer->data[y_indptr_i+k])]) * pgm_read_float_near(&input[pgm_read_word(&thisLayer->indices[y_indptr_i+j])]);
k++;
}
res[i]=entry + pgm_read_float_near(&thisLayer->bias[i]);
if(last_round == false) res[i]= res[i]<0 ? 0 : res[i]; // ReLu (except last_round)
}
}
void infer_layer(float *res,input_t * input,struct layer* thisLayer,bool last_round){
int16_t y_indptr_i;
int16_t y_indptr_i_p_1;
result_t entry;
int16_t k;
//PRINT_VAL("input[2] ",input[2])
//PRINT_VAL("indices_0 in fu",pgm_read_word(&thisLayer->indices[0]))
for(uint16_t i=0; i!=thisLayer->cols; i++) { // run over columns
y_indptr_i = pgm_read_word(&thisLayer->indptr[i]);
y_indptr_i_p_1 = pgm_read_word(&thisLayer->indptr[i + 1]);
entry=0;
k=0;
//PRINT_VAL("runs",y_indptr_i_p_1-y_indptr_i)
for(uint16_t j=0; j!=(y_indptr_i_p_1-y_indptr_i); j++)
{
entry+=pgm_read_float_near(&thisLayer->centroids[pgm_read_byte(&thisLayer->data[y_indptr_i+k])]) * (input[pgm_read_word(&thisLayer->indices[y_indptr_i+j])]);
k++;
}
res[i]=entry + pgm_read_float_near(&thisLayer->bias[i]);
if(last_round == false) res[i]= res[i]<0 ? 0 : res[i]; // ReLu (except last_round)
}
}
uint16_t softmax(result_t *vec,uint16_t vec_size){
uint16_t max = 0;
result_t max_elem = vec[0];
PRINT_VAL("r_0",vec[0])
for(unsigned int i=1; i<vec_size; i++) {
PRINT_VAL("r_i",vec[i])
if(vec[i]>max_elem) {
max_elem=vec[i];
max=i;
}
}
return max;
}
uint16_t softmax_light(result_t *vec,uint16_t vec_size){
uint16_t max = 0;
result_t max_elem = vec[0];
for(unsigned int i=1; i<vec_size; i++) {
if(vec[i]>max_elem) {
max_elem=vec[i];
max=i;
}
}
return max;
}
void infer_model(){
struct layer* iter = model_instance.layers;
result_t* result1 = (result_t*) malloc(iter->cols*sizeof(result_t));
infer_input_layer(result1,model_instance.in,iter,false);
PRINT_VAL("result ",softmax_light(result1,iter->cols)) ;
PRINT("");
iter=iter->next_layer;
result_t* result2= (result_t*) malloc(iter->cols*sizeof(result_t));
infer_layer(result2,result1,iter,false);
PRINT_VAL("result ",softmax_light(result2,iter->cols)) ;
PRINT("");
free(result1);
iter=iter->next_layer;
result_t* result3= (result_t*) malloc(iter->cols*sizeof(result_t));
infer_layer(result3,result2,iter,true);
PRINT_VAL("result ",softmax_light(result3,iter->cols));
PRINT("") ;
free(result2);
}
void setup() {
Serial.begin(9600);
infer_model();
}
void loop() {
//Serial.print(" \n loop ");
//delay(65537);// wait 65 sec
}
/* AUTO GENERATED FILE
* BUILD 1560879328.889239
*/
#include "mat.h"
// currently not needed
/*
void init_mat(){
model_instance.n = 3;
model_instance.in_size = 180;
model_instance.in = (input_t* const) input_vector;
model_instance.layers = &l1;
}
*/
/*
l1.data = l1data;
l1.indices = l1indices;
l1.indptr = l1indptr;
l1.bias = l1bias;
l1.centroids = l1centroids;
l2.data = l2data;
l2.indices = l2indices;
l2.indptr = l2indptr;
l2.bias = l2bias;
l2.centroids = l2centroids;
l3.data = l3data;
l3.indices = l3indices;
l3.indptr = l3indptr;
l3.bias = l3bias;
l3.centroids = l3centroids;
*/
/* AUTO GENERATED FILE
* BUILD 1560879328.889239
*/
#ifndef matrices
#define matrices
#include "structure.h"
static const PROGMEM input_t input_vector[] = {
0.0400390625,0.044921875,0.0458984375,0.046875,0.0302734375,0.0498046875,0.0439453125,0.03125,0.02734375,0.0400390625,0.044921875,0.0458984375,0.046875,0.03125,0.048828125,0.0439453125,0.03125,0.02734375,0.0400390625,0.044921875,0.0458984375,0.046875,0.0302734375,0.0498046875,0.0439453125,0.03125,0.02734375,0.041015625,0.044921875,0.0458984375,0.046875,0.03125,0.048828125,0.0439453125,0.03125,0.02734375,0.0400390625,0.044921875,0.0458984375,0.0478515625,0.0302734375,0.0498046875,0.0439453125,0.03125,0.02734375,0.041015625,0.044921875,0.0458984375,0.046875,0.03125,0.048828125,0.0439453125,0.0302734375,0.02734375,0.0400390625,0.0458984375,0.046875,0.0478515625,0.03125,0.0498046875,0.04296875,0.03125,0.02734375,0.0419921875,0.044921875,0.046875,0.0478515625,0.0322265625,0.0498046875,0.0439453125,0.03125,0.0283203125,0.0390625,0.0390625,0.0341796875,0.046875,0.029296875,0.04296875,0.0439453125,0.03125,0.0263671875,0.0224609375,0.0185546875,0.015625,0.0341796875,0.017578125,0.0224609375,0.0390625,0.0224609375,0.0166015625,0.0087890625,0.009765625,0.009765625,0.0146484375,0.0078125,0.0107421875,0.0166015625,0.0087890625,0.0087890625,0.0078125,0.009765625,0.0087890625,0.0107421875,0.005859375,0.0107421875,0.0087890625,0.005859375,0.005859375,0.0078125,0.0087890625,0.0107421875,0.0107421875,0.005859375,0.01171875,0.009765625,0.005859375,0.0048828125,0.005859375,0.0078125,0.0107421875,0.0087890625,0.00390625,0.01171875,0.0078125,0.0048828125,0.0048828125,0.0146484375,0.0166015625,0.017578125,0.01171875,0.005859375,0.013671875,0.0078125,0.0048828125,0.0048828125,0.03125,0.0341796875,0.0361328125,0.029296875,0.0185546875,0.03125,0.01953125,0.01171875,0.0107421875,0.0361328125,0.0400390625,0.041015625,0.0400390625,0.0263671875,0.0419921875,0.03515625,0.0234375,0.01953125,0.0380859375,0.0419921875,0.04296875,0.04296875,0.0283203125,0.046875,0.0400390625,0.02734375,0.0234375,0.0380859375,0.04296875,0.044921875,0.044921875,0.029296875,0.046875,0.0419921875,0.0283203125,0.0244140625,0.0390625,0.04296875,0.044921875,0.0458984375,0.029296875,0.0478515625,0.04296875,0.029296875,0.0263671875
};
static const PROGMEM data_t l1data[] = {
38,63,32,38,38,66,38,66,22,71,1,66,71,48,5,50,71,33,61,50,22,5,47,5,48,31,48,5,66,69,34,5,1,61,32,34,71,49,50,61,37,50,28,34,26,49,61,45,30,64,31,66,37,49,11,6,31,37,35,41,66,39,49,7,39,33,6,22,38,3,14,20,17,21,24,13,51,63,28,27,40,31,3,66,66,53,25,19,7,68,71,43,4,58,40,14,5,53,8,5,64,37,22,15,15,26,47,22,22,49,48,48,48,38,61,34,32,15,5,22,5,69,15,37,64,12,66,53,14,45,54,32,17,28,56,64,5,64,56,12,26,7,56,24,65,62,50,28,44,66,27,32,24,44,63,65,54,32,70,17,65,14,1,51,45,2,45,65,28,0,66,25,9,27,44,57,28,25,31,46,59,26,55,4,31,27,7,53,50,63,66,48,61,71,26,63,26,48,1,48,22,1,61,69,33,64,49,34,33,15,69,26,63,66,63,63,34,1,49,47,0,7,56,31,17,48,53,71,47,62,69,8,50,51,34,12,62,48,0,42,47,48,7,56,26,0,42,36,54,16,46,15,40,24,4,1,71,51,48,8,42,18,55,7,4,30,23,43,10,53,29,49,67,62,6,26,15,38,12,5,51,65,24,53,51,36,51,56,42,14,42,24,5,5,71,38,5,63,50,26,26,66,50,26,71,26,61,15,26,71,61,48,15,61,69,15,49,50,34,37,22,71,6,33,52,42,37,69,15,20,12,15,47,69,30,47,22,47,64,32,49,64,41,60,50,11,69,35,66,60,52,6,48,40,5,53,38,42,14,42,14,36,8,51,8,53,65,45,53,56,36,8,58,8,8,36,17,8,36,51,17,28,28,58,51
};
static const PROGMEM indices_t l1indices[] = {
14,17,20,23,25,26,28,29,31,32,34,35,37,38,39,40,41,42,43,44,45,47,48,49,50,51,52,53,54,57,58,59,60,61,62,63,66,69,70,71,78,79,83,84,85,87,88,92,93,94,96,98,99,100,102,103,105,106,108,109,110,111,112,113,114,115,116,117,118,119,121,122,124,128,129,130,131,132,133,134,135,136,137,138,139,141,143,145,146,147,148,150,151,152,155,156,158,159,160,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,21,22,24,27,30,33,36,39,43,47,50,53,54,56,59,62,63,66,69,71,72,75,78,80,85,88,89,91,93,95,97,98,99,100,101,102,104,110,112,114,119,120,123,124,126,127,128,129,130,131,133,134,135,136,137,138,139,141,142,143,144,145,146,147,148,149,150,152,153,155,157,158,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,23,29,32,35,40,47,50,53,56,57,59,60,62,63,65,66,67,68,69,71,72,74,75,76,77,78,83,84,87,92,100,101,102,110,111,112,113,116,119,122,123,124,125,128,129,130,131,133,134,136,137,140,141,143,144,145,146,147,149,150,151,153,155,156,157,159,160,162,165,1,2,4,5,7,8,10,11,15,18,24,27,34,42,43,49,50