#include <LiquidCrystal_I2C.h>
// Инициализирую ЛСД дисплей с 4 строками и 20 столбцами
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
// class object_name(params);
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
void setup() {
lcd.init();
lcd.backlight();
}
void loop() {
// Массив целевых значений будет содержать 100 значений типа флоат (массив)
int n_points = 100;
float y_true[n_points];
// Заполняю массив игриков по формуле: x * 0.5 * (1 + noise) + (0.7 + noise)
for (int x = 0; x < n_points; x++){
y_true[x] = x * 0.5 * (random(0, 10) / 1000.0 + 1) + (0.7 + random(0, 10) / 1000.0);
}
// Инициализирую параметры регрессии, которые будут оптимизироваться градиентным спуском
float w = 0.05;
float b = 0.05;
float w_update = 0.0;
float b_update = 0.0;
// Скорость обучения градиентного спуска
float lr = 0.0001;
// Цикл обучения параметров регрессии (w и b) при помощи градиентного спуска
for (int i = 0; i < 1000; i++){
for (int x = 0; x < n_points; x++){
w_update = lr * 2 * (w * x + b - y_true[x]) * x;
b_update = lr * 2 * (w * x + b - y_true[x]);
w = w - w_update;
b = b - b_update;
}
// Меняю указатели на дисплее и вывожу информацию об обучаемых параметрах и истинных параметрах
lcd.setCursor(0, 0);
lcd.print("W coef=");
lcd.print(w);
lcd.setCursor(0, 1);
lcd.print("B coef=");
lcd.print(b);
lcd.setCursor(0, 2);
lcd.print("Epoch=");
lcd.print(i);
lcd.setCursor(0, 3);
lcd.print("True: W=");
lcd.print(0.5);
lcd.print(" B=");
lcd.print(0.7);
}
delay(10000);
}