22 template <
typename AReal>
26 output.
MultT(input, weights);
29 template <
typename AReal>
32 for (
size_t i = 0; i < (size_t)output.
GetNrows(); i++) {
33 for (
size_t j = 0; j < (size_t)output.
GetNcols(); j++) {
34 output(i, j) += biases(j, 0);
39 template <
typename AReal>
47 for (
size_t i = 0; i < (size_t)df.
GetNrows(); i++) {
48 for (
size_t j = 0; j < (size_t)df.
GetNcols(); j++) {
49 df(i, j) *= activation_gradients(i, j);
55 activation_gradients_backward.
Mult(df, weights);
60 weight_gradients.
TMult(df, activations_backward);
65 for (
size_t j = 0; j < (size_t)df.
GetNcols(); j++) {
67 for (
size_t i = 0; i < (size_t)df.
GetNrows(); i++) {
70 bias_gradients(j, 0) =
sum;
75 template <
typename AReal>
78 for (
size_t i = 0; i < (size_t)A.
GetNrows(); i++) {
79 for (
size_t j = 0; j < (size_t)A.
GetNcols(); j++) {
80 A(i, j) += beta *
B(i, j);
85 template <
typename AReal>
91 template <
typename AReal>
94 for (
size_t i = 0; i <
A.size(); ++i) {
95 ScaleAdd(
A[i],
B[i], beta);
99 template <
typename AReal>
102 for (
size_t i = 0; i <
A.size(); ++i) {
107 template <
typename AReal>
119 template <
typename AReal>
121 size_t fltHeight,
size_t fltWidth,
size_t strideRows,
size_t strideCols,
122 size_t zeroPaddingHeight,
size_t zeroPaddingWidth)
125 int imgHeightBound = imgHeight + zeroPaddingHeight - (fltHeight - 1) / 2 - 1;
126 int imgWidthBound = imgWidth + zeroPaddingWidth - (fltWidth - 1) / 2 - 1;
127 size_t currLocalView = 0;
130 for (
int i = -zeroPaddingHeight + fltHeight / 2; i <= imgHeightBound; i += strideRows) {
131 for (
int j = -zeroPaddingWidth + fltWidth / 2; j <= imgWidthBound; j += strideCols) {
132 size_t currLocalViewPixel = 0;
136 for (
Int_t k = i -
Int_t(fltHeight) / 2; k <= i + (
Int_t(fltHeight) - 1) / 2; k++) {
140 if (k < 0 || k >=
Int_t(imgHeight) || l < 0 || l >=
Int_t(imgWidth))
141 A(currLocalView, currLocalViewPixel++) = 0;
143 A(currLocalView, currLocalViewPixel++) =
B(
m, k * imgWidth +
l);
154 template <
typename AReal>
156 size_t filterHeight,
size_t filterWidth,
size_t numFilters)
158 size_t jump = filterHeight * filterWidth;
159 for (
size_t j = 0; j < filterDepth; j++) {
160 for (
size_t k = 0; k < numFilters; k++) {
161 for (
size_t i = 0; i < jump; i++) {
162 A(j, k * jump + i) =
B(k, ((j + 1) * jump - 1) - i);
169 template <
typename AReal>
172 for (
size_t i = 0; i < (size_t)output.
GetNrows(); i++) {
173 for (
size_t j = 0; j < (size_t)output.
GetNcols(); j++) {
174 output(i, j) += biases(i, 0);
179 #ifdef HAVE_CNN_REFERENCE 181 template <
typename AReal>
187 const std::vector<
TMatrixT<AReal>> &activations_backward,
size_t batchSize,
188 size_t inputHeight,
size_t inputWidth,
size_t depth,
size_t height,
189 size_t width,
size_t filterDepth,
size_t filterHeight,
size_t filterWidth,
195 m = activation_gradients[0].GetNrows();
196 n = activation_gradients[0].GetNcols();
198 for (
size_t i = 0; i < batchSize; i++) {
199 for (
size_t j = 0; j < (size_t)m; j++) {
200 for (
size_t k = 0; k < (size_t)n; k++) {
201 df[i](j, k) *= activation_gradients[i](j, k);
207 CalculateConvActivationGradients(activation_gradients_backward, df, weights, batchSize, inputHeight, inputWidth,
208 depth, height, width, filterDepth, filterHeight, filterWidth);
211 CalculateConvWeightGradients(weight_gradients, df, activations_backward, batchSize, inputHeight, inputWidth, depth,
212 height, width, filterDepth, filterHeight, filterWidth, nLocalViews);
215 CalculateConvBiasGradients(bias_gradients, df, batchSize, depth, nLocalViews);
219 template <
typename AReal>
223 size_t inputHeight,
size_t inputWidth,
size_t depth,
224 size_t height,
size_t width,
size_t filterDepth,
225 size_t filterHeight,
size_t filterWidth)
228 if (activation_gradients_backward.size() == 0)
return;
231 TMatrixT<AReal> rotWeights(filterDepth, depth * filterHeight * filterWidth);
232 RotateWeights(rotWeights, weights, filterDepth, filterHeight, filterWidth, weights.
GetNrows());
235 size_t tempZeroPaddingHeight = (size_t)(
floor((inputHeight - height + filterHeight - 1) / 2));
236 size_t tempZeroPaddingWidth = (size_t)(
floor((inputWidth - width + filterWidth - 1) / 2));
239 size_t tempNLocalViews = inputHeight * inputWidth;
240 size_t tempNLocalViewPixels = depth * filterHeight * filterWidth;
242 size_t tempStrideRows = 1;
243 size_t tempStrideCols = 1;
246 for (
size_t i = 0; i < batchSize; i++) {
248 Im2col(dfTr, df[i], inputHeight, inputWidth, filterHeight, filterWidth, tempStrideRows, tempStrideCols,
249 tempZeroPaddingHeight, tempZeroPaddingWidth);
251 activation_gradients_backward[i].MultT(rotWeights, dfTr);
258 template <
typename AReal>
262 size_t batchSize,
size_t inputHeight,
size_t inputWidth,
263 size_t depth,
size_t height,
size_t width,
size_t filterDepth,
264 size_t filterHeight,
size_t filterWidth,
size_t nLocalViews)
270 weight_gradients(i, j) = 0;
273 for (
size_t i = 0; i < batchSize; i++) {
275 size_t tempZeroPaddingHeight = (filterHeight - height + inputHeight - 1) / 2;
276 size_t tempZeroPaddingWidth = (filterWidth - width + inputWidth - 1) / 2;
278 size_t tempNLocalViews = filterHeight * filterWidth;
279 size_t tempNLocalViewPixels = inputHeight * inputWidth;
281 size_t tempStrideRows = 1;
282 size_t tempStrideCols = 1;
284 for (
size_t j = 0; j < depth; j++) {
288 for (
size_t k = 0; k < nLocalViews; k++) {
289 rowDelta(0, k) = df[i](j, k);
296 Im2col(rowDeltaTr, rowDelta, height, width, inputHeight, inputWidth, tempStrideRows, tempStrideCols,
297 tempZeroPaddingHeight, tempZeroPaddingWidth);
299 res.MultT(activations_backward[i], rowDeltaTr);
301 for (
size_t k = 0; k < filterDepth; k++) {
302 for (
size_t l = 0;
l < filterHeight * filterWidth;
l++) {
303 weight_gradients(j, k * (filterHeight * filterWidth) +
l) += res(k, (tempNLocalViews - 1) -
l);
310 (
void)weight_gradients;
312 (
void)activations_backward;
327 template <
typename AReal>
329 size_t batchSize,
size_t depth,
size_t nLocalViews)
331 for (
size_t i = 0; i < depth; i++) {
333 for (
size_t j = 0; j < nLocalViews; j++) {
334 for (
size_t k = 0; k < batchSize; k++) {
338 bias_gradients(i, 0) =
sum;
344 template <
typename AReal>
346 size_t imgWidth,
size_t fltHeight,
size_t fltWidth,
size_t strideRows,
350 int imgHeightBound = imgHeight - (fltHeight - 1) / 2 - 1;
351 int imgWidthBound = imgWidth - (fltWidth - 1) / 2 - 1;
352 size_t currLocalView = 0;
355 for (
int i = fltHeight / 2; i <= imgHeightBound; i += strideRows) {
356 for (
int j = fltWidth / 2; j <= imgWidthBound; j += strideCols) {
359 AReal value = -std::numeric_limits<AReal>::max();
361 for (
int k = i -
Int_t(fltHeight) / 2; k <= i + (
Int_t(fltHeight) - 1) / 2; k++) {
362 for (
int l = j -
Int_t(fltWidth) / 2;
l <= j + (
Int_t(fltWidth) - 1) / 2;
l++) {
363 if (
C(
m, k * imgWidth +
l) > value) {
364 value =
C(
m, k * imgWidth +
l);
365 B(
m, currLocalView) = k * imgWidth +
l;
369 A(
m, currLocalView) = value;
377 template <
typename AReal>
381 size_t depth,
size_t nLocalViews)
383 for (
size_t i = 0; i < batchSize; i++) {
384 for (
size_t j = 0; j < depth; j++) {
387 for (
size_t t = 0; t < (size_t)activationGradientsBackward[i].GetNcols(); t++) {
388 activationGradientsBackward[i][j][t] = 0;
392 for (
size_t k = 0; k < nLocalViews; k++) {
393 AReal grad = activationGradients[i][j][k];
394 size_t winningIdx = indexMatrix[i][j][k];
395 activationGradientsBackward[i][j][winningIdx] = grad;
402 template <
typename AReal>
410 auto nElem = i * nColsA + j;
411 A(i, j) =
B(nElem / nColsB, (nElem - 1) % nColsB);
417 template <
typename AReal>
421 for (
size_t i = 0; i < (size_t)size; i++) {
422 for (
size_t j = 0; j < (size_t)nRows; j++) {
423 for (
size_t k = 0; k < (size_t)nCols; k++) {
424 A(i, j * nCols + k) =
B[i](j, k);
431 template <
typename AReal>
435 for (
size_t i = 0; i < (size_t)size; i++) {
436 for (
size_t j = 0; j < (size_t)nRows; j++) {
437 for (
size_t k = 0; k < (size_t)nCols; k++) {
438 A[i](j, k) =
B(i, j * nCols + k);
445 template <
typename AReal>
450 auto T = out[0].GetNrows();
451 auto D = out[0].GetNcols();
452 if ((
T != (
Int_t)in.size()) || (
Int_t(
B) != in[0].GetNrows()) || (D != in[0].GetNcols())) {
453 std::cout <<
"Incompatible Dimensions\n" 454 << in.size() <<
"x" << in[0].GetNrows() <<
"x" << in[0].GetNcols() <<
" --> " <<
B <<
"x" <<
T <<
"x" 458 for (
size_t i = 0; i <
B; ++i) {
459 for (
Int_t j = 0; j <
T; ++j) {
460 for (
Int_t k = 0; k < D; ++k) {
461 out[i](j, k) = in[j](i, k);
static long int sum(long int i)
static void MaxPoolLayerBackward(std::vector< TMatrixT< AReal >> &activationGradientsBackward, const std::vector< TMatrixT< AReal >> &activationGradients, const std::vector< TMatrixT< AReal >> &indexMatrix, size_t batchSize, size_t depth, size_t nLocalViews)
Perform the complete backward propagation step in a Max Pooling Layer.
static void AddConvBiases(TMatrixT< AReal > &output, const TMatrixT< AReal > &biases)
Add the biases in the Convolutional Layer.
static void Im2col(TMatrixT< AReal > &A, TMatrixT< AReal > &B, size_t imgHeight, size_t imgWidth, size_t fltHeight, size_t fltWidth, size_t strideRows, size_t strideCols, size_t zeroPaddingHeight, size_t zeroPaddingWidth)
Transform the matrix B in local view format, suitable for convolution, and store it in matrix A...
image html pict1_TGaxis_012 png width
Define new text attributes for the label number "labNum".
double beta(double x, double y)
Calculates the beta function.
Int_t GetNoElements() const
The reference architecture class.
static void Flatten(TMatrixT< AReal > &A, const std::vector< TMatrixT< AReal >> &B, size_t size, size_t nRows, size_t nCols)
Flattens the tensor B, such that each matrix, is stretched in one row, resulting with a matrix A...
void MultT(const TMatrixT< Element > &a, const TMatrixT< Element > &b)
General matrix multiplication. Create a matrix C such that C = A * B^T.
static void Copy(TMatrixT< Scalar_t > &A, const TMatrixT< Scalar_t > &B)
void TMult(const TMatrixT< Element > &a, const TMatrixT< Element > &b)
Create a matrix C such that C = A' * B.
static void ConvLayerBackward(std::vector< TMatrixT< AReal >> &, TMatrixT< AReal > &, TMatrixT< AReal > &, std::vector< TMatrixT< AReal >> &, const std::vector< TMatrixT< AReal >> &, const TMatrixT< AReal > &, const std::vector< TMatrixT< AReal >> &, size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t, size_t)
Perform the complete backward propagation step in a Convolutional Layer.
static void Reshape(TMatrixT< AReal > &A, const TMatrixT< AReal > &B)
Transform the matrix B to a matrix with different dimensions A.
static void RotateWeights(TMatrixT< AReal > &A, const TMatrixT< AReal > &B, size_t filterDepth, size_t filterHeight, size_t filterWidth, size_t numFilters)
Rotates the matrix B, which is representing a weights, and stores them in the matrix A...
static void Backward(TMatrixT< Scalar_t > &activationGradientsBackward, TMatrixT< Scalar_t > &weightGradients, TMatrixT< Scalar_t > &biasGradients, TMatrixT< Scalar_t > &df, const TMatrixT< Scalar_t > &activationGradients, const TMatrixT< Scalar_t > &weights, const TMatrixT< Scalar_t > &activationBackward)
Perform the complete backward propagation step.
static void Deflatten(std::vector< TMatrixT< AReal >> &A, const TMatrixT< Scalar_t > &B, size_t index, size_t nRows, size_t nCols)
Transforms each row of B to a matrix and stores it in the tensor B.
static void SumColumns(TMatrixT< AReal > &B, const TMatrixT< AReal > &A)
Sum columns of (m x n) matrixx A and write the results into the first m elements in A...
void Copy(void *source, void *dest)
static void Downsample(TMatrixT< AReal > &A, TMatrixT< AReal > &B, const TMatrixT< AReal > &C, size_t imgHeight, size_t imgWidth, size_t fltHeight, size_t fltWidth, size_t strideRows, size_t strideCols)
Downsample the matrix C to the matrix A, using max operation, such that the winning indices are store...
static void ScaleAdd(TMatrixT< Scalar_t > &A, const TMatrixT< Scalar_t > &B, Scalar_t beta=1.0)
Adds a the elements in matrix B scaled by c to the elements in the matrix A.
typedef void((*Func_t)())
Abstract ClassifierFactory template that handles arbitrary types.
void Mult(const TMatrixT< Element > &a, const TMatrixT< Element > &b)
General matrix multiplication. Create a matrix C such that C = A * B.
static void Rearrange(std::vector< TMatrixT< AReal >> &out, const std::vector< TMatrixT< AReal >> &in)
Rearrage data accoring to time fill B x T x D out with T x B x D matrix in.
static void MultiplyTranspose(TMatrixT< Scalar_t > &output, const TMatrixT< Scalar_t > &input, const TMatrixT< Scalar_t > &weights)
Matrix-multiply input with the transpose of and write the results into output.
static void AddRowWise(TMatrixT< Scalar_t > &output, const TMatrixT< Scalar_t > &biases)
Add the vectors biases row-wise to the matrix output.