#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;
}