Created
May 28, 2016 11:27
-
-
Save dev-zzo/c5ba629a58d7abb4e4db0a885e47f8b9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <malloc.h> | |
struct _perceptron_t { | |
size_t weights_count; | |
float thfunc_param; | |
float weights[1]; | |
}; | |
typedef struct _perceptron_t perceptron_t; | |
static perceptron_t *perceptron_create(size_t input_size) | |
{ | |
perceptron_t *p; | |
size_t i; | |
p = (perceptron_t *)malloc(sizeof(perceptron_t) + (input_size - 1) * sizeof(p->weights[0])); | |
p->weights_count = input_size; | |
for (i = 0; i < input_size; ++i) { | |
p->weights[i] = 1.0f; | |
} | |
p->thfunc_param = 1.0f; | |
return p; | |
} | |
static float perceptron_apply(const perceptron_t *p, const float *inputs) | |
{ | |
float net = 0.0f; | |
size_t i; | |
for (i = 0; i < p->weights_count; ++i) { | |
net += p->weights[i] * inputs[i]; | |
} | |
return net >= p->thfunc_param ? 1.0f : 0.0f; | |
} | |
static void perceptron_learn(perceptron_t *p, float expected, float actual, const float *inputs, float learn_coeff) | |
{ | |
float correction; | |
size_t i; | |
correction = (actual - expected) * learn_coeff; | |
for (i = 0; i < p->weights_count; ++i) { | |
p->weights[i] -= correction * inputs[i]; | |
} | |
p->thfunc_param += correction; | |
} | |
#define INPUT_SIZE 3 | |
struct _training_data_t { | |
float output; | |
float inputs[INPUT_SIZE]; | |
}; | |
typedef struct _training_data_t training_data_t; | |
static training_data_t training_data[] = { | |
{ 1.0f, { 0.0f, 0.0f, 0.0f } }, | |
{ 1.0f, { 1.1f, 0.8f, 1.3f } }, | |
{ 1.0f, { 0.5f, 1.0f, 0.8f } }, | |
{ 0.0f, { 3.0f, 5.0f, 4.0f } }, | |
}; | |
static void perceptron_print(const perceptron_t *p) | |
{ | |
size_t i; | |
printf("Input weights:"); | |
for (i = 0; i < p->weights_count; ++i) { | |
printf(" %f", p->weights[i]); | |
} | |
printf("; Output thr.: %f\n", p->thfunc_param); | |
} | |
static void perceptron_train(perceptron_t *p, const training_data_t* training, size_t training_size) | |
{ | |
size_t sample_i; | |
int iteration; | |
int adjusted; | |
iteration = 1; | |
do { | |
printf("\nStarting training iteration %d.\n", iteration++); | |
perceptron_print(p); | |
printf("\n"); | |
adjusted = 0; | |
for (sample_i = 0; sample_i < training_size; ++sample_i) { | |
const training_data_t* sample; | |
float output; | |
sample = &training[sample_i]; | |
output = perceptron_apply(p, sample->inputs); | |
if (output != sample->output) { | |
printf(" Sample %d: output does not match; expected %f, got %f\n", sample_i, sample->output, output); | |
adjusted = 1; | |
perceptron_learn(p, sample->output, output, sample->inputs, 0.05); | |
perceptron_print(p); | |
} | |
else { | |
printf(" Sample %d: output matches\n", sample_i); | |
} | |
} | |
} while (adjusted); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
perceptron_t *p1; | |
p1 = perceptron_create(INPUT_SIZE); | |
perceptron_train(p1, training_data, sizeof(training_data) / sizeof(training_data[0])); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment