2727#pragma once
2828#include " layer.h"
2929#include " product.h"
30+ #include " dropout.h"
3031
3132namespace tiny_cnn {
3233
3334// normal
34- template <typename N, typename Activation>
35+ template <typename N, typename Activation, typename Filter = filter_none >
3536class fully_connected_layer : public layer <N, Activation> {
3637public:
3738 typedef layer<N, Activation> Base;
3839 typedef typename Base::Optimizer Optimizer;
3940
40- fully_connected_layer (int in_dim, int out_dim) : layer<N, Activation>(in_dim, out_dim, in_dim * out_dim, out_dim) {}
41+ fully_connected_layer (int in_dim, int out_dim)
42+ : layer<N, Activation>(in_dim, out_dim, in_dim * out_dim, out_dim), filter_(out_dim) {}
4143
4244 int connection_size () const {
4345 return this ->in_size_ * this ->out_size_ + this ->out_size_ ;
@@ -58,10 +60,13 @@ class fully_connected_layer : public layer<N, Activation> {
5860 this ->output_ [index][r] = this ->a_ .f (z);
5961 }
6062
61- return this ->next_ ? this ->next_ ->forward_propagation (this ->output_ [index], index) : this ->output_ [index];
63+ auto & this_out = this ->filter_ .filter_fprop (this ->output_ [index], index);
64+
65+ return this ->next_ ? this ->next_ ->forward_propagation (this_out, index) : this_out;
6266 }
6367
6468 const vec_t & back_propagation (const vec_t & current_delta, int index) {
69+ const vec_t & curr_delta = this ->filter_ .filter_bprop (current_delta, index);
6570 const vec_t & prev_out = this ->prev_ ->output (index);
6671 const activation& prev_h = this ->prev_ ->activation_function ();
6772 vec_t & prev_delta = this ->prev_delta_ [index];
@@ -73,7 +78,7 @@ class fully_connected_layer : public layer<N, Activation> {
7378 // for (int r = 0; r < this->out_size_; r++)
7479 // prev_delta[c] += current_delta[r] * this->W_[c*this->out_size_+r];
7580
76- prev_delta[c] = vectorize::dot (¤t_delta [0 ], &this ->W_ [c*this ->out_size_ ], this ->out_size_ );
81+ prev_delta[c] = vectorize::dot (&curr_delta [0 ], &this ->W_ [c*this ->out_size_ ], this ->out_size_ );
7782 prev_delta[c] *= prev_h.df (prev_out[c]);
7883 }
7984
@@ -83,11 +88,11 @@ class fully_connected_layer : public layer<N, Activation> {
8388 dW[c*this->out_size_+i] += current_delta[i] * prev_out[c];*/
8489
8590 for (int c = 0 ; c < this ->in_size_ ; c++) {
86- vectorize::muladd (¤t_delta [0 ], prev_out[c], r.end () - r.begin (), &dW[c*this ->out_size_ + r.begin ()]);
91+ vectorize::muladd (&curr_delta [0 ], prev_out[c], r.end () - r.begin (), &dW[c*this ->out_size_ + r.begin ()]);
8792 }
8893
8994 for (int i = r.begin (); i < r.end (); i++)
90- db[i] += current_delta [i];
95+ db[i] += curr_delta [i];
9196 });
9297
9398 return this ->prev_ ->back_propagation (this ->prev_delta_ [index], index);
@@ -101,7 +106,7 @@ class fully_connected_layer : public layer<N, Activation> {
101106
102107 for (int c = 0 ; c < this ->in_size_ ; c++)
103108 for (int r = 0 ; r < this ->out_size_ ; r++)
104- this ->Whessian_ [c*this ->out_size_ + r] += current_delta2[r] * prev_out[c] * prev_out[c];
109+ this ->Whessian_ [c*this ->out_size_ + r] += current_delta2[r] * prev_out[c] * prev_out[c];
105110
106111 for (int r = 0 ; r < this ->out_size_ ; r++)
107112 this ->bhessian_ [r] += current_delta2[r];
@@ -110,13 +115,16 @@ class fully_connected_layer : public layer<N, Activation> {
110115 this ->prev_delta2_ [c] = 0.0 ;
111116
112117 for (int r = 0 ; r < this ->out_size_ ; r++)
113- this ->prev_delta2_ [c] += current_delta2[r] * this ->W_ [c*this ->out_size_ + r] * this ->W_ [c*this ->out_size_ + r];
118+ this ->prev_delta2_ [c] += current_delta2[r] * this ->W_ [c*this ->out_size_ + r] * this ->W_ [c*this ->out_size_ + r];
114119
115120 this ->prev_delta2_ [c] *= prev_h.df (prev_out[c]) * prev_h.df (prev_out[c]);
116121 }
117122
118123 return this ->prev_ ->back_propagation_2nd (this ->prev_delta2_ );
119124 }
125+
126+ protected:
127+ Filter filter_;
120128};
121129
122130} // namespace tiny_cnn
0 commit comments