LBANN  0.103.0
LivermoreBigArtificialNeuralNetworkToolkit
categorical_accuracy.hpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2023, Lawrence Livermore National Security, LLC.
3 // Produced at the Lawrence Livermore National Laboratory.
4 // Written by the LBANN Research Team (B. Van Essen, et al.) listed in
5 // the CONTRIBUTORS file. <lbann-dev@llnl.gov>
6 //
7 // LLNL-CODE-697807.
8 // All rights reserved.
9 //
10 // This file is part of LBANN: Livermore Big Artificial Neural Network
11 // Toolkit. For details, see http://software.llnl.gov/LBANN or
12 // https://github.com/LLNL/LBANN.
13 //
14 // Licensed under the Apache License, Version 2.0 (the "Licensee"); you
15 // may not use this file except in compliance with the License. You may
16 // obtain a copy of the License at:
17 //
18 // http://www.apache.org/licenses/LICENSE-2.0
19 //
20 // Unless required by applicable law or agreed to in writing, software
21 // distributed under the License is distributed on an "AS IS" BASIS,
22 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
23 // implied. See the License for the specific language governing
24 // permissions and limitations under the license.
26 
27 #ifndef LBANN_LAYERS_LOSS_CATEGORICAL_ACCURACY_HPP_INCLUDED
28 #define LBANN_LAYERS_LOSS_CATEGORICAL_ACCURACY_HPP_INCLUDED
29 
32 #include "lbann/proto/layers.pb.h"
33 
34 namespace lbann {
35 
47 template <typename TensorDataType, data_layout T_layout, El::Device Dev>
48 class categorical_accuracy_layer : public data_type_layer<TensorDataType>
49 {
50 public:
52  : data_type_layer<TensorDataType>(comm)
53  {
55  }
56 
57  categorical_accuracy_layer* copy() const override
58  {
59  return new categorical_accuracy_layer(*this);
60  }
61 
63 
65  template <typename ArchiveT>
66  void serialize(ArchiveT& ar);
67 
69 
70  std::string get_type() const override { return "categorical accuracy"; }
71  data_layout get_data_layout() const override { return T_layout; }
72  El::Device get_device_allocation() const override { return Dev; }
73  bool can_run_inplace() const override { return false; }
74  int get_backprop_requirements() const override { return ERROR_SIGNALS; }
75 
76 #ifdef LBANN_HAS_ONNX
77  void fill_onnx_node(onnx::GraphProto& graph) const override;
78 #endif // LBANN_HAS_ONNX
79 
80  void setup_dims() override;
81 
82  void fp_compute() override;
83 
84 protected:
86  void write_specific_proto(lbann_data::Layer& proto) const final;
87 
88  friend class cereal::access;
90 };
91 
92 template <typename T, data_layout L, El::Device D>
94  lbann_data::Layer& proto) const
95 {
96  proto.set_datatype(proto::ProtoDataType<T>);
97  proto.mutable_categorical_accuracy();
98 }
99 
100 #ifdef LBANN_HAS_ONNX
101 template <typename T, data_layout L, El::Device D>
103  onnx::GraphProto& graph) const
104 {
105  auto* shape = graph.add_initializer();
106  shape->set_name(this->get_name() + "_shape_0");
107  shape->set_data_type(onnx::TensorProto::INT64);
108  shape->add_dims(2);
109  shape->add_int64_data(0);
110  shape->add_int64_data(-1);
111  shape->set_doc_string(this->get_name() + " shape");
112 
113  auto* equal = graph.add_node();
114 
115  for (auto const* parent : this->get_parent_layers()) {
116  size_t idx = parent->find_child_layer_index(*this);
117  size_t prt_idx = this->find_parent_layer_index(*parent);
118 
119  // x = Reshape(data=x, shape=[0,-1])
120  // y = Reshape(data=y, shape=[0,-1])
121  auto* reshape = graph.add_node();
122  reshape->add_input(parent->get_name() + "_" + std::to_string(idx));
123  reshape->add_input(this->get_name() + "_shape_0");
124  reshape->add_output(this->get_name() + "_reshape_" +
125  std::to_string(prt_idx));
126  reshape->set_name(this->get_name() + "_reshape" + std::to_string(prt_idx));
127  reshape->set_op_type("Reshape");
128  reshape->set_domain("");
129  reshape->set_doc_string("Reshape node for Categorical Accuracy Layer");
130 
131  // xmax = ArgMax(data=x, axis=-1)
132  // ymax = ArgMax(data=y, axis=-1)
133  auto* argmax = graph.add_node();
134  argmax->add_input(reshape->output(0));
135  auto* attribute = argmax->add_attribute();
136  attribute->set_name("axis");
137  attribute->set_type(onnx::AttributeProto::INT);
138  attribute->set_i(-1);
139  argmax->add_output(this->get_name() + "_argmax_" + std::to_string(prt_idx));
140  argmax->set_name(this->get_name() + "_argmax_" + std::to_string(prt_idx));
141  argmax->set_op_type("ArgMax");
142  argmax->set_domain("");
143  argmax->set_doc_string("Argmax node for Categorical Accuracy Layer");
144 
145  // z = Equal(A=xmax, B=ymax)
146  equal->add_input(argmax->output(0));
147  }
148  equal->add_output(this->get_name() + "_equal_0");
149  equal->set_name(this->get_name() + "_equal_0");
150  equal->set_op_type("Equal");
151  equal->set_domain("");
152  equal->set_doc_string("Equal node for Categorical Accuracy Layer");
153 
154  // z = Cast(input=z, to=float)
155  auto* cast = graph.add_node();
156  cast->add_input(equal->output(0));
157  auto* attribute = cast->add_attribute();
158  attribute->set_name("to");
159  attribute->set_type(onnx::AttributeProto::INT);
160  attribute->set_i(onnx::TensorProto::FLOAT);
161  for (auto const* child : this->get_child_layers()) {
162  auto idx = this->find_child_layer_index(*child);
163  cast->add_output(this->get_name() + "_" + std::to_string(idx));
164  }
165  cast->set_name(this->get_name() + "_cast_0");
166  cast->set_op_type("Cast");
167  cast->set_domain("");
168  cast->set_doc_string("Cast node for Categorical Accuracy Layer");
169 }
170 #endif // LBANN_HAS_ONNX
171 
172 #ifndef LBANN_CATEGORICAL_ACCURACY_LAYER_INSTANTIATE
173 
174 #define PROTO_DEVICE(T, Device) \
175  extern template class categorical_accuracy_layer<T, \
176  data_layout::DATA_PARALLEL, \
177  Device>; \
178  extern template class categorical_accuracy_layer< \
179  T, \
180  data_layout::MODEL_PARALLEL, \
181  Device>
182 
184 #undef PROTO_DEVICE
185 
186 #endif // LBANN_CATEGORICAL_ACCURACY_LAYER_INSTANTIATE
187 
188 } // namespace lbann
189 
190 #endif // LBANN_LAYERS_LOSS_CATEGORICAL_ACCURACY_HPP_INCLUDED
El::Device get_device_allocation() const override
Get the device allocation for the data tensors. We assume that the decice allocation of the previous ...
void write_specific_proto(lbann_data::Layer &proto) const final
categorical_accuracy_layer * copy() const override
Copy function. This function dynamically allocates memory for a layer instance and instantiates a cop...
void setup_dims() override
Setup tensor dimensions Called by the &#39;setup&#39; function. If there are any input tensors, the base method sets all uninitialized output tensor dimensions equal to the first input tensor dimensions.
data_layout get_data_layout() const override
Get data layout of the data tensors. We assume that the data layouts of the previous activations...
constexpr El::Device Device
size_t find_parent_layer_index(const Layer &l) const
std::string to_string(El::Device const &d)
void fp_compute() override
Apply layer operation. Called by the &#39;forward_prop&#39; function. Given the input tensors, the output tensors are populated with computed values.
std::vector< const Layer * > get_parent_layers() const
std::string get_name() const
Get the layer instance&#39;s name.
Definition: layer.hpp:332
std::vector< const Layer * > get_child_layers() const
bool can_run_inplace() const override
If True, the computation can run in-place (feeding each input activations tensor as the corresponding...
data_layout
Data layout that is optimized for different modes of parallelism.
Definition: base.hpp:218
int get_backprop_requirements() const override
Returns the necessary tensors for computing backpropagation.
size_t find_child_layer_index(const Layer &l) const
std::string get_type() const override
Get the layer type&#39;s name.
void set_name(const std::string name)
Set the layer instance&#39;s name. Each layer in a model should have a unique, preferably human-readable...
Definition: layer.hpp:319
int m_expected_num_parent_layers
Definition: layer.hpp:838