Logo ROOT   6.14/05
Reference Guide
LossFunctions.cxx
Go to the documentation of this file.
1 // @(#)root/tmva/tmva/dnn:$Id$
2 // Author: Simon Pfreundschuh 20/07/16
3 
4 /*************************************************************************
5  * Copyright (C) 2016, Simon Pfreundschuh *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12  /////////////////////////////////////////////////////////////////////
13  // Implementation of the loss functions for the multi-threaded CPU //
14  // implementation using Roots TThreadExecutor and BLAS. //
15  /////////////////////////////////////////////////////////////////////
16 
18 
19 namespace TMVA
20 {
21 namespace DNN
22 {
23 
24 //______________________________________________________________________________
25 template <typename AFloat>
27  const TCpuMatrix<AFloat> &weights)
28 {
29  const AFloat *dataY = Y.GetRawDataPointer();
30  const AFloat *dataOutput = output.GetRawDataPointer();
31  const AFloat *dataWeights = weights.GetRawDataPointer();
32  std::vector<AFloat> temp(Y.GetNElements());
33  size_t m = Y.GetNrows();
34  AFloat norm = 1.0 / ((AFloat) Y.GetNrows() * Y.GetNcols());
35 
36  auto f = [&dataY, &dataOutput, &dataWeights, &temp, m](UInt_t workerID) {
37  AFloat dy = dataY[workerID] - dataOutput[workerID];
38  temp[workerID] = dataWeights[workerID % m] * dy * dy;
39  return 0;
40  };
41 
42  auto reduction = [](const std::vector<AFloat> & v )
43  {
44  return std::accumulate(v.begin(),v.end(),AFloat{});
45  };
46 
48  return norm * Y.GetThreadExecutor().Reduce(temp, reduction);
49 }
50 
51 //______________________________________________________________________________
52 template <typename AFloat>
54  const TCpuMatrix<AFloat> &output, const TCpuMatrix<AFloat> &weights)
55 {
56 
57  AFloat *dataDY = dY.GetRawDataPointer();
58  const AFloat *dataY = Y.GetRawDataPointer();
59  const AFloat *dataOutput = output.GetRawDataPointer();
60  const AFloat *dataWeights = weights.GetRawDataPointer();
61 
62  size_t m = Y.GetNrows();
63  AFloat norm = 1.0 / ((AFloat) Y.GetNrows() * Y.GetNcols());
64 
65  auto f = [&dataDY, &dataY, &dataOutput, &dataWeights, m, norm](UInt_t workerID) {
66  dataDY[workerID] = -2.0 * norm * (dataY[workerID] - dataOutput[workerID]);
67  dataDY[workerID] *= dataWeights[workerID % m];
68  return 0;
69  };
70 
72 }
73 
74 //______________________________________________________________________________
75 template <typename AFloat>
77  const TCpuMatrix<AFloat> &weights)
78 {
79  const AFloat *dataY = Y.GetRawDataPointer();
80  const AFloat *dataOutput = output.GetRawDataPointer();
81  const AFloat *dataWeights = weights.GetRawDataPointer();
82  std::vector<AFloat> temp(Y.GetNElements());
83 
84  size_t m = Y.GetNrows();
85  AFloat norm = 1.0 / ((AFloat) Y.GetNrows() * Y.GetNcols());
86 
87  auto f = [&dataY, &dataOutput, &dataWeights, &temp, m](UInt_t workerID) {
88  AFloat y = dataY[workerID];
89  AFloat sig = 1.0 / (1.0 + exp(- dataOutput[workerID]));
90  temp[workerID] = - (y * log(sig) + (1.0 - y) * log(1.0 - sig));
91  temp[workerID] *= dataWeights[workerID % m];
92  return 0;
93  };
94 
95  auto reduction = [](const std::vector<AFloat> & v )
96  {
97  return std::accumulate(v.begin(),v.end(),AFloat{});
98  };
99 
101  return norm * Y.GetThreadExecutor().Reduce(temp, reduction);
102 }
103 
104 //______________________________________________________________________________
105 template <typename AFloat>
107  const TCpuMatrix<AFloat> &output, const TCpuMatrix<AFloat> &weights)
108 {
109  AFloat *dataDY = dY.GetRawDataPointer();
110  const AFloat *dataY = Y.GetRawDataPointer();
111  const AFloat *dataOutput = output.GetRawDataPointer();
112  const AFloat *dataWeights = weights.GetRawDataPointer();
113 
114  size_t m = Y.GetNrows();
115  AFloat norm = 1.0 / ((AFloat) Y.GetNrows() * Y.GetNcols());
116 
117  auto f = [&dataDY, &dataY, &dataOutput, &dataWeights, m, norm](UInt_t workerID) {
118  AFloat y = dataY[workerID];
119  AFloat sig = 1.0 / (1.0 + exp(- dataOutput[workerID]));
120  dataDY[workerID] = norm * (sig - y);
121  dataDY[workerID] *= dataWeights[workerID % m];
122  return 0;
123  };
124 
126 }
127 
128 //______________________________________________________________________________
129 template <typename AFloat>
131  const TCpuMatrix<AFloat> &weights)
132 {
133  const AFloat *dataY = Y.GetRawDataPointer();
134  const AFloat *dataOutput = output.GetRawDataPointer();
135  const AFloat *dataWeights = weights.GetRawDataPointer();
136 
137  std::vector<AFloat> temp(Y.GetNrows());
138  size_t m = Y.GetNrows();
139  size_t n = Y.GetNcols();
140  AFloat norm = 1.0 / ((AFloat) m);
141 
142  auto f = [&dataY, &dataOutput, &dataWeights, &temp, n, m](UInt_t workerID) {
143  AFloat sum = 0.0;
144  for (size_t j = 0; j < n; j++) {
145  sum += exp(dataOutput[workerID + j * m]);
146  }
147  for (size_t j = 0; j < n; j++) {
148  temp[workerID] -=
149  dataY[workerID + j * m] * log(exp(dataOutput[workerID + j * m]) / sum);
150  }
151  temp[workerID] *= dataWeights[workerID];
152  return 0;
153  };
154 
155  auto reduction = [](const std::vector<AFloat> & v )
156  {
157  return std::accumulate(v.begin(),v.end(),AFloat{});
158  };
159 
161  return norm * Y.GetThreadExecutor().Reduce(temp, reduction);
162 }
163 
164 //______________________________________________________________________________
165 template <typename AFloat>
167  const TCpuMatrix<AFloat> &output, const TCpuMatrix<AFloat> &weights)
168 {
169  AFloat *dataDY = dY.GetRawDataPointer();
170  const AFloat *dataY = Y.GetRawDataPointer();
171  const AFloat *dataOutput = output.GetRawDataPointer();
172  const AFloat *dataWeights = weights.GetRawDataPointer();
173 
174  size_t m = Y.GetNrows();
175  size_t n = Y.GetNcols();
176  AFloat norm = 1.0 / ((AFloat) m);
177 
178  auto f = [&dataDY, &dataY, &dataOutput, &dataWeights, norm, n, m](UInt_t workerID) {
179  AFloat sum = 0.0;
180  AFloat sumY = 0.0;
181  AFloat weight = dataWeights[workerID];
182  for (size_t j = 0; j < n; j++) {
183  sum += exp(dataOutput[workerID + j * m]);
184  sumY += dataY[workerID + j * m];
185  }
186  for (size_t j = 0; j < n; j++) {
187  dataDY[workerID + j * m] =
188  norm * (exp(dataOutput[workerID + j * m]) / sum * sumY - dataY[workerID + j * m]);
189  dataDY[workerID + j * m] *= weight;
190  }
191  return 0;
192  };
193 
195 }
196 
197 } // namespace DNN
198 } // namespace TMVA
static long int sum(long int i)
Definition: Factory.cxx:2258
static void MeanSquaredErrorGradients(TCpuMatrix< Scalar_t > &dY, const TCpuMatrix< Scalar_t > &Y, const TCpuMatrix< Scalar_t > &output, const TCpuMatrix< Scalar_t > &weights)
The TCpuMatrix class.
Definition: CpuMatrix.h:72
auto * m
Definition: textangle.C:8
size_t GetNcols() const
Definition: CpuMatrix.h:127
static Scalar_t CrossEntropy(const TCpuMatrix< Scalar_t > &Y, const TCpuMatrix< Scalar_t > &output, const TCpuMatrix< Scalar_t > &weights)
Sigmoid transformation is implicitly applied, thus output should hold the linear activations of the l...
#define f(i)
Definition: RSha256.hxx:104
static Scalar_t MeanSquaredError(const TCpuMatrix< Scalar_t > &Y, const TCpuMatrix< Scalar_t > &output, const TCpuMatrix< Scalar_t > &weights)
size_t GetNElements() const
Definition: CpuMatrix.h:128
auto Reduce(const std::vector< T > &objs, BINARYOP redfunc) -> decltype(redfunc(objs.front(), objs.front()))
"Reduce" an std::vector into a single object in parallel by passing a binary operator as the second a...
SVector< double, 2 > v
Definition: Dict.h:5
unsigned int UInt_t
Definition: RtypesCore.h:42
static ROOT::TThreadExecutor & GetThreadExecutor()
Definition: CpuMatrix.h:139
AFloat * GetRawDataPointer()
Return raw pointer to the elements stored contiguously in column-major order.
Definition: CpuMatrix.h:136
A pseudo container class which is a generator of indices.
Definition: TSeq.hxx:66
Double_t y[n]
Definition: legend1.C:17
static Scalar_t SoftmaxCrossEntropy(const TCpuMatrix< Scalar_t > &Y, const TCpuMatrix< Scalar_t > &output, const TCpuMatrix< Scalar_t > &weights)
Softmax transformation is implicitly applied, thus output should hold the linear activations of the l...
Abstract ClassifierFactory template that handles arbitrary types.
auto Map(F func, unsigned nTimes) -> std::vector< typename std::result_of< F()>::type >
Execute func (with no arguments) nTimes in parallel.
size_t GetNrows() const
Definition: CpuMatrix.h:126
static void SoftmaxCrossEntropyGradients(TCpuMatrix< Scalar_t > &dY, const TCpuMatrix< Scalar_t > &Y, const TCpuMatrix< Scalar_t > &output, const TCpuMatrix< Scalar_t > &weights)
double exp(double)
static void CrossEntropyGradients(TCpuMatrix< Scalar_t > &dY, const TCpuMatrix< Scalar_t > &Y, const TCpuMatrix< Scalar_t > &output, const TCpuMatrix< Scalar_t > &weights)
const Int_t n
Definition: legend1.C:16
double log(double)