33 #include "tiny_dnn/util/util.h"
34 #include "tiny_dnn/util/image.h"
35 #include "tiny_dnn/layers/partial_connected_layer.h"
36 #include "tiny_dnn/activations/activation_function.h"
41 template <
typename Activation>
42 void tiny_average_unpooling_kernel(
bool parallelize,
43 const std::vector<tensor_t*>& in_data,
44 std::vector<tensor_t*>& out_data,
45 const shape3d& out_dim,
47 std::vector<
typename partial_connected_layer<Activation>::wi_connections>& out2wi,
49 for (
size_t sample = 0; sample < in_data[0]->size(); sample++) {
50 const vec_t& in = (*in_data[0])[sample];
51 const vec_t& W = (*in_data[1])[0];
52 const vec_t& b = (*in_data[2])[0];
53 vec_t& out = (*out_data[0])[sample];
54 vec_t& a = (*out_data[1])[sample];
56 auto oarea = out_dim.area();
58 for (
size_t d = 0; d < out_dim.depth_; ++d) {
59 float_t weight = W[d];
61 for (
size_t i = 0; i < oarea; ++i, ++idx) {
62 const auto& connections = out2wi[idx];
63 float_t value = float_t(0);
64 for (
auto connection : connections)
65 value += in[connection.second];
72 assert(out.size() == out2wi.size());
73 for_i(parallelize, out2wi.size(), [&](
int i) {
80 template<
typename Activation>
81 void tiny_average_unpooling_back_kernel(
const std::vector<tensor_t*>& in_data,
82 const std::vector<tensor_t*>& out_data,
83 std::vector<tensor_t*>& out_grad,
84 std::vector<tensor_t*>& in_grad,
85 const shape3d& in_dim,
87 std::vector<
typename partial_connected_layer<Activation>::io_connections>& weight2io,
88 std::vector<
typename partial_connected_layer<Activation>::wo_connections>& in2wo,
89 std::vector<std::vector<serial_size_t>>& bias2out) {
91 for (
size_t sample = 0; sample < in_data[0]->size(); sample++) {
92 const vec_t& prev_out = (*in_data[0])[sample];
93 const vec_t& W = (*in_data[1])[0];
94 vec_t& dW = (*in_grad[1])[sample];
95 vec_t& db = (*in_grad[2])[sample];
96 vec_t& prev_delta = (*in_grad[0])[sample];
97 vec_t& curr_delta = (*out_grad[0])[sample];
99 auto inarea = in_dim.area();
101 for (
size_t i = 0; i < in_dim.depth_; ++i) {
102 float_t weight = W[i];
103 for (
size_t j = 0; j < inarea; ++j, ++idx) {
104 prev_delta[idx] = weight * curr_delta[in2wo[idx][0].second];
108 for (
size_t i = 0; i < weight2io.size(); ++i) {
109 const auto& connections = weight2io[i];
110 float_t diff = float_t(0);
112 for (
auto connection : connections)
113 diff += prev_out[connection.first] * curr_delta[connection.second];
118 for (
size_t i = 0; i < bias2out.size(); i++) {
119 const std::vector<serial_size_t>& outs = bias2out[i];
120 float_t diff = float_t(0);
123 diff += curr_delta[o];
133 template<
typename Activation = activation::
identity>
137 CNN_USE_LAYER_MEMBERS;
146 serial_size_t in_height,
148 serial_size_t pooling_size)
150 in_width * in_height *
in_channels * sqr(pooling_size),
152 stride_(pooling_size),
154 out_(in_width*pooling_size, in_height*pooling_size,
in_channels),
157 init_connection(pooling_size);
168 serial_size_t in_height,
170 serial_size_t pooling_size,
171 serial_size_t stride)
173 unpool_out_dim(in_width, pooling_size, stride) *
174 unpool_out_dim(in_height, pooling_size, stride) *
in_channels,
178 out_(unpool_out_dim(in_width, pooling_size, stride),
179 unpool_out_dim(in_height, pooling_size, stride),
in_channels),
182 init_connection(pooling_size);
185 std::vector<index3d<serial_size_t>>
in_shape()
const override {
189 std::vector<index3d<serial_size_t>>
out_shape()
const override {
190 return { out_, out_ };
193 std::string
layer_type()
const override {
return "ave-unpool"; }
196 std::vector<tensor_t*>& out_data)
override {
198 tiny_average_unpooling_kernel<Activation>(
210 const std::vector<tensor_t*>& out_data,
211 std::vector<tensor_t*>& out_grad,
212 std::vector<tensor_t*>& in_grad)
override {
213 tensor_t& curr_delta = *out_grad[0];
214 this->backward_activation(*out_grad[0], *out_data[0], curr_delta);
216 tiny_average_unpooling_back_kernel<Activation>(
229 serial_size_t stride_;
234 static serial_size_t unpool_out_dim(serial_size_t
in_size,
235 serial_size_t pooling_size,
236 serial_size_t stride) {
237 return static_cast<int>((
in_size-1) * stride + pooling_size);
240 void init_connection(serial_size_t pooling_size) {
241 for (serial_size_t c = 0; c < in_.depth_; ++c) {
242 for (serial_size_t y = 0; y < in_.height_; ++y) {
243 for (serial_size_t x = 0; x < in_.width_; ++x) {
244 connect_kernel(pooling_size, x, y, c);
249 for (serial_size_t c = 0; c < in_.depth_; ++c) {
250 for (serial_size_t y = 0; y < out_.height_; ++y) {
251 for (serial_size_t x = 0; x < out_.width_; ++x) {
252 this->connect_bias(c, out_.get_index(x, y, c));
258 void connect_kernel(serial_size_t pooling_size,
262 serial_size_t dymax = std::min(pooling_size, out_.height_ - y);
263 serial_size_t dxmax = std::min(pooling_size, out_.width_ - x);
264 serial_size_t dstx = x * stride_;
265 serial_size_t dsty = y * stride_;
266 serial_size_t inidx = in_.get_index(x, y, inc);
267 for (serial_size_t dy = 0; dy < dymax; ++dy) {
268 for (serial_size_t dx = 0; dx < dxmax; ++dx) {
269 this->connect_weight(
271 out_.get_index(dstx + dx, dsty + dy, inc),
average pooling with trainable weights
Definition: average_unpooling_layer.h:134
std::vector< index3d< serial_size_t > > in_shape() const override
array of input shapes (width x height x depth)
Definition: average_unpooling_layer.h:185
std::string layer_type() const override
name of layer, should be unique for each concrete class
Definition: average_unpooling_layer.h:193
average_unpooling_layer(serial_size_t in_width, serial_size_t in_height, serial_size_t in_channels, serial_size_t pooling_size, serial_size_t stride)
Definition: average_unpooling_layer.h:167
average_unpooling_layer(serial_size_t in_width, serial_size_t in_height, serial_size_t in_channels, serial_size_t pooling_size)
Definition: average_unpooling_layer.h:145
void forward_propagation(const std::vector< tensor_t * > &in_data, std::vector< tensor_t * > &out_data) override
Definition: average_unpooling_layer.h:195
void back_propagation(const std::vector< tensor_t * > &in_data, const std::vector< tensor_t * > &out_data, std::vector< tensor_t * > &out_grad, std::vector< tensor_t * > &in_grad) override
return delta of previous layer (delta=\frac{dE}{da}, a=wx in fully-connected layer)
Definition: average_unpooling_layer.h:209
std::vector< index3d< serial_size_t > > out_shape() const override
array of output shapes (width x height x depth)
Definition: average_unpooling_layer.h:189
serial_size_t in_size() const
!
Definition: layer.h:176
bool parallelize_
Flag indicating whether the layer/node operations ara paralellized.
Definition: layer.h:696
serial_size_t in_channels() const
number of outgoing edges in this layer
Definition: layer.h:146
Definition: partial_connected_layer.h:34