CUDA Networks
Public Member Functions | List of all members
NeuralNetwork Class Reference

Represents a simple feedforward neural network with one hidden layer. More...

#include <neural_network.h>

Public Member Functions

 NeuralNetwork (int input_size, int hidden_size, int output_size)
 Construct a new NeuralNetwork object. More...
 
 ~NeuralNetwork ()
 Destroy the NeuralNetwork object. More...
 
void initialize ()
 Initialize the neural network parameters. More...
 
void forward (const Matrix &X)
 Perform forward propagation through the network. More...
 
void backward (const Matrix &X, const Matrix &Y)
 Perform backward propagation through the network. More...
 
void update_params (double learning_rate)
 Updates the network parameters based on computed gradients. More...
 
Vector get_predictions () const
 Get predictions from the output layer (A2) More...
 
double get_accuracy (const Matrix &Y) const
 Calculate the accuracy of predictions compared to true labels. More...
 
void gradient_descent (const Matrix &X, const Matrix &Y, double learning_rate, int epochs)
 Perform gradient descent to train the neural network. More...
 
double * get_W1_data () const
 Get the pointer to the W1 matrix data. More...
 
double * get_W2_data () const
 Get the pointer to the W2 matrix data. More...
 
double * get_b1_data () const
 Get the pointer to the b1 vector data. More...
 
double * get_b2_data () const
 Get the pointer to the b2 vector data. More...
 
std::pair< int, int > get_W1_dimensions () const
 Get the dimensions of the W1 matrix. More...
 
std::pair< int, int > get_W2_dimensions () const
 Get the dimensions of the W2 matrix. More...
 
int get_b1_size () const
 Get the size of the b1 vector. More...
 
int get_b2_size () const
 Get the size of the b2 vector. More...
 
Matrix get_DW1 () const
 Get the DW1 matrix. More...
 
double get_db1 () const
 Get the db1 scalar. More...
 
Matrix get_DW2 () const
 Get the DW2 matrix. More...
 
double get_db2 () const
 Get the db2 scalar. More...
 
double * get_A_data () const
 Get the pointer to the A matrix data (input matrix) More...
 
std::pair< int, int > get_A_dimensions () const
 Get the dimensions of the A matrix. More...
 
double * get_Z1_data () const
 Get the pointer to the Z1 matrix data (pre-activation of hidden layer) More...
 
std::pair< int, int > get_Z1_dimensions () const
 Get the dimensions of the Z1 matrix. More...
 
double * get_A1_data () const
 Get the pointer to the A1 matrix data (activation of hidden layer) More...
 
std::pair< int, int > get_A1_dimensions () const
 Get the dimensions of the A1 matrix. More...
 
double * get_Z2_data () const
 Get the pointer to the Z2 matrix data (pre-activation of output layer) More...
 
std::pair< int, int > get_Z2_dimensions () const
 Get the dimensions of the Z2 matrix. More...
 
double * get_A2_data () const
 Get the pointer to the A2 matrix data (activation of output layer) More...
 
std::pair< int, int > get_A2_dimensions () const
 Get the dimensions of the A2 matrix. More...
 

Detailed Description

Represents a simple feedforward neural network with one hidden layer.

Definition at line 16 of file neural_network.h.

Constructor & Destructor Documentation

◆ NeuralNetwork()

NeuralNetwork::NeuralNetwork ( int  input_size,
int  hidden_size,
int  output_size 
)

Construct a new NeuralNetwork object.

Parameters
input_sizeNumber of input features
hidden_sizeNumber of neurons in the hidden layer
output_sizeNumber of output classes

Definition at line 8 of file neural_network_constructor.cu.

