#include #include #include #include #include #include // #define DEBUG #define CHECK_SEED 69 #define BIAS 20 #define PASSES 999999 #define MIN(x, y) (((x) < (y)) ? (x) : (y)) #define WIDTH 60 #define HEIGHT 60 float input[HEIGHT][WIDTH]; float weights[HEIGHT][WIDTH]; int rand_range(int low, int high) { assert(low < high); return rand() % (high - low) + low; } void print_weight(); void fill_rect(int x0, int y0, int x1, int x2, float val); void fill_circle(int cx, int cy, int r, float val); void gen_rect(); void gen_circle(); void gen_shape(int opt) { if(opt == 0) gen_rect(); else if(opt == 1) gen_circle(); else assert(0); } void sub_weights(); void add_weights(); void manip_weights(int opt) { if(opt == 0) sub_weights(); else if(opt == 1) add_weights(); else assert(0); } float get_out() { float out_node = 0.0f; for(int i = 0; i < HEIGHT; i++) for(int j = 0; j < WIDTH; j++) { out_node += (weights[i][j] * input[i][j]); } return out_node; } void train() { memset(input, 0, HEIGHT*WIDTH*4); int opt = rand_range(0, 2); gen_shape(opt); float out = get_out(); if((out > BIAS) != opt) manip_weights(opt); #ifdef DEBUG printf("OUT %f", out); print_all(); #endif } int check() { memset(input, 0, HEIGHT*WIDTH*4); int opt = rand_range(0, 2); gen_shape(opt); float out = get_out(); if((out > BIAS) != opt) return 0; return 1; } int main() { memset(input, 0, HEIGHT*WIDTH*4); memset(weights, 0, HEIGHT*WIDTH*4); // ----- Train -----// time_t cur_time = time(0); puts("[INFO] Training model"); srand(time(0)); for(size_t i = 0; i < PASSES; i++) { train(); #ifdef DEBUG sleep(5); #endif } puts("[INFO] Training completed"); printf("[INFO] Operation took %ld seconds\n", time(0) - cur_time); // ----- Check ----- // cur_time = time(0); puts("[INFO] Checking model success rate"); srand(CHECK_SEED); int correct = 0; for(size_t i = 0; i < PASSES; i++) { correct += check(); } printf("[INFO] Model success rate is %f%%\n", ((float)correct/PASSES)*100); printf("[INFO] Operation took %ld seconds\n", time(0) - cur_time); print_weight(); return 0; } void print_weight() { puts("------------------------------------------------------------"); for(int i = 0; i < HEIGHT; i++) { for(int j = 0; j < WIDTH; j++) { if(weights[i][j] == 0.0f) printf("."); else if(weights[i][j] < 0.0f) printf("@"); else printf("#"); } puts(""); } puts("------------------------------------------------------------"); } void fill_rect(int x0, int y0, int x1, int y1, float val) { assert(x0 >= 0); assert(x1 >= 0); assert(x0 < WIDTH); assert(x1 < WIDTH); assert(y0 >= 0); assert(y1 >= 0); assert(y0 < HEIGHT); assert(y1 < HEIGHT); assert(x0 <= x1); assert(y0 <= y1); for(int y = y0; y <= y1; y++) { for(int x = x0; x <= x1; x++) { input[y][x] = val; } } } void fill_circle(int cx, int cy, int r, float val) { assert(r > 0); int x0 = cx - r; assert(x0 >= 0); assert(x0 < WIDTH); int y0 = cy - r; assert(y0 >= 0); assert(y0 < HEIGHT); int x1 = cx + r; assert(x1 >= 0); assert(x1 < WIDTH); int y1 = cy + r; assert(y1 >= 0); assert(y1 < HEIGHT); for (int y = y0; y <= y1; ++y) for (int x = x0; x <= x1; ++x) { int dx = x - cx; int dy = y - cy; if (dx*dx + dy*dy <= r*r) input[y][x] = val; } } void gen_rect() { int x0 = rand_range(0, WIDTH); int y0 = rand_range(0, HEIGHT); int x1 = rand_range(x0, WIDTH); int y1 = rand_range(y0, HEIGHT); fill_rect(x0, y0, x1, y1, 1.0f); } void gen_circle() { int cx = rand_range(2, WIDTH-2); int cy = rand_range(2, HEIGHT-2); int r = MIN( MIN(cx, WIDTH - cx), MIN(cy, HEIGHT - cy)); r = rand_range(1, r); fill_circle(cx, cy, r, 1.0f); } void sub_weights() { for(int i = 0; i < HEIGHT; i++) for(int j = 0; j < WIDTH; j++) { weights[i][j] -= input[i][j]; } } void add_weights() { for(int i = 0; i < HEIGHT; i++) for(int j = 0; j < WIDTH; j++) { weights[i][j] += input[i][j]; } }