Advertisement
Miquel_Fuster

Basic perceptron

Dec 28th, 2023 (edited)
1,176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.35 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. // the perceptron
  6. typedef struct {
  7.     size_t inputs_count;
  8.     double learning_rate;
  9.     double bias;
  10.     double *weight;
  11.     double (*activation)(double aggregation);
  12. } perceptron;
  13.  
  14. // a basic activation function
  15. double step_function(double value) {
  16.     return value < 0.5? 0 : 1;
  17. }
  18.  
  19. // initialization of a perceptron
  20. void perceptron_init(perceptron *p, size_t inputs_count, double learning_rate, double (*activation_function)(double)) {
  21.     srand(time(NULL));
  22.  
  23.     p->bias = (double)rand() / (double)RAND_MAX; // between 0 and 1
  24.     p->weight = malloc(sizeof(double) * inputs_count);
  25.     p->inputs_count = inputs_count;
  26.     p->learning_rate = learning_rate;
  27.     p->activation = activation_function;
  28.  
  29.     // basic error handling
  30.     if(p->weight == NULL) {
  31.         p->inputs_count = 0;
  32.         return;
  33.     }
  34.  
  35.     for(size_t i = 0; i < inputs_count; ++i) {
  36.         p->weight[i] = (double)rand() / (double)RAND_MAX;
  37.     }
  38. }
  39.  
  40. // activation_function(bias + input[0] * weight[0] + input[1] * weight[1] + ...)
  41. double perceptron_predict(perceptron *p, double inputs[]) {
  42.     double aggregation = p->bias;
  43.     for(size_t i = 0; i < p->inputs_count; ++i) {
  44.         aggregation += inputs[i] * p->weight[i];
  45.     }
  46.     double output = p->activation(aggregation);
  47.     return output;
  48. }
  49.  
  50. // trains a perceptron with a dataset of inputs and the expected outpus for them
  51. void perceptron_train(perceptron *p, double **inputs, double *expected_outputs, size_t data_count) {
  52.     double y;
  53.     double error;
  54.     size_t row = 0;
  55.  
  56.     while(row < data_count) {
  57.         y = perceptron_predict(p, inputs[row]);
  58.         error = expected_outputs[row] - y;
  59.         if(error == 0) {
  60.             // if there is no error take the next group of inputs
  61.             ++row;
  62.         } else {
  63.             // if the error is set then recalculate the weights and go to da capo
  64.             p->bias += p->learning_rate * error;
  65.             for(int i = 0; i < p->inputs_count; ++i) {
  66.                 p->weight[i] += p->learning_rate * error * inputs[row][i];
  67.             }
  68.             row = 0;
  69.         }
  70.     }
  71. }
  72.  
  73. // print the internal state of a perceptron
  74. void perceptron_print(perceptron *p) {
  75.     printf("perceptron %p\n", p);
  76.     printf(" + learning rate: %lf\n", p->learning_rate);
  77.     printf(" + bias: %lf\n", p->bias);
  78.     for(size_t i = 0; i < p->inputs_count; ++i) {
  79.         printf(" + wheight[%u]: %lf\n", i, p->weight[i]);
  80.     }
  81. }
  82.  
  83. // frees the 'weight' dynamic array
  84. void perceptron_dispose(perceptron *n) {
  85.     free(n->weight);
  86. }
  87.  
  88. int main() {
  89.     // dataset for an 'and' gate
  90.     double *inputs[] = {
  91.         (double[]){ 0, 0 },
  92.         (double[]){ 0, 1 },
  93.         (double[]){ 1, 0 },
  94.         (double[]){ 1, 1 }
  95.     };
  96.     double outputs[] = { 0, 0, 0, 1 };
  97.  
  98.     // creating the perceptron
  99.     perceptron p;
  100.     perceptron_init(&p, 2, 0.1, step_function);
  101.     if(p.inputs_count == 0)
  102.         return EXIT_FAILURE;
  103.  
  104.     // training the perceptron
  105.     perceptron_train(&p, inputs, outputs, 4);
  106.     perceptron_print(&p);
  107.  
  108.     // demostration
  109.     for(int k=0; k<4; ++k) {
  110.         double x[] = {(k>>1) & 1, k & 1};
  111.         double s = perceptron_predict(&p, x);
  112.  
  113.         printf("%1.0lf y %1.0lf = %1.0lf\n", x[0], x[1], s);
  114.     }
  115.  
  116.     // liberation of resources
  117.     perceptron_dispose(&p);
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement