Tenncor
dense.hpp
Go to the documentation of this file.
1 
9 #include "eteq/generated/api.hpp"
10 
11 #include "layr/init.hpp"
12 #include "layr/layer.hpp"
13 
14 #ifndef LAYR_DENSE_HPP
15 #define LAYR_DENSE_HPP
16 
17 namespace layr
18 {
19 
21 const std::string dense_weight_key = "weight";
22 
24 const std::string dense_bias_key = "bias";
25 
27 struct DenseBuilder final : public iLayerBuilder
28 {
29  DenseBuilder (std::string label) : label_(label) {}
30 
32  void set_tensor (teq::TensptrT tens, std::string target) override
33  {
34  if (target == dense_weight_key)
35  {
37  return;
38  }
39  else if (target == dense_bias_key)
40  {
42  return;
43  }
44  logs::warnf("attempt to create dense layer "
45  "with unknown tensor `%s` of label `%s`",
46  tens->to_string().c_str(), target.c_str());
47  }
48 
50  void set_sublayer (LayerptrT layer) override {} // dense has no sublayer
51 
53  LayerptrT build (void) const override;
54 
55 private:
56  NodeptrT weight_ = nullptr;
57 
58  NodeptrT bias_ = nullptr;
59 
60  std::string label_;
61 };
62 
64 const std::string dense_layer_key =
66 [](std::string label) -> LBuilderptrT
67 {
68  return std::make_shared<DenseBuilder>(label);
69 });
70 
72 struct Dense final : public iLayer
73 {
74  Dense (teq::DimT nunits, teq::DimT indim,
75  layr::InitF<PybindT> weight_init,
76  layr::InitF<PybindT> bias_init,
77  const std::string& label) :
78  label_(label),
79  weight_(weight_init(teq::Shape({nunits, indim}), dense_weight_key))
80  {
81  tag(weight_->get_tensor(), LayerId(dense_weight_key));
82  if (bias_init)
83  {
84  bias_ = bias_init(teq::Shape({nunits}), dense_bias_key);
85  tag(bias_->get_tensor(), LayerId(dense_bias_key));
86  }
87  }
88 
89  Dense (NodeptrT weight, NodeptrT bias, std::string label) :
90  label_(label),
91  weight_(weight),
92  bias_(bias)
93  {
94  tag(weight_->get_tensor(), LayerId(dense_weight_key));
95  if (bias)
96  {
97  tag(bias_->get_tensor(), LayerId(dense_bias_key));
98  }
99  }
100 
101  Dense (const Dense& other,
102  std::string label_prefix = "")
103  {
104  copy_helper(other, label_prefix);
105  }
106 
107  Dense& operator = (const Dense& other)
108  {
109  if (this != &other)
110  {
111  copy_helper(other);
112  }
113  return *this;
114  }
115 
116  Dense (Dense&& other) = default;
117 
118  Dense& operator = (Dense&& other) = default;
119 
121  Dense* clone (std::string label_prefix = "") const
122  {
123  return static_cast<Dense*>(this->clone_impl(label_prefix));
124  }
125 
127  size_t get_ninput (void) const override
128  {
129  return weight_->shape().at(1);
130  }
131 
133  size_t get_noutput (void) const override
134  {
135  return weight_->shape().at(0);
136  }
137 
139  std::string get_ltype (void) const override
140  {
141  return dense_layer_key;
142  }
143 
145  std::string get_label (void) const override
146  {
147  return label_;
148  }
149 
151  teq::TensptrsT get_contents (void) const override
152  {
153  return {
154  weight_->get_tensor(),
155  nullptr == bias_ ? nullptr : bias_->get_tensor(),
156  };
157  }
158 
160  NodeptrT connect (NodeptrT input) const override
161  {
162  auto out = tenncor::nn::fully_connect({input}, {weight_}, bias_);
163  teq::TensSetT leaves = {
164  input->get_tensor().get(),
165  weight_->get_tensor().get(),
166  };
167  if (bias_)
168  {
169  leaves.emplace(bias_->get_tensor().get());
170  }
171  recursive_tag(out->get_tensor(), leaves, LayerId());
172  return out;
173  }
174 
175 private:
176  iLayer* clone_impl (const std::string& label_prefix) const override
177  {
178  return new Dense(*this, label_prefix);
179  }
180 
181  void copy_helper (const Dense& other, std::string label_prefix = "")
182  {
183  label_ = label_prefix + other.label_;
184  weight_ = NodeptrT(other.weight_->clone());
185  tag(weight_->get_tensor(), LayerId(dense_weight_key));
186  if (other.bias_)
187  {
188  bias_ = NodeptrT(other.bias_->clone());
189  tag(bias_->get_tensor(), LayerId(dense_bias_key));
190  }
191  }
192 
193  std::string label_;
194 
196 
198 };
199 
201 using DenseptrT = std::shared_ptr<Dense>;
202 
203 }
204 
205 #endif // LAYR_DENSE_HPP
NodeptrT bias_
Definition: dense.hpp:197
std::unordered_set< teq::iTensor * > TensSetT
Hash set of raw tensor pointers.
Definition: itensor.hpp:63
Dense(teq::DimT nunits, teq::DimT indim, layr::InitF< PybindT > weight_init, layr::InitF< PybindT > bias_init, const std::string &label)
Definition: dense.hpp:74
const std::string dense_weight_key
Fully connected weight label.
Definition: dense.hpp:21
NodeptrT weight_
Definition: dense.hpp:195
const std::string dense_bias_key
Fully connected bias label.
Definition: dense.hpp:24
std::string label_
Definition: dense.hpp:60
Layer implementation to apply fully_connect functions to weight and optional bias.
Definition: dense.hpp:72
LayerRegistry & get_layer_reg(void)
Return global layer registry reference.
std::shared_ptr< Dense > DenseptrT
Smart pointer of fully connected layer.
Definition: dense.hpp:201
iLayer * clone_impl(const std::string &label_prefix) const override
Definition: dense.hpp:176
DenseBuilder(std::string label)
Definition: dense.hpp:29
static NodeptrT< T > to_node(teq::TensptrT tens)
Return node associated with tensor type.
Definition: inode.hpp:81
void copy_helper(const Dense &other, std::string label_prefix="")
Definition: dense.hpp:181
std::string register_tagr(std::string key, LayerBuildF builder)
Definition: layer.hpp:198
Dense & operator=(const Dense &other)
Definition: dense.hpp:107
Definition: shape.hpp:62
void recursive_tag(teq::TensptrT root, teq::TensSetT ignores, LayerId subs) const
Definition: conv.hpp:16
NodeptrT weight_
Definition: dense.hpp:56
std::shared_ptr< iLayerBuilder > LBuilderptrT
Layer builder smart pointer.
Definition: layer.hpp:179
LayerptrT build(void) const override
Implementation of iLayerBuilder.
Dense(NodeptrT weight, NodeptrT bias, std::string label)
Definition: dense.hpp:89
const std::string layers_key_prefix
String prefixed to every layer key.
Definition: layer.hpp:25
std::function< eteq::VarptrT< T >(teq::Shape, std::string)> InitF
Function that produces a variable given the variable&#39;s shape and label.
Definition: init.hpp:20
Definition: layer.hpp:164
std::string get_ltype(void) const override
Implementation of iLayer.
Definition: dense.hpp:139
teq::TensptrsT get_contents(void) const override
Implementation of iLayer.
Definition: dense.hpp:151
void set_sublayer(LayerptrT layer) override
Implementation of iLayerBuilder.
Definition: dense.hpp:50
Dense(const Dense &other, std::string label_prefix="")
Definition: dense.hpp:101
void tag(teq::TensptrT tensor, LayerId subs) const
std::shared_ptr< iTensor > TensptrT
Tensor smart pointer.
Definition: itensor.hpp:51
std::vector< TensptrT > TensptrsT
Vector of tensor smart pointers.
Definition: itensor.hpp:60
Sublayer type, label, and index encapsulation.
Definition: layer.hpp:35
size_t get_noutput(void) const override
Implementation of iLayer.
Definition: dense.hpp:133
std::string label_
Definition: dense.hpp:193
void set_tensor(teq::TensptrT tens, std::string target) override
Implementation of iLayerBuilder.
Definition: dense.hpp:32
uint16_t DimT
Type used for shape dimension.
Definition: shape.hpp:31
size_t get_ninput(void) const override
Implementation of iLayer.
Definition: dense.hpp:127
std::string get_label(void) const override
Implementation of iLayer.
Definition: dense.hpp:145
Definition: coord.hpp:16
const std::string dense_layer_key
Identifier for fully connected layer.
Definition: dense.hpp:64
std::shared_ptr< iNode< T > > NodeptrT
Smart pointer of node.
Definition: inode.hpp:63
Builder implementation for fully connected layer.
Definition: dense.hpp:27
std::shared_ptr< iLayer > LayerptrT
Smart pointer of layer.
Definition: layer.hpp:159
NodeptrT connect(NodeptrT input) const override
Implementation of iLayer.
Definition: dense.hpp:160
Definition: layer.hpp:121
NodeptrT bias_
Definition: dense.hpp:58
Dense * clone(std::string label_prefix="") const
Return deep copy of this layer with prefixed label.
Definition: dense.hpp:121