Skip to content

Instantly share code, notes, and snippets.

@dev-zzo
Created May 28, 2016 11:27
Show Gist options
  • Save dev-zzo/c5ba629a58d7abb4e4db0a885e47f8b9 to your computer and use it in GitHub Desktop.
Save dev-zzo/c5ba629a58d7abb4e4db0a885e47f8b9 to your computer and use it in GitHub Desktop.
#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