Loading...
Searching...
No Matches
dense_layer.h
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-only
2// Copyright (C) 2026 Artificial Intelligence Techniques, S.L. and Roberto López González
3
4#pragma once
5
12
13namespace opennn
14{
15
16class Dense final : public Layer
17{
18public:
19
20 Dense(const Shape& = {},
21 const Shape& = {},
22 const string& = "Tanh",
24 const string& = "dense_layer");
25
26 Shape get_output_shape() const override;
27
28 Index get_input_features() const { return input_shape.empty() ? 0 : input_shape.back(); }
29
30 const ActivationFunction& get_activation_function() const { return activation_operator.activation_function; }
31 ActivationFunction get_output_activation() const override { return activation_operator.activation_function; }
32
33 bool get_batch_normalization() const { return batch_norm.active(); }
34
35 vector<TensorSpec> get_forward_specs(Index) const override;
36 vector<TensorSpec> get_backward_specs(Index) const override;
37 bool backward_uses_forward_output() const noexcept override { return gated || batch_norm.active() || activation_operator.activation_function != ActivationFunction::Identity; }
38 bool preserves_output_delta_during_backward() const noexcept override { return !backward_uses_forward_output() && !dropout.active(); }
39 bool folds_input_delta_addend(size_t input) const noexcept override
40 {
41 return input == 0 && combination.folds_input_delta_addend && !gated && !tied_source
42 && !combination.accumulate_input_delta && !combination.drelu_source;
43 }
44
45 ForwardSlotKind get_forward_slot_kind(size_t slot) const override
46 {
47 if ((!gated && slot == ActivationView)
48 || slot == DreluMask
49 || slot == DropoutMask)
52 }
53
54 void set(const Shape& = {},
55 const Shape& = {},
56 const string& = "Tanh",
58 const string& = "dense_layer");
59
60 bool accepts_input_rank(Index rank) const override { return is_one_of(rank, 1, 2); }
61
62 void apply_input_shape(const Shape&) override;
63 void set_output_shape(const Shape&) override;
64 void on_compute_dtype_changed() override { configure_operators(); }
65
66 void set_activation_function(const string&);
67 void set_batch_normalization(bool enable);
68
69 void set_use_bias(bool use_bias) { combination.use_bias = use_bias; up_combination.use_bias = use_bias; }
70 bool get_use_bias() const { return combination.use_bias; }
71
72 void set_gated(bool new_gated);
73 bool get_gated() const { return gated; }
74
75 void set_transposed_inference(bool v) { combination.transposed_inference_preferred = v; }
76 bool get_transposed_inference() const { return combination.transposed_inference_preferred; }
77
79 void set_tied_weight(const TiedWeight&) override;
80 TiedWeight get_tied_weight() const override
81 {
82 return tied_source ? TiedWeight{tied_source, 0, 0} : TiedWeight{};
83 }
84 void set_dropout_rate(float new_rate)
85 {
86 const bool was_active = dropout.active();
87 dropout.set_rate(new_rate);
88 if (was_active != dropout.active())
89 configure_operators();
90 }
91 void set_momentum(float);
92
93 bool try_wire_drelu_fusion(Dense& producer, Index producer_layer);
94
95 bool try_wire_single_output_relu_fusion(Dense& producer, Index producer_layer);
97 bool single_output_relu_fusion_wired() const { return combination.fuse_input_relu; }
99 bool drelu_fusion_wired() const { return combination.drelu_source != nullptr; }
100
102
103 void read_JSON_body(const Json*) override;
104 void write_JSON_body(JsonWriter&) const override;
105 void on_loaded() override { configure_operators(); }
106
107 string write_expression(const vector<string>&,
108 const vector<string>&) const override;
109
110private:
111
112 Index output_features = 0;
113
114 bool gated = false;
115
116 const Layer* tied_source = nullptr;
117
118 CombinationOperator combination;
119 CombinationOperator up_combination;
120 SwiGLUOperator swiglu;
121 ActivationOperator activation_operator;
123 DropoutOperator dropout;
124
125 enum Forward
126 {
127 Input,
128 CombinationView,
129 BatchNormMean,
130 BatchNormInverseVariance,
131 ActivationView,
132 DreluMask,
133 DropoutMask,
134 Output
135 };
136
137 void configure_operators();
138 bool saves_pre_dropout_activation() const;
139};
140
141}
void read_JSON_body(const Json *) override
void set_activation_function(const string &)
void set_tied_weight(const TiedWeight &) override
vector< TensorSpec > get_backward_specs(Index) const override
void write_JSON_body(JsonWriter &) const override
bool single_output_relu_fusion_wired() const
Definition dense_layer.h:97
void set_transposed_inference(bool v)
Definition dense_layer.h:75
bool backward_uses_forward_output() const noexcept override
Definition dense_layer.h:37
void set_batch_normalization(bool enable)
ActivationFunction get_output_activation() const override
Definition dense_layer.h:31
void set_momentum(float)
bool folds_input_delta_addend(size_t input) const noexcept override
Definition dense_layer.h:39
vector< TensorSpec > get_forward_specs(Index) const override
void reset_single_output_relu_fusion()
void set_dropout_rate(float new_rate)
Definition dense_layer.h:84
void on_compute_dtype_changed() override
Definition dense_layer.h:64
void set(const Shape &={}, const Shape &={}, const string &="Tanh", BatchNormalization=BatchNormalization::No, const string &="dense_layer")
Shape get_output_shape() const override
bool try_wire_drelu_fusion(Dense &producer, Index producer_layer)
bool get_batch_normalization() const
Definition dense_layer.h:33
void set_output_shape(const Shape &) override
const ActivationFunction & get_activation_function() const
Definition dense_layer.h:30
TiedWeight get_tied_weight() const override
Definition dense_layer.h:80
Dense * drelu_producer
Definition dense_layer.h:101
Dense(const Shape &={}, const Shape &={}, const string &="Tanh", BatchNormalization=BatchNormalization::No, const string &="dense_layer")
bool accepts_input_rank(Index rank) const override
Definition dense_layer.h:60
void set_gated(bool new_gated)
string write_expression(const vector< string > &, const vector< string > &) const override
void apply_input_shape(const Shape &) override
bool preserves_output_delta_during_backward() const noexcept override
Definition dense_layer.h:38
void set_tied_weight_source(const Layer *)
bool drelu_fusion_wired() const
Definition dense_layer.h:99
void set_use_bias(bool use_bias)
Definition dense_layer.h:69
bool get_use_bias() const
Definition dense_layer.h:70
Index get_input_features() const
Definition dense_layer.h:28
bool get_gated() const
Definition dense_layer.h:73
ForwardSlotKind get_forward_slot_kind(size_t slot) const override
Definition dense_layer.h:45
void reset_drelu_fusion()
bool try_wire_single_output_relu_fusion(Dense &producer, Index producer_layer)
void on_loaded() override
Definition dense_layer.h:105
bool get_transposed_inference() const
Definition dense_layer.h:76
Definition json.h:92
Definition json.h:24
Layer(LayerType type, Trainability trainability=Trainability::Trainable)
Definition layer.h:210
Shape input_shape
Definition layer.h:219
Definition configuration.h:10
constexpr bool is_one_of(const T &value, const Candidates &... candidates)
Definition opennn_types.h:273
BatchNormalization
Definition layer.h:19
@ No
Definition layer.h:19
ForwardSlotKind
Definition layer.h:18
@ TrainingOnly
Definition layer.h:18
@ Pooled
Definition layer.h:18
ActivationFunction
Definition configuration.h:39
@ Identity
Definition configuration.h:39
Definition activation_operator.h:12
Definition batch_norm_operator.h:20
Definition combination_operator.h:12
Definition dropout_operator.h:15
Definition layer.h:43
Definition tensor_types.h:172
Definition swiglu_operator.h:16