DLPrimitives
cpu_ops.hpp
1 #pragma once
2 #include <array>
3 #include <dlprim/definitions.hpp>
4 #include <cmath>
5 
6 namespace dlprim {
8  namespace cpu {
9  template<typename T>
10  inline void apply_activation(T *p,size_t n,StandardActivations a)
11  {
12  switch(a) {
13  case StandardActivations::identity:
14  break;
15  case StandardActivations::relu:
16  {
17  T zero=T();
18  for(size_t i=0;i<n;i++) {
19  p[i] = std::max(p[i],zero);
20  }
21  }
22  break;
23  case StandardActivations::tanh:
24  {
25  for(size_t i=0;i<n;i++) {
26  p[i] = std::tanh(p[i]);
27  }
28  }
29  break;
30  case StandardActivations::sigmoid:
31  {
32  for(size_t i=0;i<n;i++) {
33  p[i] = 1 / (1 + std::exp(-p[i]));
34  }
35  }
36  break;
37  case StandardActivations::relu6:
38  {
39  T zero=T();
40  for(size_t i=0;i<n;i++) {
41  p[i] = std::min(std::max(p[i],zero),T(6));
42  }
43  }
44  break;
45  };
46  }
47 
48  template<typename T>
49  inline void apply_activation_diff(size_t n,T const *y,T const *dy,T *dx,StandardActivations a)
50  {
51  switch(a) {
52  case StandardActivations::identity:
53  {
54  for(size_t i=0;i<n;i++) {
55  dx[i] = dy[i];
56  }
57  }
58  break;
59  case StandardActivations::relu:
60  {
61  for(size_t i=0;i<n;i++) {
62  dx[i] = y[i] > 0 ? dy[i] : 0;
63  }
64  }
65  break;
66  case StandardActivations::tanh:
67  {
68  for(size_t i=0;i<n;i++) {
69  T yv = y[i];
70  dx[i] = dy[i] * (1-yv*yv);
71  }
72  }
73  break;
74  case StandardActivations::sigmoid:
75  {
76  for(size_t i=0;i<n;i++) {
77  T yv = y[i];
78  dx[i] = dy[i] * yv * (1-yv);
79  }
80  }
81  break;
82  case StandardActivations::relu6:
83  {
84  for(size_t i=0;i<n;i++) {
85  dx[i] = (6 > y[i] && y[i] > 0) ? dy[i] : 0;
86  }
87  }
88  break;
89  };
90  }
91 
92  template<typename T>
93  inline void apply_activation_diff(size_t n,T const *y,T const *dy,T *dx,float beta,StandardActivations a)
94  {
95  if(beta == 0.0f) {
96  apply_activation_diff(n,y,dy,dx,a);
97  return;
98  }
99  switch(a) {
100  case StandardActivations::identity:
101  {
102  for(size_t i=0;i<n;i++) {
103  dx[i] = beta*dx[i] + dy[i];
104  }
105  }
106  break;
107  case StandardActivations::relu:
108  {
109  for(size_t i=0;i<n;i++) {
110  dx[i] = beta*dx[i] + (y[i] > 0 ? dy[i] : 0);
111  }
112  }
113  break;
114  case StandardActivations::tanh:
115  {
116  for(size_t i=0;i<n;i++) {
117  T yv = y[i];
118  dx[i] = beta*dx[i] + (dy[i] * (1-yv*yv));
119  }
120  }
121  break;
122  case StandardActivations::sigmoid:
123  {
124  for(size_t i=0;i<n;i++) {
125  T yv = y[i];
126  dx[i] = beta*dx[i] + (dy[i] * yv * (1-yv));
127  }
128  }
129  break;
130  case StandardActivations::relu6:
131  {
132  for(size_t i=0;i<n;i++) {
133  dx[i] = beta*dx[i] + (6 > y[i] && y[i] > 0 ? dy[i] : 0);
134  }
135  }
136  break;
137  };
138  }
139  }
140 };
Mane namespace.
Definition: context.hpp:9
StandardActivations
Parameterless Activations that can be embedded to general kernels like inner product or convolution...
Definition: definitions.hpp:266