I'm implementing 'trainable neural network' (a code by Giorgi Butbaia ) in my ATTINY85 chip and can't fix this error.
what I implemented :
//Code by Giorgi Butbaia
//Define Weights
float w_111 = 0.4*random(256)/255.0 - 0.2;
float w_112 = 0.4*random(256)/255.0 - 0.2;
float w_113 = 0.4*random(256)/255.0 - 0.2;
float w_121 = 0.4*random(256)/255.0 - 0.2;
float w_122 = 0.4*random(256)/255.0 - 0.2;
float w_123 = 0.4*random(256)/255.0 - 0.2;
float b_21 = 0.4*random(256)/255.0 - 0.2;
float b_22 = 0.4*random(256)/255.0 - 0.2;
float b_23 = 0.4*random(256)/255.0 - 0.2;
float w_211 = 0.4*random(256)/255.0 - 0.2;
float w_221 = 0.4*random(256)/255.0 - 0.2;
float w_231 = 0.4*random(256)/255.0 - 0.2;
float b_31 = 0.4*random(256)/255.0 - 0.2;
//Define Helper Functions
float sigmoid(float z)
{
return 1.0/(1.0+exp(-z));
}
float forwardProp(float y_11, float y_12)
{
float y_21 = sigmoid(b_21 + w_111*y_11 + w_121*y_12);
float y_22 = sigmoid(b_22 + w_112*y_11 + w_122*y_12);
float y_23 = sigmoid(b_23 + w_113*y_11 + w_123*y_12);
float y_31 = sigmoid(b_31 + w_211*y_21 + w_221*y_22 + w_231*y_23);
return y_31;
}
float error(float T[], float y_11_d[], float y_12_d[], int dataSize)
{
//Initialize variables
float err = 0.0;
float y_31 = 0.0;
for(int i = 0; i < dataSize; i++)
{
y_31 = forwardProp(y_11_d, y_12_d);
err += exp(pow(y_31 - T,2));
}
return err - dataSize;
}
float train(float T[], float y_11_d[], float y_12_d[], int num_iter, float rate, boolean reinitializeWeights, int dataSize) //Returns error on dataset
{
//Serial.println("Initializing Variables");
if(reinitializeWeights)
{
w_111 = 0.4*random(256)/255.0 - 0.2;
w_112 = 0.4*random(256)/255.0 - 0.2;
w_113 = 0.4*random(256)/255.0 - 0.2;
w_121 = 0.4*random(256)/255.0 - 0.2;
w_122 = 0.4*random(256)/255.0 - 0.2;
w_123 = 0.4*random(256)/255.0 - 0.2;
b_21 = 0.4*random(256)/255.0 - 0.2;
b_22 = 0.4*random(256)/255.0 - 0.2;
b_23 = 0.4*random(256)/255.0 - 0.2;
w_211 = 0.4*random(256)/255.0 - 0.2;
w_221 = 0.4*random(256)/255.0 - 0.2;
w_231 = 0.4*random(256)/255.0 - 0.2;
b_31 = 0.4*random(256)/255.0 - 0.2;
}
//Initialize variables, to avoid reinitialization during each iteration
float dw_111 = 0.0;
float dw_112 = 0.0;
float dw_113 = 0.0;
float dw_121 = 0.0;
float dw_122 = 0.0;
float dw_123 = 0.0;
float db_21 = 0.0;
float db_22 = 0.0;
float db_23 = 0.0;
float dw_211 = 0.0;
float dw_221 = 0.0;
float dw_231 = 0.0;
float db_31 = 0.0;
float t_n = 0.0;
float y_11 = 0.0;
float y_12 = 0.0;
float y_21 = 0.0;
float y_22 = 0.0;
float y_23 = 0.0;
float y_31 = 0.0;
//Start training
//Serial.print("Starting Loop, dataSize: "); Serial.println(dataSize);
for(int iteration = 0; iteration < num_iter; iteration++)
{
//Serial.println("Iteration");
for(int i = 0; i < dataSize; i++)
{
//Gather data
t_n = T;
y_11 = y_11_d;
y_12 = y_12_d;
y_21 = sigmoid(b_21 + w_111*y_11 + w_121*y_12);
y_22 = sigmoid(b_22 + w_112*y_11 + w_122*y_12);
y_23 = sigmoid(b_23 + w_113*y_11 + w_123*y_12);
y_31 = sigmoid(b_31 + w_211*y_21 + w_221*y_22 + w_231*y_23);
//Compute derivatives
dw_111 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_211 * y_21*(1.0-y_21) * y_11;
dw_112 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_221 * y_22*(1.0-y_22) * y_11;
dw_113 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_231 * y_23*(1.0-y_23) * y_11;
dw_121 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_211 * y_21*(1.0-y_21) * y_12;
dw_122 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_221 * y_22*(1.0-y_22) * y_12;
dw_123 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_231 * y_23*(1.0-y_23) * y_12;
db_21 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_211 * y_21*(1.0-y_21);
db_22 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_221 * y_22*(1.0-y_22);
db_23 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * w_231 * y_23*(1.0-y_23);
dw_211 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * y_21;
dw_221 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * y_22;
dw_231 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31) * y_23;
db_31 = 2*(y_31 - t_n)*exp(pow((y_31 - t_n),2)) * y_31*(1.0-y_31);
//Update weights
w_111 -= rate*dw_111;
w_112 -= rate*dw_112;
w_113 -= rate*dw_113;
w_121 -= rate*dw_121;
w_122 -= rate*dw_122;
w_123 -= rate*dw_123;
b_21 -= rate*db_21;
b_22 -= rate*db_22;
b_23 -= rate*db_23;
w_211 -= rate*dw_211;
w_221 -= rate*dw_221;
w_231 -= rate*dw_231;
b_31 -= rate*db_31;
}
}
//Serial.println("Training has Finished");
return error(T, y_11_d, y_12_d, dataSize);
}
//Initialize arrays, with maximum number of entries 10
float T[20];
float y_11_d[20];
float y_12_d[20];
//TODO delete this:
//float T[] = {0.0, 1.0, 1.0, 0.0};
//float y_11_d[] = {0.0, 0.0, 1.0, 1.0};
//float y_12_d[] = {0.0, 1.0, 0.0, 1.0};
int y_11_P = A3; //Input neuron y_1^(1)
int y_12_P = A2; //Input neuron y_1^(2)
int y_31_IN = A1; //Input for the result t_n
int add_to_dataset = 1; //Training Mode: Adding Entry in dataset
int y_31_OUT = 1; //Acting Mode: Outputing the result of the forward propagation algorithm
int switchPin = 0;
boolean mode = true; //True corresponds to training mode, whereas false cooresponds to acting mode
void setup()
{
pinMode(switchPin, INPUT);
pinMode(y_11_P, INPUT);
pinMode(y_12_P, INPUT);
pinMode(add_to_dataset, INPUT);
}
//Debouncing variables
boolean prevAddState = LOW; //Previous state of the add_to_dataset pin, to avoid duplicates
boolean prevSwitchState = LOW; //Previous state of switchPin
int dataSize = 0;//since data is dynamically allocated sizeof method will not work
void loop()
{
if(mode) //Training Mode
{
/////////////////////////////////////////////////////////////////
///////////////// add_to_dataset pin ////////////////////////////
/////////////////////////////////////////////////////////////////
if(digitalRead(add_to_dataset) == HIGH && prevAddState == LOW)
{
dataSize++;
T[dataSize - 1] = analogRead(y_31_IN)/1023.0;
y_11_d[dataSize -1] = analogRead(y_11_P)/1023.0;
y_12_d[dataSize -1 ] = analogRead(y_12_P)/1023.0;
prevAddState = HIGH;
delay(500); //To avoid bouncing effect
}
else
{
prevAddState = LOW;
}
//////////////////////////////////////////////////////////////
/////////////////// Switch Pin ///////////////////////////////
//////////////////////////////////////////////////////////////
if(digitalRead(switchPin) == HIGH && prevSwitchState == LOW)
{
//Start the training process
if(dataSize != 0)
{
pinMode(y_31_OUT, OUTPUT); //Set DDR of y_31_OUT pin
analogWrite(y_31_OUT, 255.0);
train(T, y_11_d, y_12_d, 2000, 0.5, true, dataSize); //train without weight re-initialization
for(int i = 0; i < 5; i++) //Blinking is equivalent to switching mode
{
analogWrite(y_31_OUT, 255);
delay(500);
analogWrite(y_31_OUT, 0);
delay(500);
}
mode = false; //Switch Mode
}
prevSwitchState = HIGH;
delay(100); //To avoid bouncing effect
}
else {
prevSwitchState = LOW;
}
}
else {
//Forward Propagate during each iteration
analogWrite(y_31_OUT, 255.0*forwardProp(analogRead(y_11_P)/1023.0, analogRead(y_12_P)/1023.0));
if(digitalRead(switchPin) == HIGH && prevSwitchState == LOW)
{
//Indicate switch of mode by means of blinking LED
for(int i = 0; i < 5; i++)
{
analogWrite(y_31_OUT, 255);
delay(500);
analogWrite(y_31_OUT, 0);
delay(500);
}
mode = true; //Switch mode
pinMode(add_to_dataset, INPUT);
prevSwitchState = HIGH;
delay(500);
}
else
{
prevSwitchState = LOW;
}
}
}
//}
And this throws the following error when compiled:
Trainable_Neural_Net:160: error: unable to find a register to spill in class 'POINTER_REGS'
Trainable_Neural_Net:160: error: this is the insn:
(insn 269 268 271 5 (set (reg/v:SF 109 [ t_n ])
(mem:SF (post_inc:HI (reg:HI 150 [ ivtmp.129 ])) [2 MEM[base: _228, offset: 0B]+0 S4 A8])) C:\Users\user\Desktop\000?뿰援?\0怨쇳깘\?떊寃쎈쭩\?븘?몢?씠?끂肄붾뱶\Trainable_Neural_Net\Trainable_Neural_Net.ino:110 100 {*movsf}
(expr_list:REG_INC (reg:HI 150 [ ivtmp.129 ])
(nil)))