tiny_dnn 1.0.0
A header only, dependency-free deep learning framework in C++11
Loading...
Searching...
No Matches
average_unpooling_layer.h
1/*
2 Copyright (c) 2013, Taiga Nomi
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the <organization> nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
17 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27#pragma once
28
29#include <string>
30#include <vector>
31#include <algorithm>
32
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"
37
38namespace tiny_dnn {
39
40// forward_propagation
41template <typename Activation>
42void 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,
46 float_t scale_factor,
47 std::vector<typename partial_connected_layer<Activation>::wi_connections>& out2wi,
48 Activation& h) {
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];
55
56 auto oarea = out_dim.area();
57 size_t idx = 0;
58 for (size_t d = 0; d < out_dim.depth_; ++d) {
59 float_t weight = W[d];// * scale_factor;
60 float_t bias = b[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)// 13.1%
65 value += in[connection.second]; // 3.2%
66 value *= weight;
67 value += bias;
68 a[idx] = value;
69 }
70 }
71
72 assert(out.size() == out2wi.size());
73 for_i(parallelize, out2wi.size(), [&](int i) {
74 out[i] = h.f(a, i);
75 });
76 }
77}
78
79// back_propagation
80template<typename Activation>
81void 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,
86 float_t scale_factor,
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) {
90
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];
98
99 auto inarea = in_dim.area();
100 size_t idx = 0;
101 for (size_t i = 0; i < in_dim.depth_; ++i) {
102 float_t weight = W[i];// * scale_factor;
103 for (size_t j = 0; j < inarea; ++j, ++idx) {
104 prev_delta[idx] = weight * curr_delta[in2wo[idx][0].second];
105 }
106 }
107
108 for (size_t i = 0; i < weight2io.size(); ++i) {
109 const auto& connections = weight2io[i];
110 float_t diff = float_t(0);
111
112 for (auto connection : connections)
113 diff += prev_out[connection.first] * curr_delta[connection.second];
114
115 dW[i] += diff;// * scale_factor;
116 }
117
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);
121
122 for (auto o : outs)
123 diff += curr_delta[o];
124
125 db[i] += diff;
126 }
127 }
128}
129
133template<typename Activation = activation::identity>
135 public:
137 CNN_USE_LAYER_MEMBERS;
138
146 serial_size_t in_height,
147 serial_size_t in_channels,
148 serial_size_t pooling_size)
152 stride_(pooling_size),
156
157 init_connection(pooling_size);
158 }
159
168 serial_size_t in_height,
169 serial_size_t in_channels,
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,
176 stride_(stride),
178 out_(unpool_out_dim(in_width, pooling_size, stride),
179 unpool_out_dim(in_height, pooling_size, stride), in_channels),
181
182 init_connection(pooling_size);
183 }
184
185 std::vector<index3d<serial_size_t>> in_shape() const override {
186 return { in_, w_, index3d<serial_size_t>(1, 1, out_.depth_) };
187 }
188
189 std::vector<index3d<serial_size_t>> out_shape() const override {
190 return { out_, out_ };
191 }
192
193 std::string layer_type() const override { return "ave-unpool"; }
194
195 void forward_propagation(const std::vector<tensor_t*>& in_data,
196 std::vector<tensor_t*>& out_data) override {
197
200 in_data,
201 out_data,
202 out_,
203 Base::scale_factor_,
204 Base::out2wi_,
205 Base::h_);
206
207 }
208
209 void back_propagation(const std::vector<tensor_t*>& in_data,
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);
215
217 in_data,
218 out_data,
219 out_grad,
220 in_grad,
221 in_,
222 Base::scale_factor_,
223 Base::weight2io_,
224 Base::in2wo_,
225 Base::bias2out_);
226 }
227
228 private:
229 serial_size_t stride_;
230 shape3d in_;
231 shape3d out_;
232 shape3d w_;
233
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);
238 }
239
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);
245 }
246 }
247 }
248
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));
253 }
254 }
255 }
256 }
257
258 void connect_kernel(serial_size_t pooling_size,
259 serial_size_t x,
260 serial_size_t y,
261 serial_size_t inc) {
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(
270 inidx,
271 out_.get_index(dstx + dx, dsty + dy, inc),
272 inc);
273 }
274 }
275 }
276};
277
278} // namespace tiny_dnn
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
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
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
Simple image utility class.
Definition image.h:94
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