Caffe2 - C++ API
A deep learning, cross platform ML framework
softmax_shared.cc
1 
17 #include "caffe2/core/context.h"
18 #include "caffe2/core/operator.h"
19 #include "caffe2/utils/math.h"
20 
21 namespace caffe2 {
22 
23 void SoftmaxCPU(
24  CPUContext& context,
25  const int N,
26  const int D,
27  const float* Xdata,
28  float* Ydata,
29  float* scale,
30  const float* sum_multiplier,
31  bool logarithmic,
32  float* rowmax) {
33  math::RowwiseMax<float, CPUContext>(N, D, Xdata, rowmax, &context);
34  // Put the intermediate result X - max(X) into Y
35  context.template Copy<float, CPUContext, CPUContext>(N * D, Xdata, Ydata);
36  // Subtract the max (for numerical reasons)
37  math::Gemm<float, CPUContext>(
38  CblasNoTrans,
39  CblasNoTrans,
40  N,
41  D,
42  1,
43  -1,
44  rowmax,
45  sum_multiplier,
46  1,
47  Ydata,
48  &context);
49  // Exponentiation
50  math::Exp<float, CPUContext>(N * D, Ydata, Ydata, &context);
51  math::Gemv<float, CPUContext>(
52  CblasNoTrans, N, D, 1, Ydata, sum_multiplier, 0, scale, &context);
53  // Do division
54  // TODO(Yangqing): maybe implement it more beautifully?
55  if (!logarithmic) {
56  for (int i = 0; i < N; ++i) {
57  for (int j = 0; j < D; ++j) {
58  Ydata[i * D + j] /= scale[i];
59  }
60  }
61  } else {
62  for (int i = 0; i < N; ++i) {
63  for (int j = 0; j < D; ++j) {
64  Ydata[i * D + j] =
65  Xdata[i * D + j] - rowmax[i] - log(fmaxf(scale[i], 1e-20f));
66  }
67  }
68  }
69 }
70 
71 } // namespace caffe2
Copyright (c) 2016-present, Facebook, Inc.