11  : input_size(input_size),
12  hidden_size(hidden_size),
13  output_size(output_size),
14  W1(hidden_size, input_size),
15  b1(hidden_size),
16  W2(output_size, hidden_size),
17  b2(output_size),
18  A(input_size, 1),
19  Z1(hidden_size, 1),
20  A1(hidden_size, 1),
21  Z2(output_size, 1),
22  A2(output_size, 1),
23  DZ2(output_size, 1),
24  DW2(output_size, hidden_size),
25  db2(0.0),
26  DZ1(hidden_size, 1),
27  DW1(hidden_size, input_size),
28  db1(0.0) {
29  // Initialize the neural network parameters
30  initialize();
31 }
void initialize()
Initialize the neural network parameters.

◆ ~NeuralNetwork()

NeuralNetwork::~NeuralNetwork ( )

Destroy the NeuralNetwork object.

Definition at line 8 of file neural_network_destructor.cu.

8  {
9  // The destructor for Matrix and Vector objects will be called automatically
10  // to free the GPU memory
11 }

Member Function Documentation

◆ backward()

void NeuralNetwork::backward ( const Matrix X,
const Matrix Y 
)

Perform backward propagation through the network.

Parameters
XInput data matrix
YTrue labels matrix

Definition at line 8 of file neural_network_backward.cu.

8  {
9  // Get the number of training examples
10  int m = X.get_cols();
11 
12  // Compute the gradient of the output layer
13  // DZ2 = A2 - Y
14  DZ2 = A2.subtract(Y);
15  // std::cout << "Gradient of output layer DZ2:" << std::endl;
16  // DZ2.print(4);
17 
18  // Compute gradient for W2
19  // DW2 = 1/m * DZ2 * A1^T
20  DW2 = DZ2.multiply(A1.transpose());
21  DW2.divide_scalar(m);
22  // std::cout << "Gradient for W2:" << std::endl;
23  // DW2.print(4);
24 
25  // Compute gradient for b2
26  // db2 = 1/m * sum(DZ2)
27  db2 = DZ2.sum() / m;
28  // std::cout << "Gradient for b2: " << db2 << std::endl;
29 
30  // Compute the gradient of the hidden layer
31  // DZ1 = W2^T * DZ2 .* ReLU'(Z1)
32  Matrix W2_transpose = W2.transpose();
33  DZ1 = W2_transpose.multiply(DZ2);
34  Matrix Z1_relu_derivative = Z1.relu_derivative();
35  DZ1 = DZ1.multiply_elementwise(Z1_relu_derivative);
36  // std::cout << "Gradient of hidden layer DZ1:" << std::endl;
37  // DZ1.print(4);
38 
39  // Compute gradient for W1
40  // DW1 = 1/m * DZ1 * X^T
41  DW1 = DZ1.multiply(X.transpose());
42  DW1.divide_scalar(m);
43  // std::cout << "Gradient for W1:" << std::endl;
44  // DW1.print(4);
45 
46  // Compute gradient for b1
47  // db1 = 1/m * sum(DZ1)
48  db1 = DZ1.sum() / m;
49  // std::cout << "Gradient for b1: " << db1 << std::endl;
50 }
Represents a matrix with GPU-accelerated operations.
Definition: matrix.h:18
void divide_scalar(double scalar)
Divides all elements in the matrix by a scalar.
int get_cols() const
Get the number of columns in the matrix.
Matrix multiply_elementwise(const Matrix &other) const
Performs element-wise multiplication with another matrix.
Matrix transpose() const
Transposes the matrix and returns a new Matrix object.
Matrix subtract(const Matrix &other) const
Subtracts another matrix from this matrix.
Matrix multiply(const Matrix &other) const
Multiplies this matrix with another matrix.
Matrix relu_derivative() const
Applies the derivative of the ReLU activation function to the matrix.
double sum() const
Sums all elements in the matrix.
Definition: matrix_sum.cu:15

◆ forward()

void NeuralNetwork::forward ( const Matrix X)

Perform forward propagation through the network.

Parameters
XInput data matrix

Definition at line 8 of file neural_network_forward.cu.

