-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathc_xor.c
119 lines (101 loc) · 3.99 KB
/
c_xor.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define INPUT_NEURONS 2
#define HIDDEN_NEURONS 2
#define OUTPUT_NEURONS 1
#define LEARNING_RATE 0.5
#define EPOCHS 500000
// Define the structure of a neuron
typedef struct {
double weights[INPUT_NEURONS];
double bias;
} Neuron;
// Define the structure of a network
typedef struct {
Neuron hidden[HIDDEN_NEURONS];
Neuron output;
} Network;
// Define the sigmoid function
double sigmoid(double x) {
return 1 / (1 + exp(-x));
}
// Define the derivative of the sigmoid function
double sigmoid_prime(double x) {
return sigmoid(x) * (1 - sigmoid(x));
}
// Define the feedforward function
double feedforward(Network* network, double inputs[INPUT_NEURONS], double hidden_outputs[HIDDEN_NEURONS]) {
for (int i = 0; i < HIDDEN_NEURONS; i++) {
hidden_outputs[i] = sigmoid(network->hidden[i].weights[0] * inputs[0] + network->hidden[i].weights[1] * inputs[1] + network->hidden[i].bias);
}
double output = sigmoid(network->output.weights[0] * hidden_outputs[0] + network->output.weights[1] * hidden_outputs[1] + network->output.bias);
return output;
}
// Define the train function
void train(Network* network, double inputs[INPUT_NEURONS], double target) {
// Feedforward
double hidden_outputs[HIDDEN_NEURONS];
double output = feedforward(network, inputs, hidden_outputs);
// Calculate output error
double output_error = output - target;
// Calculate output gradient
double output_gradient = output_error * sigmoid_prime(output);
// Adjust output weights and bias
for (int i = 0; i < HIDDEN_NEURONS; i++) {
network->output.weights[i] += output_gradient * hidden_outputs[i] * LEARNING_RATE;
}
network->output.bias += output_gradient * LEARNING_RATE;
// Calculate hidden errors and adjust hidden weights and biases
for (int i = 0; i < HIDDEN_NEURONS; i++) {
double hidden_error = network->output.weights[i] * output_error;
double hidden_gradient = hidden_error * hidden_outputs[i] * (1 - hidden_outputs[i]);
for (int j = 0; j < INPUT_NEURONS; j++) {
network->hidden[i].weights[j] += hidden_gradient * inputs[j] * LEARNING_RATE;
}
network->hidden[i].bias += hidden_gradient * LEARNING_RATE;
}
}
int main() {
// Initialize network
Network network = {0};
// Initialize random number generator
srand(time(NULL));
// Initialize weights and biases to random values
for (int i = 0; i < HIDDEN_NEURONS; i++) {
for (int j = 0; j < INPUT_NEURONS; j++) {
network.hidden[i].weights[j] = ((double)rand() / RAND_MAX) * 2 - 1;
}
network.hidden[i].bias = ((double)rand() / RAND_MAX) * 2 - 1;
network.output.weights[i] = ((double)rand() / RAND_MAX) * 2 - 1;
}
network.output.bias = (double)rand() / RAND_MAX;
// Define training data
double inputs[4][INPUT_NEURONS] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
double targets[4] = {0, 1, 1, 0};
// Train network
for (int i = 0; i < EPOCHS; i++) {
for (int j = 0; j < 4; j++) {
train(&network, inputs[j], targets[j]);
}
}
// Print final weights and biases
printf("Final hidden weights:\n");
for (int i = 0; i < HIDDEN_NEURONS; i++) {
printf("Neuron %d: %f, %f\n", i, network.hidden[i].weights[0], network.hidden[i].weights[1]);
}
printf("Final hidden biases:\n");
for (int i = 0; i < HIDDEN_NEURONS; i++) {
printf("Neuron %d: %f\n", i, network.hidden[i].bias);
}
printf("Final output weights: %f, %f\n", network.output.weights[0], network.output.weights[1]);
printf("Final output bias: %f\n", network.output.bias);
// Test network
printf("\nOutput from neural network after %d epochs:\n", EPOCHS);
double hidden_outputs[4][HIDDEN_NEURONS];
for (int i = 0; i < 4; i++) {
printf("XOR(%d, %d) = %f\n", (int)inputs[i][0], (int)inputs[i][1], feedforward(&network, inputs[i], hidden_outputs[i]));
}
return 0;
}