From 5cae610328befb6fc1cfe851ace43231ad42faba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Lanzend=C3=B6rfer?= <leviathan@libresilicon.com> Date: Thu, 4 Jul 2024 22:41:34 +0100 Subject: [PATCH] Updat firmware --- firmware/firmware.c | 29 ++++++++++++++++++++------ firmware/include/rnn.h | 17 ++++++++-------- firmware/rnn.c | 46 +++++++++++++++++++++++------------------- 3 files changed, 57 insertions(+), 35 deletions(-) diff --git a/firmware/firmware.c b/firmware/firmware.c index bc8835f..29893e1 100644 --- a/firmware/firmware.c +++ b/firmware/firmware.c @@ -79,7 +79,9 @@ void main() TRAIN_STORE_LEARNING_RATE, TRAIN_STORE_DECAY_RATE, TRAIN_RUN_EPOCHS, - TRAIN_RUN_SINGLE_EPOCH + TRAIN_RUN_SINGLE_EPOCH, + // The fun part: Inference + PREDICT } command_mode; command_mode = START; @@ -93,13 +95,12 @@ void main() int new_value; // Training - uint32_t new_token; - uint32_t token_series[MAX_NUM_TOKENS]; + uint16_t new_token; + uint16_t token_series[MAX_NUM_TOKENS]; int token_counter = 0; uint32_t learning_rate = 0; uint32_t decay_rate = 0; uint32_t epoch_value = 0; - while(true) { @@ -145,6 +146,9 @@ void main() else if(!strcmp(msg,"TRAIN")) { command_mode = TRAIN; } + else if(!strcmp(msg,"PREDICT")) { + command_mode = PREDICT; + } break; case INIT: @@ -249,11 +253,15 @@ void main() case WRITE_LAYER_WEIGHTS: response = "END"; - if(value_write_counter<current_max_num_values) { + if((value_write_counter<current_max_num_values) && (current_layer_value == LAYER_VALUE_TYPE_WEIGHTS) ) { response = numstr; new_value = atoi(numstr); set_layer_weight(current_layer, neuron_idx, value_write_counter, new_value); value_write_counter++; + } else if (current_layer_value == LAYER_VALUE_TYPE_BIAS) { + response = numstr; + new_value = atoi(numstr); + set_layer_bias(current_layer, neuron_idx, new_value); } break; @@ -286,7 +294,7 @@ void main() new_token = atoi(numstr); token_series[token_counter] = new_token; token_counter++; - response = numstr; + response = itoa(token_counter, numstr, 10); } else { response = "END"; } @@ -316,6 +324,15 @@ void main() response = itoa(new_value, numstr, 10); break; + case PREDICT: + new_token = atoi(numstr); + for(int i=0;i<MSGBUF;i++) { + numstr[i]=0; + } + new_token = predict_next_token(new_token); + response = itoa(new_token, numstr, 10); + break; + } write_response(response); } diff --git a/firmware/include/rnn.h b/firmware/include/rnn.h index 9f8fa6d..943e91a 100644 --- a/firmware/include/rnn.h +++ b/firmware/include/rnn.h @@ -22,7 +22,8 @@ #define TRAINING_SINGLE_SHOT (1<<8) -#define ENCODER_WEIGHT_COUNT (NUM_INPUT_SYNAPSES+NUM_INPUT_NEURONS) +//#define ENCODER_WEIGHT_COUNT (NUM_INPUT_SYNAPSES+NUM_INPUT_NEURONS) +#define ENCODER_WEIGHT_COUNT (NUM_INPUT_SYNAPSES) #define HIDDEN_WEIGHT_COUNT (NUM_INPUT_NEURONS+NUM_HIDDEN_NEURONS_H) #define DECODER_WEIGHT_COUNT (NUM_HIDDEN_NEURONS_H) @@ -113,7 +114,7 @@ void set_layer_alpha( /* * Run inference */ -uint32_t predict_next_token(uint32_t token); +uint16_t predict_next_token(uint16_t token); /* * Run trainingg @@ -123,7 +124,7 @@ uint32_t predict_next_token(uint32_t token); * The mask is an XOR value of the bits of the supposed * output and what the network actually delivered */ -uint32_t mask_back_propgatation(uint32_t mask); +uint16_t mask_back_propgatation(uint16_t mask); /* * Access the LSFR output inside the ANN controller @@ -165,8 +166,8 @@ char* run_training( int num_epochs, uint32_t learning_rate_zero, uint32_t decay_rate, - uint32_t *xp, - uint32_t xn + uint16_t *xp, + int xi ); /* @@ -180,10 +181,10 @@ char* run_training( * Returns 0 when successful * Returns 1 when unsuccessful */ -uint32_t run_training_single_epoch( +int run_training_single_epoch( int epoch, uint32_t learning_rate_zero, uint32_t decay_rate, - uint32_t *xp, - uint32_t xi + uint16_t *xp, + int xi ); diff --git a/firmware/rnn.c b/firmware/rnn.c index b1e5f02..810774d 100644 --- a/firmware/rnn.c +++ b/firmware/rnn.c @@ -131,9 +131,9 @@ void set_layer_alpha( /* * Run inference */ -uint32_t predict_next_token(uint32_t token) +uint16_t predict_next_token(uint16_t token) { - uint32_t ret; + uint16_t ret; ann_cmd = RUN_INFERENCE|INFERENCE_START; ann_value1 = token; ann_cmd = RUN_INFERENCE|INFERENCE_FETCH; @@ -149,7 +149,7 @@ uint32_t predict_next_token(uint32_t token) * The mask is an XOR value of the bits of the supposed * output and what the network actually delivered */ -uint32_t mask_back_propgatation(uint32_t mask) +uint16_t mask_back_propgatation(uint16_t mask) { ann_cmd = RUN_TRAINING|TRAINING_SINGLE_SHOT; ann_value1 = mask; @@ -256,17 +256,18 @@ void set_bias_values(int bias) * Returns 0 when successful * Returns 1 when unsuccessful */ -uint32_t run_training_single_epoch( +int run_training_single_epoch( int epoch, uint32_t learning_rate_zero, uint32_t decay_rate, - uint32_t *xp, - uint32_t xi + uint16_t *xp, + int xi ) { + int error; int last_val; - uint32_t train_mask; - uint32_t y = xp[xi];; + uint16_t train_mask; + uint16_t y = xp[xi-1];; /* * Revert the LSTM states @@ -276,16 +277,17 @@ uint32_t run_training_single_epoch( * Put all the prior tokens of the time series * into the LSTM for reaching the state we wish to train on */ - for(int xpi=0; xpi<xi; xpi++) { + for(int xpi=0; xpi<xi-1; xpi++) { last_val = predict_next_token(xp[xpi]); } + /* * Check whether the network has already been trained * Set return value to zero and exit the loop if so */ train_mask = last_val ^ y; - if(!train_mask) { - return train_mask; + if(last_val==y) { + return 0; } /* * Determine the training mask my finding out which @@ -293,8 +295,11 @@ uint32_t run_training_single_epoch( */ set_alpha(learning_rate_zero/(1+(decay_rate*epoch))); mask_back_propgatation(train_mask); - - return train_mask; + + error = 0; + for(int i=0;i<32;i++) + error+=(train_mask>>i)&1; + return error; } @@ -313,13 +318,13 @@ int run_training_epochs( int num_epochs, uint32_t learning_rate_zero, uint32_t decay_rate, - uint32_t *xp, - uint32_t xi + uint16_t *xp, + int xi ) { int last_val; - uint32_t train_mask; - uint32_t y = xp[xi];; + uint16_t train_mask; + uint16_t y = xp[xi];; for(int epoch=0; epoch<num_epochs;epoch++) { if(run_training_single_epoch( @@ -349,8 +354,8 @@ char* run_training( int num_epochs, uint32_t learning_rate_zero, uint32_t decay_rate, - uint32_t *xp, - uint32_t xn + uint16_t *xp, + int xn ) { int last_val; @@ -367,7 +372,7 @@ char* run_training( * xi tells the functions where y is located in the array (x -> y) * xi must be xn-1 at most */ - for(uint32_t xi=1; xi<xn; xi++) { + for(int xi=1; xi<xn; xi++) { ret = run_training_epochs( num_epochs, learning_rate_zero, @@ -391,4 +396,3 @@ char* run_training( return msgbuf; } - -- GitLab