Neural Network Code:
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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
#include <iostream> #include <vector> #include <cmath> #include <cstdlib> #include <ctime> const double LEARNING_RATE = 0.1; const int INPUT_SIZE = 2; const int HIDDEN_SIZE = 2; const int OUTPUT_SIZE = 1; const int NUM_EPOCHS = 10000; // Sigmoid activation function double sigmoid(double x) { return 1.0 / (1.0 + std::exp(-x)); } // Derivative of sigmoid function double sigmoid_derivative(double x) { return x * (1.0 - x); } // Neural Network class class NeuralNetwork { public: NeuralNetwork() { std::srand(std::time(0)); // Initialize weights for hidden layer and output layer for (int i = 0; i < INPUT_SIZE; ++i) { for (int j = 0; j < HIDDEN_SIZE; ++j) { hiddenWeights[i][j] = (std::rand() / double(RAND_MAX)) - 0.5; } } for (int j = 0; j < HIDDEN_SIZE; ++j) { for (int k = 0; k < OUTPUT_SIZE; ++k) { outputWeights[j][k] = (std::rand() / double(RAND_MAX)) - 0.5; } } // Initialize biases for (int j = 0; j < HIDDEN_SIZE; ++j) { hiddenBiases[j] = (std::rand() / double(RAND_MAX)) - 0.5; } for (int k = 0; k < OUTPUT_SIZE; ++k) { outputBiases[k] = (std::rand() / double(RAND_MAX)) - 0.5; } } // Forward pass std::vector<double> forward(const std::vector<double>& input) { // Compute hidden layer activations std::vector<double> hiddenLayer(HIDDEN_SIZE); for (int j = 0; j < HIDDEN_SIZE; ++j) { double sum = 0.0; for (int i = 0; i < INPUT_SIZE; ++i) { sum += input[i] * hiddenWeights[i][j]; } sum += hiddenBiases[j]; hiddenLayer[j] = sigmoid(sum); } // Compute output layer activations std::vector<double> outputLayer(OUTPUT_SIZE); for (int k = 0; k < OUTPUT_SIZE; ++k) { double sum = 0.0; for (int j = 0; j < HIDDEN_SIZE; ++j) { sum += hiddenLayer[j] * outputWeights[j][k]; } sum += outputBiases[k]; outputLayer[k] = sigmoid(sum); } return outputLayer; } // Backpropagation to update weights void train(const std::vector<std::vector<double>>& inputs, const std::vector<std::vector<double>>& targets) { for (int epoch = 0; epoch < NUM_EPOCHS; ++epoch) { for (size_t i = 0; i < inputs.size(); ++i) { // Forward pass std::vector<double> hiddenLayer(HIDDEN_SIZE); std::vector<double> outputLayer(OUTPUT_SIZE); // Compute hidden layer activations for (int j = 0; j < HIDDEN_SIZE; ++j) { double sum = 0.0; for (int k = 0; k < INPUT_SIZE; ++k) { sum += inputs[i][k] * hiddenWeights[k][j]; } sum += hiddenBiases[j]; hiddenLayer[j] = sigmoid(sum); } // Compute output layer activations for (int k = 0; k < OUTPUT_SIZE; ++k) { double sum = 0.0; for (int j = 0; j < HIDDEN_SIZE; ++j) { sum += hiddenLayer[j] * outputWeights[j][k]; } sum += outputBiases[k]; outputLayer[k] = sigmoid(sum); } // Backpropagation std::vector<double> outputErrors(OUTPUT_SIZE); for (int k = 0; k < OUTPUT_SIZE; ++k) { outputErrors[k] = targets[i][k] - outputLayer[k]; } std::vector<double> hiddenErrors(HIDDEN_SIZE); for (int j = 0; j < HIDDEN_SIZE; ++j) { hiddenErrors[j] = 0.0; for (int k = 0; k < OUTPUT_SIZE; ++k) { hiddenErrors[j] += outputErrors[k] * outputWeights[j][k]; } } // Update weights and biases for output layer for (int k = 0; k < OUTPUT_SIZE; ++k) { for (int j = 0; j < HIDDEN_SIZE; ++j) { double delta = LEARNING_RATE * outputErrors[k] * sigmoid_derivative(outputLayer[k]) * hiddenLayer[j]; outputWeights[j][k] += delta; } outputBiases[k] += LEARNING_RATE * outputErrors[k] * sigmoid_derivative(outputLayer[k]); } // Update weights and biases for hidden layer for (int j = 0; j < HIDDEN_SIZE; ++j) { for (int k = 0; k < INPUT_SIZE; ++k) { double delta = LEARNING_RATE * hiddenErrors[j] * sigmoid_derivative(hiddenLayer[j]) * inputs[i][k]; hiddenWeights[k][j] += delta; } hiddenBiases[j] += LEARNING_RATE * hiddenErrors[j] * sigmoid_derivative(hiddenLayer[j]); } } } } private: double hiddenWeights[INPUT_SIZE][HIDDEN_SIZE]; double outputWeights[HIDDEN_SIZE][OUTPUT_SIZE]; double hiddenBiases[HIDDEN_SIZE]; double outputBiases[OUTPUT_SIZE]; }; int main() { // Example dataset for training: XOR function std::vector<std::vector<double>> inputs = { {0.0, 0.0}, {0.0, 1.0}, {1.0, 0.0}, {1.0, 1.0} }; std::vector<std::vector<double>> targets = { {0.0}, {1.0}, {1.0}, {0.0} }; NeuralNetwork nn; nn.train(inputs, targets); std::cout << "Training completed.\n"; // Test the network for (const auto& input : inputs) { std::vector<double> output = nn.forward(input); std::cout << "Input: "; for (double val : input) { std::cout << val << ' '; } std::cout << "-> Output: " << output[0] << std::endl; } return 0; } |
Explanation:
- Activation Function:
sigmoid(double x)
: Sigmoid activation function which squashes the input to the range [0, 1].sigmoid_derivative(double x)
: Derivative of the sigmoid function used in backpropagation.
- Neural Network Class:
- Constructor: Initializes weights and biases randomly for both the hidden and output layers.
forward(const std::vector<double>& input)
: Performs a forward pass through the network to compute the output given an input.train(const std::vector<std::vector<double>>& inputs, const std::vector<std::vector<double>>& targets)
: Trains the network using backpropagation. It updates the weights and biases based on the error.
- Main Function:
- Defines a simple XOR dataset for training.
- Creates an instance of
NeuralNetwork
, trains it on the XOR dataset, and then tests the network with the training data to display the results.