Skip to content
Snippets Groups Projects
Commit 967ca645 authored by Houssem ROUIS's avatar Houssem ROUIS
Browse files

add Accuracy metric

parent b671d4a2
No related branches found
No related tags found
2 merge requests!17version 0.2.0,!15Learning backend cuda
/********************************************************************************
* Copyright (c) 2024 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_LEARNING_METRICS_ACCURACY_H_
#define AIDGE_LEARNING_METRICS_ACCURACY_H_
#include <cstddef> // std::size_t
#include <memory>
#include "aidge/data/Tensor.hpp"
namespace Aidge {
namespace metrics {
/**
* @brief Compute the Accuracy.
* This function returns the loss and set the ``grad()`` of the prediction
* input.
* @param prediction Tensor returned by the Aidge Graph, it is important that
* this tensor is not a copy as overwise the backward function will not have a
* gradient to start.
* @param target Tensor representing the ground truth, it must be one hot encoded.
* @param axis The classes axis.
*/
Tensor Accuracy(std::shared_ptr<Tensor>& prediction,
const std::shared_ptr<Tensor>& target,
std::int32_t axis);
} // namespace Metrics
} // namespace Aidge
#endif /* AIDGE_LEARNING_METRICS_ACCURACY_H_ */
/********************************************************************************
* Copyright (c) 2024 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#include <pybind11/pybind11.h>
#include "aidge/data/Tensor.hpp"
#include "aidge/graph/GraphView.hpp"
#include "aidge/learning/metrics/Accuracy.hpp"
namespace py = pybind11;
namespace Aidge {
void init_Accuracy(py::module &m) {
auto m_metric = m.def_submodule("metrics", "Submodule dedicated to evaluation metrics");
m_metric.def("Accuracy",&metrics::Accuracy, py::arg("prediction"), py::arg("target"), py::arg("axis"));
}
} // namespace Aidge
......@@ -21,12 +21,14 @@ void init_Optimizer(py::module&);
void init_SGD(py::module&);
void init_Adam(py::module&);
void init_LRScheduler(py::module&);
void init_Accuracy(py::module&);
void init_Aidge(py::module& m) {
init_Loss(m);
init_Optimizer(m);
init_SGD(m);
init_Adam(m);
init_Accuracy(m);
init_LRScheduler(m);
}
......
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#include <memory>
#include <numeric> // std::iota
#include "aidge/data/Tensor.hpp"
#include "aidge/graph/GraphView.hpp"
#include "aidge/graph/OpArgs.hpp"
#include "aidge/learning/metrics/Accuracy.hpp"
#include "aidge/operator/OperatorTensor.hpp"
#include "aidge/operator/ArgMax.hpp"
#include "aidge/operator/ReduceSum.hpp"
#include "aidge/operator/And.hpp"
#include "aidge/recipes/GraphViewHelper.hpp"
#include "aidge/scheduler/Scheduler.hpp"
#include "aidge/scheduler/SequentialScheduler.hpp"
Aidge::Tensor Aidge::metrics::Accuracy(std::shared_ptr<Tensor>& prediction,
const std::shared_ptr<Tensor>& target,
std::int32_t axis) {
/*
Implementation note:
Accuracy is computed using a graph in order to not be backend dependant.
The graph used is the following:
pred->ArgMax
->And->ReduceSum
label->ArgMax
*/
AIDGE_ASSERT(target->dims().size() == 2,
"Label must have two dims: [BatchSize, NbChannel]");
std::shared_ptr<Tensor> outputGrad = prediction->grad();
AIDGE_ASSERT(prediction->backend() == target->backend(),
"'prediction' and 'target' Tensors must be on the "
"same backend. Found {} and {}.\n",
prediction->backend(), target->backend());
AIDGE_ASSERT(prediction->dims() == target->dims(),
"'prediction' (shape {}) and 'target' (shape {}) Tensors must "
"have the same dimensions.\n",
prediction->dims(), target->dims());
AIDGE_ASSERT(prediction->dataType() == target->dataType(),
"'prediction' (data type {}) and 'target' (data type {}) "
"Tensors must have the same data type.\n",
prediction->dataType(), target->dataType());
// Create graph nodes and connections
const std::shared_ptr<Node> argmax_perd_node = ArgMax(axis);
const std::shared_ptr<Node> argmax_target_node = ArgMax(axis);
const std::shared_ptr<Node> and_node = And();
const std::shared_ptr<Node> rs_node = ReduceSum();
const std::shared_ptr<Node> pred_node = Producer(prediction, "pred");
pred_node->addChild(argmax_perd_node);
const std::shared_ptr<Node> label_node = Producer(target, "label");
label_node->addChild(argmax_target_node);
argmax_perd_node->addChild(and_node,0,0);
argmax_target_node->addChild(and_node,0,1);
// and_node->addChild(rs_node,0,0);
// Create the graph
std::shared_ptr<GraphView> gv_local =
Sequential({ and_node, rs_node});
gv_local->add({pred_node,argmax_perd_node, label_node,argmax_target_node});
gv_local->compile(prediction->getImpl()->backend(), prediction->dataType());
SequentialScheduler ss_local{gv_local};
ss_local.forward(false);
// TODO: way too complicated to access
const std::shared_ptr<OperatorTensor> res =
std::dynamic_pointer_cast<OperatorTensor>(rs_node->getOperator());
std::shared_ptr<Tensor> fallback;
return res->getOutput(0)->refFrom(fallback, "cpu");
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment