DaNNet
dnn_layer_dense.h
Go to the documentation of this file.
1 // Copyright 2019 Claes Rolen (www.rolensystems.com)
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 namespace dnn
17 {
21 
30 class layer_dense: public layer
31 {
32 private:
33 public:
39  layer_dense(const arma::uword n_rows):layer()
40  {
41  N_cols_right = 1;
42  N_rows_right = n_rows;
43  N_channels_right = 1;
45  type = "Dense";
46  id = type+"("+std::to_string(N_left)+","+std::to_string(N_right)+")";
47  }
48 
49 
55  void init(void)
56  {
57  layer::init();
58  W.set_size(N_right, N_left,1);
59  B.set_size(N_right, 1);
60  id = type+"("+std::to_string(N_left)+","+std::to_string(N_right)+")";
61  train_par = true;
62 
63  // Init W and B
65  B.zeros();
66  }
67 
73  void prop(void)
74  {
75  Y1 = W.slice(0)*(left->get_Y1());
76  if(add_bias) Y1+= B;
77  }
78 
84  void prop_mb(void)
85  {
86  Y = W.slice(0)*(*(left->get_Y_ptr()));
87  if(add_bias) Y.each_col()+=B;
88  }
89 
95  void backprop(void)
96  {
97  Dleft = (W.slice(0).t())*(*(right->get_Dleft_ptr()));
98  }
99 
105  void update(void)
106  {
107  if(train_par==true)
108  {
109  const DNN_Dtype nrm = (DNN_Dtype) 1.0/N_batch;
110  arma::Cube<DNN_Dtype> a(arma::size(W));
111  a.slice(0)=(*(right->get_Dleft_ptr())*(*(left->get_Y_ptr())).t())*nrm;
112 
113  if(add_bias)
114  {
115  opt_alg->apply(W,B,a,sum(*(right->get_Dleft_ptr()),1)*nrm);
116  }
117  else
118  {
119  arma::Mat<DNN_Dtype> m={1.0};
120  opt_alg->apply(W,m,a,m);
121  }
122  }
123  }
124 
129  arma::uword get_nrof_params(void)
130  {
131  return N_left*N_right+N_right;
132  }
133 
137  void disp(void)
138  {
139  layer::disp();
140  std::cout << "Opt algorithm: " << opt_alg->get_algorithm() << std::endl;
141  std::cout << "Nr of inputs: " << get_nrof_inputs() << std::endl;
142  std::cout << "Nr of outputs: " << get_nrof_outputs() << std::endl;
143  }
144 
153  arma::Mat<DNN_Dtype> weights2img(const arma::uword R, const arma::uword C)
154  {
155  const arma::uword Nimg = W.slice(0).n_elem/(R*C);
156  const arma::uword PR = static_cast<arma::uword>(floor(sqrt(Nimg)));
157  const arma::uword PC = static_cast<arma::uword>(ceil(Nimg/(1.0*PR)));
158  arma::Mat<DNN_Dtype> ZZ(PR*R,PC*C,arma::fill::zeros);
159 
160  arma::Col<DNN_Dtype> Iv=arma::vectorise(W.slice(0).t());
161 
162  arma::uword r=0,c=0;
163  DNN_Dtype *iptr=Iv.memptr();
164  for(arma::uword m=0; m<Nimg; m++)
165  {
166  const arma::Mat<DNN_Dtype> Z(iptr,R,C);
167  iptr+=R*C;
168  ZZ(r,c,arma::size(R,C)) = Z+B(m);
169  c+=C;
170  if(c >= PC*C)
171  {
172  r+=R;
173  c=0;
174  }
175  }
176  return ZZ;
177  }
178 
179 }; // End class layer_dense
181 } // End namespace dnn
void prop(void)
Forward propagation though layer.
opt * opt_alg
Pointer to optimizer.
std::string type
Layer type string.
arma::Mat< DNN_Dtype > Y
Output buffer mini batch [N_right,N_batch].
void update(void)
Updates the trainable parameters.
layer * right
Pointer to next layer.
arma::uword N_channels_right
Output channels, number of filters.
arma::Mat< DNN_Dtype > weights2img(const arma::uword R, const arma::uword C)
Generate an image of the weights.
arma::Mat< DNN_Dtype > Dleft
Error buffer [N_left,N_batch].
layer_dense(const arma::uword n_rows)
Dense layer constructor.
Layer base class.
arma::Mat< DNN_Dtype > Y1
Output buffer [N_right,1].
void prop_mb(void)
Forward mini batch propagation though layer.
virtual arma::uword get_nrof_inputs(void)
Get total number of layer inputs.
void init_weights(T &w, arma::uword fan_in, arma::uword fan_out, INIT_W_ALG alg, INIT_W_DIST dist)
Initiate weights.
virtual arma::uword get_nrof_outputs(void)
Get total number of layer outputs.
virtual arma::Mat< DNN_Dtype > get_Y1(void)
Get output buffer.
virtual void init(void)
Initialize layer.
void init(void)
Initialization of layer.
void disp(void)
Display info about layer.
arma::Mat< DNN_Dtype > B
Bias.
virtual arma::Mat< DNN_Dtype > * get_Dleft_ptr(void)
Get error buffer pointer - mini batch.
arma::uword get_nrof_params(void)
Get info about number of trainable parameters in layer.
virtual void disp(void)
Display info about layer.
float DNN_Dtype
Data type used in the network (float or double)
Definition: dnn.h:28
arma::uword N_left
Total size left.
arma::uword N_rows_right
Output rows.
virtual void apply(arma::Cube< DNN_Dtype > &W, arma::Mat< DNN_Dtype > &B, const arma::Cube< DNN_Dtype > &Wgrad, const arma::Mat< DNN_Dtype > &Bgrad)=0
Apply the optimizer to the layer parameters.
arma::Cube< DNN_Dtype > W
Weights.
void backprop(void)
Backpropagation of mini batch propagation though layer.
arma::uword N_batch
Mini batch size.
bool train_par
Enable training.
Definition: dnn.h:22
virtual std::string get_algorithm(void)
Get the optimizer algorithm information.
Definition: dnn_opt.h:67
arma::uword N_right
Total size right.
layer * left
Pointer to previous layer.
arma::uword N_cols_right
Output cols.
A fully connected/dense layer class.
virtual arma::Mat< DNN_Dtype > * get_Y_ptr(void)
Get output buffer pointer - mini batch.
bool add_bias
Enable bias.