In today’s technological era, Artificial Intelligence (AI) has become a hot topic. While many modern machine learning frameworks are written in high-level languages like Python, we can still implement some basic AI algorithms using C, especially neural networks. This article will introduce how to build a simple neural network in C and provide example code to help you understand its fundamental principles.
What is a Neural Network?
A neural network is an information processing system that mimics the way the human brain works, consisting of multiple nodes (or “neurons”) that interact through connections. Each connection has a weight value, and by adjusting these weights, we can train the model to recognize patterns and make predictions.
Neuron Structure
Each neuron receives input signals, sums them with weights, and then generates output signals through an activation function. Common activation functions include:
- Sigmoid function
- ReLU (Rectified Linear Unit)
- Tanh function
Basic Concepts
Before building our first simple neural network, we need to understand the following concepts:
- Input Layer: Receives external data.
- Hidden Layer: Performs computations and extracts features.
- Output Layer: Provides the final result.
Example Task
To demonstrate, we will create a small feedforward neural network with a single hidden layer to solve a binary classification problem, such as determining whether a point lies above a certain line.
Implementing a Simple Neural Network in C
Below is a code example of a simple feedforward neural network implemented in C:
#include <stdio.h>#include <stdlib.h>#include <math.h>#define INPUT_NODES 2 // Number of input nodes#define HIDDEN_NODES 2 // Number of hidden nodes#define OUTPUT_NODES 1 // Number of output nodes#define LEARNING_RATE 0.5 // Learning rate#define EPOCHS 10000 // Number of iterations
// Activation function - Sigmoid
double sigmoid(double x) { return 1 / (1 + exp(-x));}
// Derivative of the activation function - Derivative of Sigmoid
double sigmoid_derivative(double x) { return x * (1 - x);}
int main() { double input[4][INPUT_NODES] = { {0,0}, {0,1}, {1,0}, {1,1} }; // Input dataset (XOR) double output[4][OUTPUT_NODES] = { {0}, {1}, {1}, {0} }; // Output dataset
double hidden_weights[INPUT_NODES][HIDDEN_NODES]; double output_weights[HIDDEN_NODES][OUTPUT_NODES];
double hidden_layer[HIDDEN_NODES]; double output_layer[OUTPUT_NODES];
srand(time(NULL));
// Initialize weights to random values for(int i = 0; i < INPUT_NODES; i++) for(int j = 0; j < HIDDEN_NODES; j++) hidden_weights[i][j] = ((double)rand() / RAND_MAX);
for(int i = 0; i < HIDDEN_NODES; i++) for(int j = 0; j < OUTPUT_NODES; j++) output_weights[i][j] = ((double)rand() / RAND_MAX);
/* Start training */ for(int epoch=0; epoch<EPOCHS; epoch++) { int sample_index; for(sample_index=0; sample_index<4; sample_index++) {
/* Forward propagation */ for(int h=0; h<HIDDEN_NODES; h++) { hidden_layer[h]=hidden_weights[0][h]*input[sample_index][0]+hidden_weights[1][h]*input[sample_index][1]; hidden_layer[h]=sigmoid(hidden_layer[h]); }
for(int o=0;o<OUTPUT_NODES;o++){ output_layer[o]=output_weights[0][o]*hidden_layer[0]+output_weights[1][o]*hidden_layer[1]; output_layer[o]=sigmoid(output_layer[o]); }
/* Backward propagation */ double error_output; error_output=(output[sample_index][0]-output_layer[o]);
/* Update output layer weights */ for(int o=0;o<OUTPUT_NODES;o++){ for(int h=0;h<HIDDEN_NODES;h++){ output_weights[h][o]+=LEARNING_RATE*error_output*sigmoid_derivative(output_layer[o])*hidden_layer[h]; } }
/* Update hidden layer weights */ for(int h=0;h<HIDDEN_NODES;h++){ double error_hidden=sigmoid_derivative(hidden_layer[h])*error_output*output_weights[h][o]; for(int i=0;i<INPUT_NODES;i++){ hidden_weights[i][h]+=LEARNING_RATE*error_hidden*input[sample_index][i]; } } } }
printf("Training complete.\n"); printf("Final weights from input to hidden layer:\n"); for(int i=0;i<INPUT_NODES;i++){ printf("%lf ",hidden_weights[i][0]); }
printf("\nFinal weights from hidden to output layer:\n"); for(int o=0;o<OUTPUT_NODES;o++){ printf("%lf ",output_weights[0][o]); }
return EXIT_SUCCESS;}
Program Explanation
-
Initialization Phase:
- We define the number of input, hidden, and output nodes and initialize the random weights between them.
-
Forward Propagation:
- For each sample, calculate the values of the hidden layer and output layer, transforming them through the activation function.
-
Backward Propagation:
- Update the weights between connections based on the error to reduce prediction error. This process is repeated multiple times until the set number of iterations is reached or the error is sufficiently small.
Conclusion
This article demonstrated how to build a simple feedforward neural network using C, including the mechanisms of forward and backward propagation. This is just a small part of the field of machine learning, but I hope it helps you understand the basic concepts and their implementation methods. In practical applications, you may encounter more complex problems that require more powerful tools and libraries to handle. However, mastering the foundational knowledge is crucial for deeper research.