8  {
9  // Store the input matrix
10  A = X.copy();
11  // std::cout << "Input matrix A:" << std::endl;
12  // A.print(4);
13 
14  // Compute the pre-activation of the hidden layer
15  Z1 = W1.multiply(A);
16  // std::cout << "Pre-activation of hidden layer Z1:" << std::endl;
17  // Z1.print(4);
18 
19  // Add biases to the pre-activation
20  Z1.add_vector(b1);
21  // std::cout << "Z1 after adding biases:" << std::endl;
22  // Z1.print(4);
23 
24  // Apply ReLU activation to the hidden layer
25  A1 = Z1.relu();
26  // std::cout << "Activation of hidden layer A1:" << std::endl;
27  // A1.print(4);
28 
29  // Compute the pre-activation of the output layer
30  Z2 = W2.multiply(A1);
31  // std::cout << "Pre-activation of output layer Z2:" << std::endl;
32  // Z2.print(4);
33 
34  // Add biases to the pre-activation
35  Z2.add_vector(b2);
36  // std::cout << "Z2 after adding biases:" << std::endl;
37  // Z2.print(4);
38 
39  // Apply softmax activation to the output layer
40  A2 = Z2.softmax();
41  // std::cout << "Activation of output layer A2:" << std::endl;
42  // A2.print(4);
43 }
void add_vector(const Vector &v)
Adds a vector to each column of the matrix.
Matrix copy() const
Creates a deep copy of the matrix.
Definition: matrix_copy.cu:59
Matrix relu() const
Applies the ReLU activation function to the matrix.
Definition: matrix_relu.cu:30
Matrix softmax() const
Applies the softmax function to the matrix column-wise.

◆ get_A1_data()

double* NeuralNetwork::get_A1_data ( ) const
inline

Get the pointer to the A1 matrix data (activation of hidden layer)

Returns
Pointer to the A1 matrix data on the device

Definition at line 177 of file neural_network.h.

177 { return A1.get_data(); }
double * get_data() const
Get the raw data pointer of the matrix.

◆ get_A1_dimensions()

std::pair<int, int> NeuralNetwork::get_A1_dimensions ( ) const
inline

Get the dimensions of the A1 matrix.

Returns
std::pair<int, int> containing rows and columns of A1

Definition at line 183 of file neural_network.h.

183 { return {A1.get_rows(), A1.get_cols()}; }
int get_rows() const
Get the number of rows in the matrix.

◆ get_A2_data()

double* NeuralNetwork::get_A2_data ( ) const
inline

Get the pointer to the A2 matrix data (activation of output layer)

Returns
Pointer to the A2 matrix data on the device

Definition at line 201 of file neural_network.h.

201 { return A2.get_data(); }

◆ get_A2_dimensions()

std::pair<int, int> NeuralNetwork::get_A2_dimensions ( ) const
inline

Get the dimensions of the A2 matrix.

Returns
std::pair<int, int> containing rows and columns of A2

Definition at line 207 of file neural_network.h.

207 { return {A2.get_rows(), A2.get_cols()}; }

◆ get_A_data()

double* NeuralNetwork::get_A_data ( ) const
inline

Get the pointer to the A matrix data (input matrix)

Returns
Pointer to the A matrix data on the device

Definition at line 153 of file neural_network.h.

153 { return A.get_data(); }

◆ get_A_dimensions()

std::pair<int, int> NeuralNetwork::get_A_dimensions ( ) const
inline

Get the dimensions of the A matrix.

Returns
std::pair<int, int> containing rows and columns of A

Definition at line 159 of file neural_network.h.

159 { return {A.get_rows(), A.get_cols()}; }

◆ get_accuracy()

double NeuralNetwork::get_accuracy ( const Matrix Y) const

Calculate the accuracy of predictions compared to true labels.

Parameters
YTrue labels matrix
Returns
Accuracy as a fraction of correct predictions

Definition at line 22 of file neural_network_get_accuracy.cu.

22  {
23  // Get predictions
24  Vector predictions = get_predictions();
25  // std::cout << "Predictions:" << std::endl;
26  // predictions.print(0);
27 
28  // Convert Y matrix to argmax form for comparison
29  Vector Y_argmax = Y.argmax();
30  // std::cout << "True labels (argmax):" << std::endl;
31  // Y_argmax.print(0);
32 
33  // Allocate device memory for correct count
34  int* d_correct_count;
35  cudaMalloc(&d_correct_count, sizeof(int));
36  cudaMemset(d_correct_count, 0, sizeof(int));
37 
38  // Define block and grid dimensions
39  int threadsPerBlock = 256;
40  int blocksPerGrid = (Y.get_cols() + threadsPerBlock - 1) / threadsPerBlock;
41 
42  // Launch kernel to calculate accuracy
43  calculate_accuracy_kernel<<<blocksPerGrid, threadsPerBlock>>>(
44  predictions.get_data(), Y_argmax.get_data(), Y.get_cols(), d_correct_count
45  );
46 
47  // Copy correct count from device to host
48  int h_correct_count;
49  cudaMemcpy(&h_correct_count, d_correct_count, sizeof(int), cudaMemcpyDeviceToHost);
50 
51  // Calculate accuracy
52  double accuracy = static_cast<double>(h_correct_count) / Y.get_cols();
53 
54  // Free device memory
55  cudaFree(d_correct_count);
56 
57  return accuracy;
58 }
Vector argmax() const
Computes the argmax of each column in the matrix.
Vector get_predictions() const
Get predictions from the output layer (A2)
Represents a vector with GPU-accelerated operations.
Definition: vector.h:13
double * get_data() const
Get the raw data pointer of the vector.

◆ get_b1_data()

double* NeuralNetwork::get_b1_data ( ) const
inline

Get the pointer to the b1 vector data.

Returns
Pointer to the b1 vector data on the device

Definition at line 93 of file neural_network.h.

93 { return b1.get_data(); }

◆ get_b1_size()

int NeuralNetwork::get_b1_size ( ) const
inline

Get the size of the b1 vector.

Returns
Size of the b1 vector

Definition at line 117 of file neural_network.h.

117 { return b1.get_rows(); }
int get_rows() const
Get the number of elements in the vector.

◆ get_b2_data()

double* NeuralNetwork::get_b2_data ( ) const
inline

Get the pointer to the b2 vector data.

Returns
Pointer to the b2 vector data on the device

Definition at line 99 of file neural_network.h.

99 { return b2.get_data(); }

◆ get_b2_size()

int NeuralNetwork::get_b2_size ( ) const
inline

Get the size of the b2 vector.

Returns
Size of the b2 vector

Definition at line 123 of file neural_network.h.

123 { return b2.get_rows(); }

◆ get_db1()

double NeuralNetwork::get_db1 ( ) const
inline

Get the db1 scalar.

Returns
The db1 scalar

Definition at line 135 of file neural_network.h.

135 { return db1; }

◆ get_db2()

double NeuralNetwork::get_db2 ( ) const
inline

Get the db2 scalar.

Returns
The db2 scalar

Definition at line 147 of file neural_network.h.

147 { return db2; }

◆ get_DW1()

Matrix NeuralNetwork::get_DW1 ( ) const
inline

Get the DW1 matrix.

Returns
The DW1 matrix

Definition at line 129 of file neural_network.h.

129 { return DW1; }

◆ get_DW2()

Matrix NeuralNetwork::get_DW2 ( ) const
inline

Get the DW2 matrix.

Returns
The DW2 matrix

Definition at line 141 of file neural_network.h.

141 { return DW2; }

◆ get_predictions()

Vector NeuralNetwork::get_predictions ( ) const

Get predictions from the output layer (A2)

Returns
Vector containing the predicted class indices

