Deep Learning Algorithm Implementations 1.0.0
C++ implementations of fundamental deep learning algorithms
Loading...
Searching...
No Matches
autograd.cpp
Go to the documentation of this file.
1#include "utils/autograd.hpp"
2#include <algorithm>
3#include <cmath>
4#include <queue>
5#include <unordered_set>
6
7namespace utils {
8
9 template<typename T>
10 void Variable<T>::backward(const Matrix<T>& gradient) {
11 if (!requires_grad_) {
12 return;
13 }
14
15 // Initialize gradient if not provided
16 Matrix<T> grad = gradient;
17 if (gradient.rows() == 0 || gradient.cols() == 0) {
18 // Scalar case - gradient is 1
19 grad = Matrix<T>::ones(data_.rows(), data_.cols());
20 }
21
22 // Accumulate gradient
23 grad_ = grad_ + grad;
24
25 // If this variable has a gradient function, propagate backwards
26 if (grad_fn_) {
27 auto input_grads = grad_fn_->backward(grad);
28
29 // Propagate to inputs (this would require storing input variables)
30 // For now, this is a simplified implementation
31 // In a full implementation, we'd need to store the computational graph
32 }
33 }
34
35 template<typename T>
37 auto add_fn = std::make_shared<AddFunction<T>>();
38 Matrix<T> result = add_fn->forward({*this, other});
39
40 if (requires_grad_ || other.requires_grad_) {
41 return Variable<T>(result, add_fn);
42 }
43 return Variable<T>(result, false);
44 }
45
46 template<typename T>
48 auto sub_fn = std::make_shared<SubFunction<T>>();
49 Matrix<T> result = sub_fn->forward({*this, other});
50
51 if (requires_grad_ || other.requires_grad_) {
52 return Variable<T>(result, sub_fn);
53 }
54 return Variable<T>(result, false);
55 }
56
57 template<typename T>
59 auto mul_fn = std::make_shared<MulFunction<T>>();
60 Matrix<T> result = mul_fn->forward({*this, other});
61
62 if (requires_grad_ || other.requires_grad_) {
63 return Variable<T>(result, mul_fn);
64 }
65 return Variable<T>(result, false);
66 }
67
68 template<typename T>
70 auto dot_fn = std::make_shared<DotFunction<T>>();
71 Matrix<T> result = dot_fn->forward({*this, other});
72
73 if (requires_grad_ || other.requires_grad_) {
74 return Variable<T>(result, dot_fn);
75 }
76 return Variable<T>(result, false);
77 }
78
79 template<typename T>
81 auto transpose_fn = std::make_shared<TransposeFunction<T>>();
82 Matrix<T> result = transpose_fn->forward({*this});
83
84 if (requires_grad_) {
85 return Variable<T>(result, transpose_fn);
86 }
87 return Variable<T>(result, false);
88 }
89
90 template<typename T>
92 auto sum_fn = std::make_shared<SumFunction<T>>();
93 Matrix<T> result = sum_fn->forward({*this});
94
95 if (requires_grad_) {
96 return Variable<T>(result, sum_fn);
97 }
98 return Variable<T>(result, false);
99 }
100
101 template<typename T>
103 auto sum_result = sum();
104 T count = static_cast<T>(data_.rows() * data_.cols());
105 Matrix<T> count_matrix(1, 1, count);
106 Variable<T> count_var(count_matrix, false);
107
108 // mean = sum / count
109 return sum_result * Variable<T>(Matrix<T>(1, 1, 1.0 / count), false);
110 }
111
112 template<typename T>
114 auto sigmoid_fn = std::make_shared<SigmoidFunction<T>>();
115 Matrix<T> result = sigmoid_fn->forward({*this});
116
117 if (requires_grad_) {
118 return Variable<T>(result, sigmoid_fn);
119 }
120 return Variable<T>(result, false);
121 }
122
123 template<typename T>
125 // tanh(x) = (exp(2x) - 1) / (exp(2x) + 1)
126 Matrix<T> result(data_.rows(), data_.cols());
127 for (size_t i = 0; i < data_.rows(); ++i) {
128 for (size_t j = 0; j < data_.cols(); ++j) {
129 result(i, j) = std::tanh(data_(i, j));
130 }
131 }
132 return Variable<T>(result, requires_grad_);
133 }
134
135 template<typename T>
137 Matrix<T> result(data_.rows(), data_.cols());
138 for (size_t i = 0; i < data_.rows(); ++i) {
139 for (size_t j = 0; j < data_.cols(); ++j) {
140 result(i, j) = std::max(static_cast<T>(0), data_(i, j));
141 }
142 }
143 return Variable<T>(result, requires_grad_);
144 }
145
146 template<typename T>
148 Matrix<T> result(data_.rows(), data_.cols());
149 for (size_t i = 0; i < data_.rows(); ++i) {
150 for (size_t j = 0; j < data_.cols(); ++j) {
151 result(i, j) = std::exp(data_(i, j));
152 }
153 }
154 return Variable<T>(result, requires_grad_);
155 }
156
157 template<typename T>
159 Matrix<T> result(data_.rows(), data_.cols());
160 for (size_t i = 0; i < data_.rows(); ++i) {
161 for (size_t j = 0; j < data_.cols(); ++j) {
162 result(i, j) = std::log(data_(i, j));
163 }
164 }
165 return Variable<T>(result, requires_grad_);
166 }
167
168 // Explicit template instantiations
169 template class Variable<float>;
170 template class Variable<double>;
171 template class Function<float>;
172 template class Function<double>;
173 template class AddFunction<float>;
174 template class AddFunction<double>;
175 template class SubFunction<float>;
176 template class SubFunction<double>;
177 template class MulFunction<float>;
178 template class MulFunction<double>;
179 template class DotFunction<float>;
180 template class DotFunction<double>;
181 template class TransposeFunction<float>;
182 template class TransposeFunction<double>;
183 template class SigmoidFunction<float>;
184 template class SigmoidFunction<double>;
185 template class SumFunction<float>;
186 template class SumFunction<double>;
187
188} // namespace utils
PyTorch-like automatic differentiation engine.
Addition function.
Definition autograd.hpp:149
Matrix multiplication function.
Definition autograd.hpp:195
Function node in the computational graph.
Definition autograd.hpp:25
size_t cols() const
Get the number of columns.
Definition matrix.hpp:200
static Matrix ones(size_t rows, size_t cols)
Create a matrix filled with ones.
Definition matrix.cpp:128
size_t rows() const
Get the number of rows.
Definition matrix.hpp:194
Element-wise multiplication function.
Definition autograd.hpp:179
Sigmoid function.
Definition autograd.hpp:229
Subtraction function.
Definition autograd.hpp:164
Sum function.
Definition autograd.hpp:258
Transpose function.
Definition autograd.hpp:214
Variable class that supports automatic differentiation.
Definition autograd.hpp:58
Variable< T > mean() const
Definition autograd.cpp:102
Variable< T > operator-(const Variable< T > &other) const
Definition autograd.cpp:47
Variable< T > operator+(const Variable< T > &other) const
Definition autograd.cpp:36
Variable< T > sigmoid() const
Definition autograd.cpp:113
Variable< T > log() const
Definition autograd.cpp:158
Variable< T > dot(const Variable< T > &other) const
Definition autograd.cpp:69
Variable< T > exp() const
Definition autograd.cpp:147
Variable< T > tanh() const
Definition autograd.cpp:124
Variable< T > transpose() const
Definition autograd.cpp:80
void backward(const Matrix< T > &gradient=Matrix< T >())
Perform backward pass.
Definition autograd.cpp:10
Variable< T > sum() const
Definition autograd.cpp:91
Variable< T > operator*(const Variable< T > &other) const
Definition autograd.cpp:58
Variable< T > relu() const
Definition autograd.cpp:136
T sum(const Matrix< T > &matrix)
Calculate sum of all matrix elements.
Definition matrix.cpp:166