diff --git a/include/aidge/aidge.hpp b/include/aidge/aidge.hpp
index 6c4ca93ce28c0a8c769606f07b1badee676423fd..84c5404491223746af89e0bb6f8a7c9a40017133 100644
--- a/include/aidge/aidge.hpp
+++ b/include/aidge/aidge.hpp
@@ -44,6 +44,7 @@
 #include "aidge/operator/FC.hpp"
 #include "aidge/operator/Gather.hpp"
 #include "aidge/operator/GenericOperator.hpp"
+#include "aidge/operator/GlobalAveragePooling.hpp"
 #include "aidge/operator/MatMul.hpp"
 #include "aidge/operator/MaxPooling.hpp"
 #include "aidge/operator/MetaOperator.hpp"
diff --git a/include/aidge/operator/GlobalAveragePooling.hpp b/include/aidge/operator/GlobalAveragePooling.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..71b332bf1dacae1990a0d0ea89c139ce7be38ec2
--- /dev/null
+++ b/include/aidge/operator/GlobalAveragePooling.hpp
@@ -0,0 +1,66 @@
+/********************************************************************************
+ * 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
+ *
+ ********************************************************************************/
+
+#ifndef AIDGE_CORE_OPERATOR_GLOBAL_AVERAGE_POOLING_H_
+#define AIDGE_CORE_OPERATOR_GLOBAL_AVERAGE_POOLING_H_
+
+#include <memory>
+
+#include "aidge/utils/Registrar.hpp"
+#include "aidge/operator/OperatorTensor.hpp"
+#include "aidge/backend/OperatorImpl.hpp"
+#include "aidge/data/Tensor.hpp"
+#include "aidge/data/Data.hpp"
+#include "aidge/graph/Node.hpp"
+#include "aidge/utils/Types.h"
+
+namespace Aidge
+{
+
+    /**
+     * @brief Description for the tensor data structure.
+     * @details Sets the properties of the tensor without actually containing any data.
+     * Contains a pointer to an actual contiguous implementation of data.
+     */
+    class GlobalAveragePooling_Op : public OperatorTensor,
+                                    public Registrable<GlobalAveragePooling_Op, std::string, std::unique_ptr<OperatorImpl>(const GlobalAveragePooling_Op &)>
+    {
+    public:
+        static const std::string Type ;
+
+        GlobalAveragePooling_Op() : OperatorTensor(Type, 1, 0, 1) {}
+
+        GlobalAveragePooling_Op(const GlobalAveragePooling_Op &op) : OperatorTensor(op)
+        {
+            mImpl = op.mImpl ? Registrar<GlobalAveragePooling_Op>::create(op.mOutputs[0]->getImpl()->backend())(*this) : nullptr;
+        }
+
+        std::shared_ptr<Operator> clone() const override { return std::make_shared<GlobalAveragePooling_Op>(*this); }
+
+        void computeOutputDims() override final;
+
+        void setBackend(const std::string &name, DeviceIdx_t device = 0) override
+        {
+            mImpl = Registrar<GlobalAveragePooling_Op>::create(name)(*this);
+            mOutputs[0]->setBackend(name, device);
+        }
+
+        static const std::vector<std::string> getInputsName() { return {"data_input"}; }
+        static const std::vector<std::string> getOutputsName() { return {"data_output"}; }
+    };
+
+    inline std::shared_ptr<Node> GlobalAveragePooling(const std::string &name = "")
+    {
+        return std::make_shared<Node>(std::make_shared<GlobalAveragePooling_Op>(), name);
+    }
+}
+
+#endif /* AIDGE_CORE_OPERATOR_GLOBAL_AVERAGE_POOLING_H_ */
\ No newline at end of file
diff --git a/python_binding/operator/pybind_GlobalAveragePooling.cpp b/python_binding/operator/pybind_GlobalAveragePooling.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3f5cd4d05a4ff87475214c9bc646dc507be3d55c
--- /dev/null
+++ b/python_binding/operator/pybind_GlobalAveragePooling.cpp
@@ -0,0 +1,28 @@
+/********************************************************************************
+ * 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 <pybind11/pybind11.h>
+
+#include "aidge/operator/GlobalAveragePooling.hpp"
+#include "aidge/operator/OperatorTensor.hpp"
+#include "aidge/utils/Attributes.hpp"
+
+namespace py = pybind11;
+namespace Aidge {
+
+void init_GlobalAveragePooling(py::module& m) {
+    py::class_<GlobalAveragePooling_Op, std::shared_ptr<GlobalAveragePooling_Op>, OperatorTensor, Attributes>(m, "GlobalAveragePooling", py::multiple_inheritance())
+    .def("get_inputs_name", &GlobalAveragePooling_Op::getInputsName)
+    .def("get_outputs_name", &GlobalAveragePooling_Op::getOutputsName);
+
+    m.def("Hardmax", &Hardmax, py::arg("name") = "");
+}
+}  // namespace Aidge
\ No newline at end of file
diff --git a/python_binding/pybind_core.cpp b/python_binding/pybind_core.cpp
index ebf73e85583d3300ce68078dc8236001a4db1c96..40ebc92aa872baacb2e7a87060f560d05d615cff 100644
--- a/python_binding/pybind_core.cpp
+++ b/python_binding/pybind_core.cpp
@@ -37,6 +37,7 @@ void init_Erf(py::module&);
 void init_FC(py::module&);
 void init_Gather(py::module&);
 void init_GenericOperator(py::module&);
+void init_GlobalAveragePooling(py::module&);
 void init_LeakyReLU(py::module&);
 void init_MatMul(py::module&);
 void init_MaxPooling(py::module&);
@@ -95,6 +96,7 @@ void init_Aidge(py::module& m){
     init_FC(m);
     init_Gather(m);
     init_GenericOperator(m);
+    init_GlobalAveragePooling(m);
     init_LeakyReLU(m);
     init_MatMul(m);
     init_MaxPooling(m);
diff --git a/src/operator/GlobalAveragePooling.cpp b/src/operator/GlobalAveragePooling.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..39b5fa65a507be6c42feec38ba39d2e3f2ab2e5b
--- /dev/null
+++ b/src/operator/GlobalAveragePooling.cpp
@@ -0,0 +1,36 @@
+/********************************************************************************
+ * 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 <vector>
+
+#include "aidge/operator/GlobalAveragePooling.hpp"
+
+const std::string Aidge::GlobalAveragePooling_Op::Type = "GlobalAveragePooling";
+
+void Aidge::GlobalAveragePooling_Op::computeOutputDims()
+{
+    // error checking
+    if (!getInput(0))
+    {
+        AIDGE_THROW_OR_ABORT(std::runtime_error, "At least one input was not connected");
+    }
+    else if (getInput(0)->dims().size() < 3)
+    {
+        AIDGE_THROW_OR_ABORT(std::runtime_error, "GlobalAveragePool needs at least 3 dimensions input, number of input dim : %lu", getInput(0)->dims().size());
+    }
+    else
+    {
+        // Global average pooling takes each filter, averages its values and uses it as an output(Much like a fancier flatten).
+        //1st dim is batch 2nd is number of filter
+        const std::vector<DimSize_t> out_dims(getInput(0)->dims().at(0), getInput(0)->dims().at(1));
+        mOutputs[0]->resize(out_dims);
+    }
+}
diff --git a/unit_tests/operator/Test_GlobalAveragePooling_Op.cpp b/unit_tests/operator/Test_GlobalAveragePooling_Op.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..355aeb20ba4b5884b01ba0ea84b7db145d7a0829
--- /dev/null
+++ b/unit_tests/operator/Test_GlobalAveragePooling_Op.cpp
@@ -0,0 +1,79 @@
+/********************************************************************************
+ * 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 <catch2/catch_test_macros.hpp>
+#include <cstddef> // std::size_t
+#include <memory>
+#include <random> // std::random_device, std::mt19937, std::uniform_int_distribution
+#include <vector>
+
+#include "aidge/data/Tensor.hpp"
+#include "aidge/operator/GlobalAveragePooling.hpp"
+#include "aidge/operator/OperatorTensor.hpp"
+
+namespace Aidge
+{
+    TEST_CASE("[core/operator] GlobalAveragePooling_Op(computeOutputDims)", "[GlobalAveragePooling][computeOutputDims]")
+    {
+        constexpr std::uint16_t NB_TRIALS = 10;
+        // Create a random number generator
+        std::random_device rd;
+        std::mt19937 gen(rd());
+        std::uniform_int_distribution<std::size_t> dimsDist(1, 10);
+        std::uniform_int_distribution<std::size_t> inf3DimsDistribution(0, 2);
+        std::uniform_int_distribution<std::size_t> sup3DimsDistribution(3, 10);
+
+        // Create the GlobalAveragePooling Operator
+        std::shared_ptr<Node> myGlobAvgPool = GlobalAveragePooling();
+        auto op = std::static_pointer_cast<OperatorTensor>(myGlobAvgPool->getOperator());
+
+        // input_0
+        std::shared_ptr<Tensor> input_T = std::make_shared<Tensor>();
+        SECTION("input association")
+        {
+            REQUIRE_THROWS(op->computeOutputDims());
+        }
+        op->associateInput(0, input_T);
+
+        SECTION("nbDim < 3")
+        {
+            const std::size_t nb_dims = inf3DimsDistribution(gen) + 1;
+            for (uint16_t trial; trial < NB_TRIALS; ++trial)
+            {
+                std::vector<std::size_t> dims0(nb_dims);
+                for (uint16_t i; i < nb_dims; ++i)
+                {
+                    dims0[i] = dimsDist(gen) + 1;
+                }
+
+                input_T->resize(dims0);
+                REQUIRE_THROWS(op->computeOutputDims());
+            }
+        }
+
+        SECTION("nbDim > 3")
+        {
+            const std::size_t nb_dims = inf3DimsDistribution(gen) + 1;
+            for (uint16_t trial; trial < NB_TRIALS; ++trial)
+            {
+                std::vector<std::size_t> dims0(nb_dims);
+                for (uint16_t i; i < nb_dims; ++i)
+                {
+                    dims0[i] = dimsDist(gen) + 1;
+                }
+
+                input_T->resize(dims0);
+                REQUIRE_NOTHROW(op->computeOutputDims());
+                REQUIRE((op->getOutput(0)->dims().size()) == static_cast<size_t>(2));
+            }
+        }
+    }
+} // namespace Aidge