Definition at line 7 of file neural_network_get_predictions.cu.

7  {
8  // Get the argmax of A2 along axis 0 (column-wise)
9  return A2.argmax();
10 }

◆ get_W1_data()

double* NeuralNetwork::get_W1_data ( ) const
inline

Get the pointer to the W1 matrix data.

Returns
Pointer to the W1 matrix data on the device

Definition at line 81 of file neural_network.h.

81 { return W1.get_data(); }

◆ get_W1_dimensions()

std::pair<int, int> NeuralNetwork::get_W1_dimensions ( ) const
inline

Get the dimensions of the W1 matrix.

Returns
std::pair<int, int> containing rows and columns of W1

Definition at line 105 of file neural_network.h.

105 { return {W1.get_rows(), W1.get_cols()}; }

◆ get_W2_data()

double* NeuralNetwork::get_W2_data ( ) const
inline

Get the pointer to the W2 matrix data.

Returns
Pointer to the W2 matrix data on the device

Definition at line 87 of file neural_network.h.

87 { return W2.get_data(); }

◆ get_W2_dimensions()

std::pair<int, int> NeuralNetwork::get_W2_dimensions ( ) const
inline

Get the dimensions of the W2 matrix.

Returns
std::pair<int, int> containing rows and columns of W2

Definition at line 111 of file neural_network.h.

111 { return {W2.get_rows(), W2.get_cols()}; }

◆ get_Z1_data()

double* NeuralNetwork::get_Z1_data ( ) const
inline

Get the pointer to the Z1 matrix data (pre-activation of hidden layer)

Returns
Pointer to the Z1 matrix data on the device

Definition at line 165 of file neural_network.h.

165 { return Z1.get_data(); }

◆ get_Z1_dimensions()

std::pair<int, int> NeuralNetwork::get_Z1_dimensions ( ) const
inline

Get the dimensions of the Z1 matrix.

Returns
std::pair<int, int> containing rows and columns of Z1

Definition at line 171 of file neural_network.h.

171 { return {Z1.get_rows(), Z1.get_cols()}; }

◆ get_Z2_data()

double* NeuralNetwork::get_Z2_data ( ) const
inline

Get the pointer to the Z2 matrix data (pre-activation of output layer)

Returns
Pointer to the Z2 matrix data on the device

Definition at line 189 of file neural_network.h.

189 { return Z2.get_data(); }

◆ get_Z2_dimensions()

std::pair<int, int> NeuralNetwork::get_Z2_dimensions ( ) const
inline

Get the dimensions of the Z2 matrix.

Returns
std::pair<int, int> containing rows and columns of Z2

Definition at line 195 of file neural_network.h.

195 { return {Z2.get_rows(), Z2.get_cols()}; }

◆ gradient_descent()

void NeuralNetwork::gradient_descent ( const Matrix X,
const Matrix Y,
double  learning_rate,
int  epochs 
)

Perform gradient descent to train the neural network.

Parameters
XInput data matrix
YTrue labels matrix
learning_rateLearning rate for parameter updates
epochsNumber of training epochs

Definition at line 10 of file neural_network_gradient_descent.cu.

