Caffe2 - C++ API
A deep learning, cross platform ML framework
cosine_embedding_criterion_op.cc
1 #include "caffe2/operators/cosine_embedding_criterion_op.h"
2 
3 #include <algorithm>
4 
5 #include "caffe2/utils/math.h"
6 
7 namespace caffe2 {
8 
9 template <>
10 bool CosineEmbeddingCriterionOp<CPUContext>::RunOnDevice() {
11  auto& S = Input(0);
12  auto& Y = Input(1);
13 
14  CAFFE_ENFORCE(
15  S.numel() == Y.numel(),
16  "The embedding and label should have the same size.");
17  auto* output = Output(0, S.sizes(), at::dtype<float>());
18 
19  const float* Sdata = S.data<float>();
20  const int* Ydata = Y.data<int>();
21  float* output_data = output->template mutable_data<float>();
22  for (int i = 0; i < S.numel(); ++i) {
23  output_data[i] =
24  Ydata[i] == 1 ? (1.f - Sdata[i]) : std::max(0.f, Sdata[i] - margin_);
25  }
26  return true;
27 }
28 
29 template <>
30 bool CosineEmbeddingCriterionGradientOp<CPUContext>::RunOnDevice() {
31  auto& S = Input(0);
32  auto& Y = Input(1);
33  auto& dOutput = Input(2);
34 
35  auto* dS = Output(0, S.sizes(), at::dtype<float>());
36 
37  const float* Sdata = S.data<float>();
38  const int* Ydata = Y.data<int>();
39  const float* dOutput_data = dOutput.data<float>();
40  float* dSdata = dS->template mutable_data<float>();
41  for (int i = 0; i < S.numel(); ++i) {
42  dSdata[i] = dOutput_data[i] *
43  (Ydata[i] == 1 ? -1.f : static_cast<float>(Sdata[i] >= margin_));
44  }
45  return true;
46 }
47 
48 REGISTER_CPU_OPERATOR(
49  CosineEmbeddingCriterion,
50  CosineEmbeddingCriterionOp<CPUContext>);
51 REGISTER_CPU_OPERATOR(
52  CosineEmbeddingCriterionGradient,
53  CosineEmbeddingCriterionGradientOp<CPUContext>);
54 
55 OPERATOR_SCHEMA(CosineEmbeddingCriterion)
56  .NumInputs(2)
57  .NumOutputs(1)
58  .SetDoc(R"DOC(
59 CosineEmbeddingCriterion takes two inputs: the similarity value and
60 the label, and computes the elementwise criterion output as
61 
62  output = 1 - s, if y == 1
63  max(0, s - margin), if y == -1
64 )DOC")
65  .Input(0, "S", "The cosine similarity as a 1-dim TensorCPU.")
66  .Input(1, "Y", "The label as a 1-dim TensorCPU with int value of 1 or -1.")
67  .Output(0, "loss", "The output loss with the same dimensionality as S.");
68 
69 OPERATOR_SCHEMA(CosineEmbeddingCriterionGradient).NumInputs(3).NumOutputs(1);
70 
71 class GetCosineEmbeddingCriterionGradient : public GradientMakerBase {
72  using GradientMakerBase::GradientMakerBase;
73  vector<OperatorDef> GetGradientDefs() override {
74  return SingleGradientDef(
75  "CosineEmbeddingCriterionGradient",
76  "",
77  vector<string>{I(0), I(1), GO(0)},
78  vector<string>{GI(0)});
79  }
80 };
81 REGISTER_GRADIENT(
82  CosineEmbeddingCriterion,
83  GetCosineEmbeddingCriterionGradient);
84 
85 } // namespace caffe2
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
Definition: blob.h:13