Line data Source code
1 : // SPDX-License-Identifier: Apache-2.0
2 : /**
3 : * Copyright (C) 2020 Jijoong Moon <jijoong.moon@samsung.com>
4 : *
5 : * @file reduce_mean_layer.cpp
6 : * @date 25 Nov 2021
7 : * @see https://github.com/nnstreamer/nntrainer
8 : * @author Parichay Kapoor <pk.kapoor@samsung.com>
9 : * @bug No known bugs except for NYI items
10 : * @brief This is Reduce Mean Layer Class for Neural Network
11 : */
12 :
13 : #include <layer_context.h>
14 : #include <nntrainer_error.h>
15 : #include <nntrainer_log.h>
16 : #include <node_exporter.h>
17 : #include <reduce_mean_layer.h>
18 :
19 : namespace nntrainer {
20 :
21 : static constexpr size_t SINGLE_INOUT_IDX = 0;
22 :
23 8 : void ReduceMeanLayer::finalize(InitLayerContext &context) {
24 8 : NNTR_THROW_IF(context.getNumInputs() != 1, std::invalid_argument)
25 : << "Reduce mean only supports 1 input for now";
26 :
27 : const TensorDim &in_dim = context.getInputDimensions()[0];
28 8 : TensorDim out_dim = in_dim;
29 :
30 : /**
31 : * if reduce axis is not provided, reduction is performed across all the
32 : * dimensions except the batch
33 : */
34 : auto &reduce_axis = std::get<props::ReduceDimension>(reduce_mean_props);
35 8 : if (reduce_axis.empty()) {
36 0 : out_dim = TensorDim({1, 1, 1, 1});
37 : }
38 :
39 8 : out_dim.setTensorDim(reduce_axis.get(), 1);
40 8 : context.setOutputDimensions({out_dim});
41 8 : }
42 :
43 0 : void ReduceMeanLayer::forwarding(RunLayerContext &context, bool training) {
44 : auto &reduce_axis = std::get<props::ReduceDimension>(reduce_mean_props);
45 0 : if (reduce_axis.empty()) {
46 0 : context.getInput(SINGLE_INOUT_IDX)
47 0 : .average({1, 2, 3}, context.getOutput(SINGLE_INOUT_IDX));
48 : } else {
49 0 : context.getInput(SINGLE_INOUT_IDX)
50 0 : .average(reduce_axis, context.getOutput(SINGLE_INOUT_IDX));
51 : }
52 0 : }
53 :
54 0 : void ReduceMeanLayer::calcDerivative(RunLayerContext &context) {
55 0 : auto &deriv = context.getIncomingDerivative(SINGLE_INOUT_IDX);
56 0 : auto &ret_deriv = context.getOutgoingDerivative(SINGLE_INOUT_IDX);
57 :
58 0 : unsigned int div = static_cast<unsigned int>(ret_deriv.size() / deriv.size());
59 :
60 : /** TODO: optimize this by supporting broadcast in copy */
61 0 : ret_deriv.setZero();
62 0 : ret_deriv.add_i(deriv);
63 :
64 0 : ret_deriv.divide_i(static_cast<float>(div));
65 0 : }
66 :
67 68 : void ReduceMeanLayer::setProperty(const std::vector<std::string> &values) {
68 68 : auto remain_props = loadProperties(values, reduce_mean_props);
69 66 : if (!remain_props.empty()) {
70 : std::string msg = "[ReduceMeanLayer] Unknown Layer Properties count " +
71 4 : std::to_string(remain_props.size());
72 8 : throw exception::not_supported(msg);
73 : }
74 66 : }
75 :
76 0 : void ReduceMeanLayer::exportTo(Exporter &exporter,
77 : const ml::train::ExportMethods &method) const {
78 0 : exporter.saveResult(reduce_mean_props, method, this);
79 0 : }
80 :
81 : } /* namespace nntrainer */
|