10  {
11  const int bar_width = 50;
12  std::string bar;
13 
14  // Iterate through epochs
15  for (int epoch = 0; epoch < epochs; ++epoch) {
16  // Perform forward propagation
17  forward(X);
18 
19  // Perform backward propagation
20  backward(X, Y);
21 
22  // Update parameters
23  update_params(learning_rate);
24 
25  // Calculate accuracy for this epoch
26  double accuracy = get_accuracy(Y);
27 
28  // Calculate progress
29  float progress = static_cast<float>(epoch + 1) / epochs;
30  int pos = static_cast<int>(bar_width * progress);
31 
32  // Update progress bar
33  bar = "[";
34  for (int i = 0; i < bar_width; ++i) {
35  if (i < pos) bar += "=";
36  else if (i == pos) bar += ">";
37  else bar += " ";
38  }
39  bar += "] ";
40 
41  // Print progress bar and accuracy
42  std::cout << "\r" << std::setw(3) << static_cast<int>(progress * 100.0) << "% "
43  << bar << std::setw(3) << epoch + 1 << "/" << std::setw(3) << epochs
44  << " - Accuracy: " << std::fixed << std::setprecision(4) << accuracy << std::flush;
45  }
46  // Move to the next line after completion
47  std::cout << std::endl;
48 }
void backward(const Matrix &X, const Matrix &Y)
Perform backward propagation through the network.
void update_params(double learning_rate)
Updates the network parameters based on computed gradients.
double get_accuracy(const Matrix &Y) const
Calculate the accuracy of predictions compared to true labels.
void forward(const Matrix &X)
Perform forward propagation through the network.

◆ initialize()

void NeuralNetwork::initialize ( )

Initialize the neural network parameters.

Definition at line 9 of file neural_network_initialize.cu.

9  {
10  // Initialize W1 with random values
11  W1.randomize();
12  // Scale W1 by sqrt(2.0 / input_size) for better initial performance
13  W1.multiply_scalar(std::sqrt(2.0 / input_size));
14 
15  // Initialize b1 with random values
16  b1.randomize();
17  // Scale b1 by 0.01 to keep initial values small
18  b1.multiply_scalar(0.01);
19 
20  // Initialize W2 with random values
21  W2.randomize();
22  // Scale W2 by sqrt(2.0 / hidden_size) for better initial performance
23  W2.multiply_scalar(std::sqrt(2.0 / hidden_size));
24 
25  // Initialize b2 with random values
26  b2.randomize();
27  // Scale b2 by 0.01 to keep initial values small
28  b2.multiply_scalar(0.01);
29 
30  // Initialize other matrices with zeros
31  A.initialize();
32  Z1.initialize();
33  A1.initialize();
34  Z2.initialize();
35  A2.initialize();
36  DZ2.initialize();
37  DW2.initialize();
38  DZ1.initialize();
39  DW1.initialize();
40 
41  // Initialize scalar gradients to zero
42  db1 = 0.0;
43  db2 = 0.0;
44 }
void initialize()
Initialize the matrix (typically sets all elements to zero)
void randomize()
Randomize the matrix elements with values between -0.5 and 0.5.
void multiply_scalar(double scalar)
Multiplies all elements in the matrix by a scalar.
void randomize()
Randomize the vector elements with values between -0.5 and 0.5.
void multiply_scalar(double scalar)
Multiplies all elements in the vector by a scalar.

◆ update_params()

void NeuralNetwork::update_params ( double  learning_rate)

Updates the network parameters based on computed gradients.

Parameters
learning_rateThe learning rate for the parameter update.

Definition at line 8 of file neural_network_update_params.cu.

8  {
9  // Update weights for the first layer (W1)
10  DW1.multiply_scalar(learning_rate);
11  W1 = W1.subtract(DW1);
12  // std::cout << "Updated W1:" << std::endl;
13  // W1.print(4);
14 
15  // Update bias for the first layer (b1)
16  b1.subtract_scalar(learning_rate * db1);
17  // std::cout << "Updated b1:" << std::endl;
18  // b1.print(4);
19 
20  // Update weights for the second layer (W2)
21  DW2.multiply_scalar(learning_rate);
22  W2 = W2.subtract(DW2);
23  // std::cout << "Updated W2:" << std::endl;
24  // W2.print(4);
25 
26  // Update bias for the second layer (b2)
27  b2.subtract_scalar(learning_rate * db2);
28  // std::cout << "Updated b2:" << std::endl;
29  // b2.print(4);
30 }
void subtract_scalar(double scalar)
Subtracts a scalar value from all elements in the vector.

The documentation for this class was generated from the following files: